weylonn / Forum War - Intégration Risibank

// ==UserScript==
// @name        Forum War - Intégration Risibank
// @match       https://forumwar.up.railway.app/play/*
// @grant       GM_xmlhttpRequest
// @grant       GM_addStyle
// @grant       GM_getValue
// @grant       GM_setValue
// @version     1.0
// @author      weylonn
// @licence     MIT
// @updateURL https://openuserjs.org/meta/weylonn/Forum_War_-_Intégration_Risibank.meta.js
// @description Une intégration de risibank dans le chat de Forum War
// ==/UserScript==

const chatContainer = document.querySelector('.row.send-wrap');

const css = `
    .risibank-container {
        width: 100%;
        height: 125px;
        overflow-y: scroll;
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        align-items: flex-start;
  }
  
  .risibank-container img {
        width: 68px;
        height: 51px;
        margin: 5px;
        cursor: pointer;
  }

  #risibank-search-input {
    width: calc(100% - 10px);
    margin: 5px;
  }
`;
GM_addStyle(css);

GM_xmlhttpRequest({
    url: 'https://risibank.fr/api/v1/medias',
    method: 'GET',
    responseType: 'json',
    onload: function (data) {
        setup(data.response);
    }
});

function setup(risibankData) {
    const html = `
        <ul id="risibank-tabs" class="nav nav-tabs">
            <li data-tab-code="favorites"> <a> Favoris </a>  </li>
            <li data-tab-code="top"> <a> Populaire </a>  </li>
            <li data-tab-code="trending"> <a> Tendance </a>  </li>
            <li data-tab-code="new"> <a> Récent </a>  </li>
            <li data-tab-code="search"> <a> recherche </a>  </li>
            <li> <input id="risibank-username-input" type="text" class="form-control" placeholder="Compte Risibank" />  </li>
        </ul>

        <div class="risibank-container hide" data-container-code="favorites">

        </div>

        <div class="risibank-container hide" data-container-code="top">

        </div>

        <div class="risibank-container hide" data-container-code="trending">

        </div>

        <div class="risibank-container hide" data-container-code="new">

        </div>

        <div class="risibank-container hide" data-container-code="search">
            <input id="risibank-search-input" type="text" class="form-control message-input">
        </div>
    `;

    chatContainer.insertAdjacentHTML('beforebegin', html);

    const tabs = document.querySelectorAll('ul#risibank-tabs li[data-tab-code]');
    const containers = document.querySelectorAll('.risibank-container');
    const forumWarInput = document.querySelector('#example-input2-group2');
    const risibankSearchInput = document.querySelector('input#risibank-search-input');
    const risibankUsernameInput = document.querySelector('input#risibank-username-input');

    let favoriteImages = [];

    function getFavorites() {
        const username = GM_getValue('risibank_username');

        GM_xmlhttpRequest({
            url: `https://risibank.fr/api/v1/users/by-username/${username}`,
            method: 'GET',
            responseType: 'json',
            onload: function (data) {
                GM_xmlhttpRequest({
                    url: `https://risibank.fr/api/v1/users/${data.response.id}/favorites`,
                    method: 'GET',
                    responseType: 'json',
                    onload: function (data) {
                        favoriteImages = data.response;
                        setActiveContainer('favorites', true);
                    }
                });
            }
        });
    }

    if (GM_getValue('risibank_username')) {
        getFavorites();
    }

    let searchTimeout = null;
    risibankSearchInput.addEventListener('keyup', () => {
        clearTimeout(searchTimeout);
        searchTimeout = setTimeout(() => {
            makeRisibankSearch();
        }, 500);
    });

    function makeRisibankSearch() {
        const search = risibankSearchInput.value;
        GM_xmlhttpRequest({
            url: 'https://risibank.fr/api/v1/medias/search?query=' + search + '&page=1',
            method: 'GET',
            responseType: 'json',
            onload: function (data) {
                const container = document.querySelector('.risibank-container[data-container-code="search"]');
                const images = container.querySelectorAll('img');
                for (const image of images) {
                    image.remove();
                }

                for (const image of data.response.medias) {
                    const img = document.createElement('img');
                    img.src = image.source_url;
                    container.appendChild(img);

                    img.addEventListener('click', () => {
                        insertSticker(image.source_url);
                    });
                }
            }
        });
    }

    const risibankUsername = GM_getValue('risibank_username');
    if (risibankUsername) {
        risibankUsernameInput.value = risibankUsername;
    }

    risibankUsernameInput.addEventListener('keyup', () => {
        GM_setValue('risibank_username', risibankUsernameInput.value);
    });

    function setActiveContainer(code, forceRefresh) {
        const tab = document.querySelector(`li[data-tab-code="${code}"]`);
        const container = document.querySelector(`.risibank-container[data-container-code="${code}"]`);

        for (const t of tabs) {
            t.classList.remove('active');
        }
        tab.classList.add('active');

        for (const c of containers) {
            c.classList.add('hide');
        }
        container.classList.remove('hide');

        if (!container.classList.contains('initialised') || forceRefresh) {
            let images = [];
            switch (code) {
                case 'favorites':
                    images = favoriteImages;
                    break;
                case 'top':
                    images = risibankData.top;
                    break;
                case 'trending':
                    images = risibankData.hot;
                    break;
                case 'new':
                    images = risibankData.new;
                    break;
            }
            for (const image of images) {
                const img = document.createElement('img');
                img.src = image.source_url;
                container.appendChild(img);

                img.addEventListener('click', () => {
                    insertSticker(image.source_url);
                });
            }

            container.classList.add('initialised');
        }
    }

    for (const tab of tabs) {
        const code = tab.dataset.tabCode;
        tab.addEventListener('click', () => {
            setActiveContainer(code, false);
        });
    }

    function insertSticker(text) {
        // Check if the input is focused
        if (document.activeElement === forumWarInput) {
            const startPos = forumWarInput.selectionStart;
            const endPos = forumWarInput.selectionEnd;

            // Insert text at cursor position
            forumWarInput.value = forumWarInput.value.substring(0, startPos) +
                text +
                forumWarInput.value.substring(endPos, forumWarInput.value.length);

            // Move the cursor after the inserted text
            forumWarInput.selectionStart = startPos + text.length;
            forumWarInput.selectionEnd = startPos + text.length;
        } else {
            // Insert text at the end
            forumWarInput.value += text;
        }
    }

    if (GM_getValue('risibank_username')) {
        setActiveContainer('favorites', false);
    } else {
        setActiveContainer('top', false);
    }
}