RisiOnche

Risibank sur onche.org (Fix)

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         RisiOnche
// @namespace    RisiOnche
// @version      0.101.0
// @description  Risibank sur onche.org (Fix)
// @author       RisiOnche, Catalyst
// @match        https://onche.org/topic/*
// @match        https://onche.org/forum/*
// @match        https://onche.org/chat/*
// @match        https://onche.org/account/*
// @exclude      https://onche.org/forum/**/search
// @exclude      https://onche.org/forum/**/search?*
// @icon         https://www.risishack.com/lfoubw.png
// @grant        none
// ==/UserScript==


(async () => {

    //CSS
    const CSS = document.createElement('style');
    CSS.id = "risi-onche-css";
    CSS.textContent = `
    #risi-onche iframe {
        height: 10rem !important
    }

    /*unset force width on Shackimg */
    .preview ._solo .smiley img[src^="https://image.noelshack.com/"] {
       width: unset !important;
    }

    /* hide class risi onche close*/
    #risi-onche:not(.risi-onche-open) {
        display : none;
    }

    /* Replace stickers when risibank is open */
    #post .composer__stickers-host:has(+ #risi-onche.risi-replace-stickers.risi-onche-open) {
        display: none;
    }

    /*BTN RISI CSS PANEL*/
    #risi-onche-panel .button {
        font-size: .9rem;
    }


    /*BTN RISI CSS FOFO PROFIL*/
    .forum .risibank-toggle img,
    .account .risibank-toggle img {
        filter: hue-rotate(250deg);
        width: 22px;
    }

    /*BTN RISI CSS MP*/
    #chat .risibank-toggle img {
        filter: grayscale(1);
        width: 17px;
    }

    /* RisiMobile Options */
    @media (max-width: 880px) {
        #right .bloc.border.red {
            order: -1;
        }
    }

    /*MOBILE BTN ENVOYER CSS*/
    @media (max-width: 415px) {
        .bloc #post {
            padding-left: 5px; /* Padding for post */
            padding-right: 5px; /* reduce on mobile */
        }
        .forum .composer__send {
            padding: 0.4rem 0.5rem !important;
            font-size: 0.85em !important;
            margin: auto;
            border-radius : 6px !important;
            transition : none;
        }
        .forum .composer__send .mdi {
            font-size: 1rem;
        }
        .composer__toolbar .composer__send .mdi {
            display : none !important; /*icone ➣ masquée sur mobile car trop petit*/
        }
    }`;
    document.head.appendChild(CSS);

    //LOAD_STORAGE_VALUE
    const loadSettings = JSON.parse(localStorage.getItem('risi-onche-storage') || '{}');

    //GLOBAL_VALUE
    const settings = {}; // { risiOverlay : ... , risiApi : ... , risiOpen : ... , replaceStickers : ... }
    settings.risiOverlay = loadSettings.risiOverlay ?? false;
    settings.risiApi = loadSettings.risiApi ?? false;
    settings.risiOpen = loadSettings.risiOpen ?? true;
    settings.replaceStickers = loadSettings.replaceStickers ?? false;

    let showNSFW = false;
    if (location.href.includes('onche.org/forum/3/')) showNSFW = true;
    if (document.querySelector('.title a[href*="onche.org/forum/3/"]')) showNSFW = true;

    //  AWAIT DOM TEXT PROMISE // POLL DOM IF IN JS (Retry 6 times)
    const textAreaPostSel = '#chat textarea, #post textarea , .account .bloc.insert-image textarea';
    let tentatives = 0;
    await new Promise(resolve => {
        (function check() {
            if (document.querySelector(textAreaPostSel)) return resolve();
            else if (++tentatives < 6) setTimeout(check, 300);
            else resolve(); // Fallback
        })();
    });

    //GLOBAL_NODE
    let placeBtnAfterMain;
    let placeRisiBefore;
    let textAreaPost = document.querySelector(textAreaPostSel);
    let placeSettingsAfter = document.querySelector('#right .bloc.border:last-of-type');
    if (location.href.includes('onche.org/chat/')) { 
        //MP CHAT
        placeBtnAfterMain = document.querySelector('.Form__toolbar__button:last-of-type');
        placeRisiBefore = document.querySelector(textAreaPostSel);
    } else if (location.href.includes('onche.org/account/')) { 
        // PROFIL
        placeBtnAfterMain = document.querySelector('.account .bloc.insert-image .item:last-of-type');
        placeRisiBefore = document.querySelector(textAreaPostSel);
    } else {
        //FOFO
        placeBtnAfterMain = document.querySelector('#post .composer__toolbar-items .onche-add, #post .composer__toolbar-items .item:last-of-type');
        placeRisiBefore = document.querySelector(textAreaPostSel);
    }

    // LAPI a été mal compilée (MAJ 2025) : })(this.window = this.window || {});
    // INJECTION OBLIGATOIRE DE L'API DANS LE <HEAD> GLOBAL pour palier au soucis.
    // Sinon incompatibilité avec IOS / GREASYMONKEY ET VIOLENT MONKEY.
    const script = document.createElement('script');
    script.src = 'https://risibank.fr/downloads/web-api/risibank.js?v=1.3.2';
    document.head.appendChild(script);
    script.onload = () => risibankApiReady();

    // BRIDGE API IN HEAD FOR GREASYMONKEY
    const risiOnche = document.createElement('script');
    risiOnche.id = "risi-onche-bridge-api";
    risiOnche.textContent = `
    function activateRisibank(container, textArea, risiOverlay, showNSFW) {
        const themeRisi = document.body.matches('.blue, .grey') ? 'dark' : 'light';
        RisiBank.activate({
            type: risiOverlay ? 'overlay' : 'iframe',
            container,
            theme: themeRisi,
            mediaSize: 'sm',
            navbarSize: 'sm',
            defaultTab: 'fav',
            showNSFW: showNSFW,
            allowUsernameSelection: true,
            onSelectMedia: (e) => {
                RisiBank.Actions.addSourceImageLink(textArea)(e);
                textArea?.dispatchEvent(new Event('change', { bubbles: true })); /*Remonte un event pour refresh la preview*/
            }
        });
    }
    window.activateRisibank = activateRisibank;`;
    document.head.appendChild(risiOnche);

    // Appel direct de la fonction ou via unsafeWindow.fonction (TamperMonkey VS GreasyMonkey) - Grant None reste necessaire
    const activateRisibankSafe = typeof activateRisibank !== "undefined" ? activateRisibank : unsafeWindow.activateRisibank;


    // BTN OPEN RISIBANK
    function insertRisibankButton(placeBtnAfter) {
        placeBtnAfter?.insertAdjacentHTML('afterend', `
            <div class="risibank-toggle item Form__toolbar__button" title="Ouvrir / Fermer RisiBank">
                <img src="https://risibank.fr/logo.png">
            </div>
        `);
    }


    //Create IFRAME RisiOnche
    let risiOncheAlreadyMounted = false;
    function embedRisiOnche(textArea) {
        document.getElementById('risi-onche')?.classList.remove('risi-onche-open');
        if (settings.risiOverlay || !settings.risiOpen) return;

        document.getElementById('risi-onche')?.classList.add('risi-onche-open');

        if (!placeRisiBefore || risiOncheAlreadyMounted) return;

        //1ER INJECTION
        placeRisiBefore.insertAdjacentHTML('beforebegin', `<div id="risi-onche" class="risi-onche-open ${settings.replaceStickers ? 'risi-replace-stickers' : ''}" style="max-height: 30rem"></div>`);
        activateRisibankSafe(document.getElementById('risi-onche'), textArea, false, showNSFW);
        risiOncheAlreadyMounted = true
    }


    function risibankApiReady() {

        insertRisibankButton(placeBtnAfterMain); //BTN MAIN

        embedRisiOnche(textAreaPost); //MONTAGE IFRAME

        // Bloc Options dans la sidebar
        placeSettingsAfter?.insertAdjacentHTML('afterend', `
            <div id="risi-onche-panel" class="bloc border red">
                <div class="title">🔧 Risibank</div>
                <div class="content centered">
                    <button id="swtich-mode" class="button bordered secondary" type="button">Mode intégré : <span>${!settings.risiOverlay ? 'On' : 'Off'}</span></button>
                    <button id="replace-onche-stickers" class="button bordered secondary" type="button" title="Quand le panel s'ouvre, afficher l'intégration Risibank à la place des stickers onche (pour gagner de la place)">Masquer les stickers onche : <span>${settings.replaceStickers ? 'On' : 'Off'}</span></button>
                    <button id="open-risibank-url" class="button bordered secondary" type="button" title="Lors d'un clic sur un sticker noelshack, rediriger vers RisiBank si le sticker existe plutôt que noelshack">Rediriger vers RisiBank : <span>${settings.risiApi ? 'On' : 'Off'}</span></button>
                </div>
            </div>
        `);
        // Listeners Bloc Options
        document.getElementById('swtich-mode')?.addEventListener('click', (event) => {
            settings.risiOverlay = !settings.risiOverlay; // Revert
            event.currentTarget.querySelector('span').textContent = `${!settings.risiOverlay ? 'On' : 'Off'}`;
            localStorage.setItem('risi-onche-storage', JSON.stringify(settings));
            embedRisiOnche(textAreaPost);
        });
        document.getElementById('replace-onche-stickers')?.addEventListener('click', (event) => {
            settings.replaceStickers = !settings.replaceStickers; // Revert
            document.getElementById('risi-onche')?.classList.toggle('risi-replace-stickers', settings.replaceStickers); // Revert Class
            event.currentTarget.querySelector('span').textContent = `${settings.replaceStickers ? 'On' : 'Off'}`;
            localStorage.setItem('risi-onche-storage', JSON.stringify(settings));
        });
        document.getElementById('open-risibank-url')?.addEventListener('click', (event) => {
            settings.risiApi = !settings.risiApi; // Revert
            event.currentTarget.querySelector('span').textContent = `${settings.risiApi ? 'On' : 'Off'}`;
            localStorage.setItem('risi-onche-storage', JSON.stringify(settings));
        });
    }


    //GLOBAL LISTENER
    document.body.addEventListener('click', async (e) => {

        // BOUTON RISIBANK
        const risibankBtn = e.target.closest('.risibank-toggle');
        if (risibankBtn) {

            const mainBloc = risibankBtn.closest('#post, #chat, .account');
            if (!settings.risiOverlay && mainBloc) {
                // IFRAME INTEGREE MAIN
                settings.risiOpen = !settings.risiOpen;
                localStorage.setItem('risi-onche-storage', JSON.stringify(settings));
                embedRisiOnche(textAreaPost);
            } else if (mainBloc) {
                // OVERLAY MAIN
                activateRisibankSafe(document.body, textAreaPost, true, showNSFW);
            } else {
                // OVERLAY IN EDITION
                const editBloc = risibankBtn.closest('.message[data-edit]');
                const textAreaEdit = editBloc.querySelector('textarea');
                activateRisibankSafe(document.body, textAreaEdit, true, showNSFW);
            }

        }

        // BTN_IMG_JVC => OPEN API OR BYPASS 403
        const linkShack = e.target.closest('a.link[href^="https://image.noelshack.com/"]');
        if (linkShack) {
            if (settings.risiApi) {
                e.preventDefault();
                window.open('https://risibank.fr/api/v1/medias/by-source?type=jvc&url=' + linkShack.href, '_blank');
            } else if (!linkShack.matches('[rel~="noreferrer"]')) {
                e.preventDefault();
                window.open(linkShack.href, '_blank', 'noopener,noreferrer'); //FallBack NoReferrer If no balise REL
            }
        }

        //BTN_IMG_ONCHE => CONTEXTMENU => ADD OPTION : Voir en HD
        const imgOnche = e.target.closest('.logged .sticker > img[src^="https://cloud.onche.org/"]');
        if (imgOnche) {

            await new Promise(r => setTimeout(r, 100));

            const contextMenu = document.getElementById('context'), btnHDHere = document.getElementById('show-onche-hd');
            if (!contextMenu || btnHDHere) return;

            contextMenu.insertAdjacentHTML('beforeend', `
                <div class="item has-icon" id="show-onche-hd">
                    <span class="context-label">Voir en HD</span><span class="mdi mdi-printer-pos"></span>
                </div>`);
            document.getElementById('show-onche-hd').addEventListener('click', () => {
                window.open(imgOnche.src.split('/').slice(0, -1).join('/'), '_blank'); //Vire le l'index Ratio => Max Hd
            });
        }

        //BOUTON MODIFIER
        const btnItem = e.target.closest('#context .item.has-icon');
        if (btnItem?.querySelector('.mdi-pencil-outline')) { //Si bouton editer

            await new Promise(r => setTimeout(r, 300));

            //On traite tout les blocs ouvert en edition (plus simple) pour ajouter le BTN
            for (const editBlocMsg of document.querySelectorAll('.message[data-edit]')) {

                if (editBlocMsg.querySelector('.risibank-toggle')) continue; //Si Btn deja ajouté on ignore

                const placeBtnAfterEdit = [...editBlocMsg.querySelectorAll('.composer__toolbar .item')].pop();

                insertRisibankButton(placeBtnAfterEdit);
            }
        }

    }, true);


    // IMG_JVC => COPIE DU SRC DANS ALT pour pour copier coller avec SRC
    document.querySelectorAll('img[src^="https://image.noelshack.com/"]:not([data-processed-risionche])').forEach(imgShack => {
        imgShack.alt = imgShack.src;
        imgShack.setAttribute('data-processed-risionche', '');
    });

    // LIEN_RISI => Rempalce les liens RISIBANK par des IMAGES inline
    document.querySelectorAll('a.link[href^="https://risibank.fr/cache/medias/"]:not([data-processed-risionche])').forEach(linkRisi => {
        linkRisi.outerHTML = `
            <a href="${linkRisi.href}" class="link" data-processed-risionche target="_blank" rel="nofollow">
                <div class="smiley"><img src="${linkRisi.href}"></div>
            </a>
        `;
    });


})();