Backloggd+ (Buttons & Tweaks)

Adds customizable buttons to backloggd.

Versione datata 20/10/2025. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         Backloggd+ (Buttons & Tweaks)
// @namespace    http://vers.works/
// @version      2.7
// @icon         https://pbs.twimg.com/profile_images/1541908760607821824/3Am5dmsx_400x400.jpg
// @description  Adds customizable buttons to backloggd.
// @author       VERS
// @match        https://www.backloggd.com/*
// @match        *://backloggd.com/*
// @match        *://*.backloggd.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    const whitelist = ['Steam', 'SteamDB', 'SteamGridDB', 'Epic Games Store', 'GOG', 'Twitch', 'Youtube', 'XBOX', 'Playstation', 'Nintendo',  "Retroachievements",];

    let buttons = GM_getValue('buttons', [
        {
            name: 'Steam',
            iconUrl: 'https://i.imgur.com/9NFBdz4.png',
            searchUrl: 'https://store.steampowered.com/search/?term=',
            color: '#1a9fff',
            status: true
        },
        {
            name: 'SteamDB',
            iconUrl: 'https://i.imgur.com/t6rV9xA.png',
            searchUrl: 'https://steamdb.info/search/?a=all&q=',
            color: '#3e76cb',
            status: true
        },
        {
            name: 'SteamGridDB',
            iconUrl: 'https://i.imgur.com/oluhFHS.png',
            searchUrl: 'https://www.steamgriddb.com/search/grids?term=',
            color: '#3a6e92',
            status: true
        },
        {
            name: 'Epic Games Store',
            iconUrl: 'https://cdn2.unrealengine.com/Unreal+Engine%2Feg-logo-filled-1255x1272-0eb9d144a0f981d1cbaaa1eb957de7a3207b31bb.png',
            searchUrl: 'https://store.epicgames.com/en-US/expanded-search-results?q=',
            color: '#000000',
            status: true
        },
        {
            name: 'GOG',
            iconUrl: 'https://i.imgur.com/3tL2SKY.png',
            searchUrl: 'https://www.gog.com/en/games?query=',
            color: '#9548a6',
            status: true
        },
        {
            name: 'Twitch',
            iconUrl: 'https://i.imgur.com/UVuf0iF.png',
            searchUrl: 'https://www.twitch.tv/search?term=',
            color: '#9046fd',
            status: true
        },
        {
            name: 'Youtube',
            iconUrl: 'https://i.imgur.com/C0Ux2Y3.png',
            searchUrl: 'https://www.youtube.com/results?search_query=',
            color: '#ff0000',
            status: true
        },
        {
            name: 'XBOX',
            iconUrl: 'https://i.imgur.com/jrItCUM.png',
            searchUrl: 'https://www.xbox.com/Search/Results?q=',
            color: '#107b10',
            status: true
        },
        {
            name: 'Playstation',
            iconUrl: 'https://i.imgur.com/wvB5DF8.png',
            searchUrl: 'https://www.playstation.com/search/?q=',
            color: '#0070d1',
            status: true
        },
        {
            name: 'Nintendo',
            iconUrl: 'https://i.imgur.com/7cGs7D6.png',
            searchUrl: 'https://www.nintendo.com/us/search/#q=',
            color: '#e70819',
            status: true
        },
        {
            name: 'Retroachievements',
            iconUrl: 'https://i.imgur.com/wp8wsD2.png',
            searchUrl: 'https://retroachievements.org/games?filter%5Btitle%5D=',
            color: '#ce9833',
            status: true
        },
        {
            name: 'Settings',
            iconUrl: 'https://i.imgur.com/WvM8EHQ.png',
            color: '#16181c',
            status: true,
            isSettings: true
        }
    ]);

    function createButtonElement(buttonData) {
        const { iconUrl, searchUrl, color, name } = buttonData;

        const col = document.createElement('div');
        col.className = 'custom-btn-container col px-0 mt-auto';
        col.setAttribute('data-name', name);

        const button = document.createElement('button');
        button.className = 'button-link btn-play mx-auto custom-button';
        button.style.backgroundColor = color;
        button.style.width = '40px';
        button.style.height = '40px';
        button.style.borderRadius = '7px';
        button.style.display = 'flex';
        button.style.justifyContent = 'center';
        button.style.alignItems = 'center';
        button.style.boxShadow = 'var(--lt-shadowDefault)';
        button.style.transition = 'transform 0.1s ease-in-out, box-shadow 0.1s ease-in-out';

        button.addEventListener('mouseenter', () => {
            button.style.boxShadow = 'var(--lt-shadowActive)';
            button.style.transform = 'translateY(-1px)';
        });
        button.addEventListener('mouseleave', () => {
            button.style.boxShadow = 'var(--lt-shadowDefault)';
            button.style.transform = 'none';
        });

        const icon = document.createElement('img');
        icon.src = iconUrl;
        icon.alt = name;
        icon.style.width = '24px';
        icon.style.height = '24px';
        icon.style.pointerEvents = 'none';
        button.appendChild(icon);

        button.addEventListener('click', function() {
            if (name === 'Settings') {
                openSettingsModal();
            } else {
                let gameTitleElement = document.querySelector('#title h1');

                if (!gameTitleElement) {
                    gameTitleElement = document.querySelector('h1[itemprop="name"]');
                }
                if (!gameTitleElement) {
                    gameTitleElement = document.querySelector('.game-title h1');
                }
                if (!gameTitleElement) {
                    gameTitleElement = document.querySelector('h1');
                }

                if (gameTitleElement) {
                    const gameTitle = encodeURIComponent(gameTitleElement.textContent.trim());
                    console.log('Game title found:', gameTitle);
                    const searchLink = searchUrl.includes('%s')
                        ? searchUrl.replace('%s', gameTitle)
                        : searchUrl + gameTitle;
                    console.log('Opening URL:', searchLink);
                    window.open(searchLink, '_blank');
                } else {
                    console.error('Game title element not found on this page');
                    alert('Could not find game title on this page. Make sure you are on a game page.');
                }
            }
        });

        button.setAttribute('data-search', searchUrl);
        button.setAttribute('data-name', name);
        col.appendChild(button);
        return col;
    }

    function updateButtons() {
        const targetHr = document.querySelector('hr.mb-3.mt-2.d-none.d-md-flex');
        if (!targetHr) return;

        document.querySelectorAll('.custom-btn-row').forEach(row => row.remove());

        const activeButtons = buttons.filter(btn => btn.status);

        const whitelistButtons = activeButtons
            .filter(btn => whitelist.includes(btn.name))
            .sort((a, b) => whitelist.indexOf(a.name) - whitelist.indexOf(b.name));

        const customButtons = activeButtons.filter(btn => !whitelist.includes(btn.name) && !btn.isSettings);
        const settingsButtons = activeButtons.filter(btn => btn.isSettings);

        const allButtons = [...whitelistButtons, ...customButtons, ...settingsButtons];

        let insertAfter = targetHr;
        for (let i = 0; i < allButtons.length; i += 4) {
            const rowButtons = allButtons.slice(i, i + 4);
            const buttonRow = document.createElement('div');
            buttonRow.className = 'row mx-0 d-none d-md-flex logging-btns small-log-btns custom-btn-row flex-wrap';
            rowButtons.forEach(btn => buttonRow.appendChild(createButtonElement(btn)));

            insertAfter.parentNode.insertBefore(buttonRow, insertAfter.nextSibling);
            insertAfter = buttonRow;
        }
    }


    function addSpacer() {
        const targetHr = document.querySelector('hr.mb-3.mt-2.d-none.d-md-flex');
        if (!targetHr) return;

        const spacerParent = targetHr.parentNode.querySelector('.row.mt-2.d-none.d-md-flex');
        if (spacerParent && !spacerParent.querySelector('.spacer')) {
            const spacer = document.createElement('div');
            spacer.className = 'spacer';
            spacer.style.height = '10px';
            spacerParent.appendChild(spacer);
        }
    }

    function openSettingsModal() {
        const settingsModal = document.createElement('div');
        settingsModal.className = 'settings-modal';
        settingsModal.style.position = 'fixed';
        settingsModal.style.top = '50%';
        settingsModal.style.left = '50%';
        settingsModal.style.transform = 'translate(-50%, -50%)';
        settingsModal.style.backgroundColor = 'rgba(22, 24, 28)';
        settingsModal.style.borderRadius = '10px';
        settingsModal.style.padding = '20px';
        settingsModal.style.zIndex = '9999';
        settingsModal.style.maxHeight = 'auto';
        settingsModal.style.overflowY = 'visible';

        settingsModal.innerHTML = `
            <h1>BACKLOGGD BUTTONS</h1>
            <p style="display: flex; align-items: center;">Script made by VERS.
                <a href="https://www.backloggd.com/u/VERS/" target="_blank">
                    <img src="https://i.imgur.com/4FLnRC9.png" alt="Icon 1" style="margin-left: 10px; width: 19px; height: 19px;">
                </a>
                <a href="https://bento.me/thevers" target="_blank">
                    <img src="https://i.imgur.com/oePEdTt.png" alt="Icon 3" style="margin-left: 5px; width: 19px; height: 19px;">
                </a>
            </p>
            <h2>Button Settings</h2>
            <div style="max-height: 300px; overflow-y: auto;"> <!-- Only this container scrolls -->
                <ul>
                    ${buttons
                        .filter(button => !button.isSettings && button.name !== 'Remove Button')
                        .map(
                            button =>
                                `<li>
                                    <label>
                                        <input type="checkbox" id="${button.name}-checkbox" ${
                            button.status ? 'checked' : ''
                        }>
                                        ${button.name}
                                    </label>
                                </li>`
                        )
                        .join('')}
                </ul>
            </div>
            <button id="add-button" style="background-color: #4a5e8d; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem; display: block; width: 100%; margin-bottom: 6px;">
                <img src="https://i.imgur.com/i5OSWDm.png" alt="Add" style="width:20px; height:20px; margin-right:8px; vertical-align:middle;">Add Custom Button
            </button>

            <button id="remove-button" style="background-color: #4a5e8d; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem; display: block; width: 100%; margin-bottom: 6px;">
                <img src="https://i.imgur.com/mffJ4qZ.png" alt="Remove" style="width:20px; height:20px; margin-right:8px; vertical-align:middle;">Remove Custom Button
            </button>

            <div style="display: flex; gap: 6px; margin-bottom: 6px;">
                <button id="import-json-btn" style="flex:1; background-color: #4a5e8d; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem;">
                    <img src="https://i.imgur.com/uLKJYct.png" alt="Import" style="width:20px; height:20px; margin-right:6px; vertical-align:middle;">Import JSON
                </button>
                <button id="export-json-btn" style="flex:1; background-color: #4a5e8d; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem;">
                    <img src="https://i.imgur.com/riaa4f2.png" alt="Export" style="width:20px; height:20px; margin-right:6px; vertical-align:middle;">Export JSON
                </button>
            </div>

            <button id="flush-memory-btn" style="background-color: #ff4444; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem; display: block; width: 100%; margin-bottom: 6px;">
                <img src="https://i.imgur.com/zVry85k.png" alt="Flush" style="width:20px; height:20px; margin-right:8px; vertical-align:middle;">Flush Memory
            </button>

            <a href="https://discord.gg/eyDknctyUA" target="_blank" style="text-decoration: none;">
                <button id="discord-btn" style="background-color: #7289DA; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem; display: block; width: 100%; margin-bottom: 6px;">
                    <img src="https://uxwing.com/wp-content/themes/uxwing/download/brands-and-social-media/discord-white-icon.png" alt="Discord" style="width:20px; height:20px; margin-right:8px; vertical-align:middle;">
                    Find more buttons
                </button>
            </a>
            <button id="save-settings-btn" style="background-color: #fc6399; border: none; color: #fff; padding: 8px 16px; cursor: pointer; border-radius: .25rem; display: block; width: 100%; margin-bottom: 0px;">
                <img src="https://i.imgur.com/IpDGyvR.png" alt="Save" style="width:20px; height:20px; margin-right:8px; vertical-align:middle;">Save Settings
            </button>


        `;

        document.body.appendChild(settingsModal);
document.getElementById('import-json-btn').addEventListener('click', () => {
    const importModal = document.createElement('div');
    importModal.style.position = 'fixed';
    importModal.style.top = '50%';
    importModal.style.left = '50%';
    importModal.style.transform = 'translate(-50%, -50%)';
    importModal.style.backgroundColor = '#242832';
    importModal.style.borderRadius = '10px';
    importModal.style.padding = '20px';
    importModal.style.zIndex = '10000';
    importModal.style.width = '400px';
    importModal.innerHTML = `
        <h2>Import Buttons from JSON</h2>
        <p style="font-size: 12px;">Paste your JSON below and click <strong>Import</strong>:</p>
        <textarea id="json-import-input"
            style="width: 100%; height: 150px; background-color: #1a1d25; color: #fff; border: 1px solid #555; border-radius: 5px; padding: 8px;"></textarea>
        <div style="margin-top: 10px; display: flex; justify-content: space-between;">
            <button id="import-json-confirm" style="background-color: #fc6399; border: none; color: #fff; padding: 6px 12px; border-radius: 4px; cursor: pointer;">Import</button>
            <button id="close-json-import" style="background-color: #4a5e8d; border: none; color: #fff; padding: 6px 12px; border-radius: 4px; cursor: pointer;">Cancel</button>
        </div>
    `;
    document.body.appendChild(importModal);

    document.getElementById('close-json-import').addEventListener('click', () => importModal.remove());
    document.getElementById('import-json-confirm').addEventListener('click', () => {
        try {
            const text = document.getElementById('json-import-input').value.trim();
            if (!text) return alert('Please paste JSON first.');
            const arr = JSON.parse(text);
            if (!Array.isArray(arr)) throw new Error('Expected array.');
            let added = 0;
            arr.forEach(entry => {
                if (entry.name && entry.iconUrl && entry.searchUrl && entry.color) {
                    if (!buttons.some(b => b.name.toLowerCase() === entry.name.toLowerCase())) {
                        buttons.push({ ...entry, status: true });
                        added++;
                    }
                }
            });
            if (added > 0) {
                GM_setValue('buttons', buttons);
                alert(`✅ Imported ${added} new button(s)!`);
                window.location.reload();
            } else alert('No new buttons found.');
        } catch (err) {
            alert('❌ Invalid JSON: ' + err.message);
        }
    });
});


    document.getElementById('export-json-btn').addEventListener('click', () => {
        const exportModal = document.createElement('div');
        exportModal.style.position = 'fixed';
        exportModal.style.top = '50%';
        exportModal.style.left = '50%';
        exportModal.style.transform = 'translate(-50%, -50%)';
        exportModal.style.backgroundColor = '#242832';
        exportModal.style.borderRadius = '10px';
        exportModal.style.padding = '20px';
        exportModal.style.zIndex = '10000';
        exportModal.style.width = '400px';

        const customBtns = buttons.filter(b => !whitelist.includes(b.name) && !b.isSettings);
        exportModal.innerHTML = `
            <h2>Export Custom Buttons</h2>
            <p style="font-size: 12px;">Select which buttons to export:</p>
            <div id="export-checkboxes" style="max-height: 150px; overflow-y: auto; text-align: left; margin-bottom: 10px;">
                ${customBtns.length > 0
                    ? customBtns.map(b => `
                        <label style="display: block; margin-bottom: 4px;">
                            <input type="checkbox" value="${b.name}" checked> ${b.name}
                        </label>`).join('')
                    : '<p style="font-size: 12px; color: #ccc;">No custom buttons found.</p>'}
            </div>
            <textarea id="json-export-output" style="width:100%; height:120px; background:#1a1d25; color:#fff; border:1px solid #555; border-radius:5px; padding:6px;" readonly></textarea>
            <div style="margin-top: 10px; display: flex; justify-content: space-between;">
                <button id="export-json-generate" style="background-color: #fc6399; border: none; color: #fff; padding: 6px 12px; border-radius: 4px; cursor: pointer;">Generate</button>
                <button id="export-json-close" style="background-color: #4a5e8d; border: none; color: #fff; padding: 6px 12px; border-radius: 4px; cursor: pointer;">Close</button>
            </div>
        `;
        document.body.appendChild(exportModal);

        document.getElementById('export-json-close').addEventListener('click', () => exportModal.remove());
        document.getElementById('export-json-generate').addEventListener('click', () => {
            const selected = Array.from(exportModal.querySelectorAll('input[type="checkbox"]:checked')).map(cb => cb.value);
            const exportData = buttons
                .filter(b => selected.includes(b.name))
                .map(({ name, iconUrl, searchUrl, color }) => ({ name, iconUrl, searchUrl, color }));
            document.getElementById('json-export-output').value = JSON.stringify(exportData, null, 2);
        });
    });




        const addButtonBtn = document.getElementById('add-button');
        addButtonBtn.addEventListener('click', () => {
            openAddButtonModal();
        });

        const removeButtonBtn = document.getElementById('remove-button');
        removeButtonBtn.addEventListener('click', () => {
            openRemoveButtonModal();
        });

        const saveSettingsBtn = document.getElementById('save-settings-btn');
        saveSettingsBtn.addEventListener('click', () => {
            buttons.forEach(button => {
                if (!button.isSettings) {
                    const checkbox = document.getElementById(`${button.name}-checkbox`);
                    button.status = checkbox.checked;
                }
            });

            GM_setValue('buttons', buttons);
            window.location.reload();
        });
    }


    function openRemoveButtonModal() {
        const removeButtonModal = document.createElement('div');
        removeButtonModal.className = 'remove-button-modal';
        removeButtonModal.style.position = 'fixed';
        removeButtonModal.style.top = '50%';
        removeButtonModal.style.borderRadius = '10px';
        removeButtonModal.style.left = '50%';
        removeButtonModal.style.transform = 'translate(-50%, -50%)';
        removeButtonModal.style.backgroundColor = '#242832';
        removeButtonModal.style.padding = '20px';
        removeButtonModal.style.zIndex = '9999';
        removeButtonModal.innerHTML = `
            <h2>Remove Button</h2>
            <ul>
                ${buttons
                    .filter(button => !button.isSettings && !whitelist.includes(button.name))
                    .map(
                        button =>
                            `<li>
                                <button id="remove-${button.name}" style="background-color: #fc6399; border: none; color: #ffffff; padding: 5px 5; cursor: pointer;">✖</button>
                                <span style="margin-left: 10px;">${button.name}</span>
                            </li>`
                    )
                    .join('')}
            </ul>
            <button id="close-remove-modal" style="background-color: #4a5e8d; border: none; color: #ffffff; padding: 8px 16px; cursor: pointer; margin-top: 10px;">Close</button>
        `;

        document.body.appendChild(removeButtonModal);

        buttons
            .filter(button => !button.isSettings && !whitelist.includes(button.name))
            .forEach(button => {
                const removeButton = document.getElementById(`remove-${button.name}`);
                removeButton.addEventListener('click', () => {
                    removeButtonFromList(button.name);
                    removeButton.parentElement.remove();
                });
            });

        const closeModalBtn = document.getElementById('close-remove-modal');
        closeModalBtn.addEventListener('click', () => {
            removeButtonModal.remove();
        });
    }

    function removeButtonFromList(buttonName) {
        buttons = buttons.filter(button => button.name !== buttonName);
        GM_setValue('buttons', buttons);

        const existingRows = document.querySelectorAll('.custom-btn-row');
        existingRows.forEach(row => row.remove());

        addSpacer();
        updateButtons();
    }

    function openAddButtonModal() {
        const addButtonModal = document.createElement('div');
        addButtonModal.className = 'add-button-modal';
        Object.assign(addButtonModal.style, {
            position: 'fixed',
            top: '50%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            backgroundColor: '#242832',
            borderRadius: '10px',
            padding: '20px',
            zIndex: '9999',
            color: '#fff',
            textAlign: 'left',
            width: '420px',
            maxWidth: '90%',
            boxShadow: '0 0 12px rgba(0,0,0,0.5)',
            fontFamily: 'Inter, sans-serif'
        });

        addButtonModal.innerHTML = `
            <h2 style="text-align:center; margin-bottom: 12px;">Add Custom Button</h2>

            <div style="margin-bottom: 8px;">
                <label for="website-name" style="display:inline-block;width:120px;">Website Name:</label>
                <input type="text" id="website-name" style="width:220px; border:none; border-radius:4px; padding:4px;" required>
                <button id="info-website-name" class="info-button" style="margin-left:5px; background:none; border:none; cursor:pointer;">
                    <img src="https://i.imgur.com/jEbi3Oy.png" alt="Info" style="width:15px;height:15px;">
                </button>
            </div>

            <div style="margin-bottom: 8px;">
                <label for="icon-url" style="display:inline-block;width:120px;">Icon URL:</label>
                <input type="text" id="icon-url" style="width:220px; border:none; border-radius:4px; padding:4px;" required>
                <button id="info-icon-url" class="info-button" style="margin-left:5px; background:none; border:none; cursor:pointer;">
                    <img src="https://i.imgur.com/jEbi3Oy.png" alt="Info" style="width:15px;height:15px;">
                </button>
            </div>

            <div style="margin-bottom: 8px;">
                <label for="search-url" style="display:inline-block;width:120px;">Search URL:</label>
                <input type="text" id="search-url" style="width:220px; border:none; border-radius:4px; padding:4px;" required>
                <button id="info-search-url" class="info-button" style="margin-left:5px; background:none; border:none; cursor:pointer;">
                    <img src="https://i.imgur.com/jEbi3Oy.png" alt="Info" style="width:15px;height:15px;">
                </button>
            </div>

            <div style="margin-bottom: 8px;">
                <label for="color" style="display:inline-block;width:120px;">Button Color:</label>
                <input type="color" id="color" value="#fc6399" style="border:none; border-radius:4px; padding:2px;">
                <button id="info-color" class="info-button" style="margin-left:5px; background:none; border:none; cursor:pointer;">
                    <img src="https://i.imgur.com/jEbi3Oy.png" alt="Info" style="width:15px;height:15px;">
                </button>
            </div>

            <div style="display:flex; justify-content:space-between; margin-top:14px;">
                <button id="save-new-button" style="background-color:#fc6399; border:none; color:#fff; padding:8px 16px; border-radius:4px; cursor:pointer;">Add Button</button>
                <button id="close-button" style="background-color:#555; border:none; color:#fff; padding:8px 16px; border-radius:4px; cursor:pointer;">Close</button>
            </div>
        `;

        document.body.appendChild(addButtonModal);

        const infoTexts = {
            'website-name': `This is the button name shown in settings. It doesn't have to match the site exactly.`,
            'icon-url': `Direct link to an image (PNG/JPEG) used as the button icon. Example: https://i.imgur.com/abcd123.png`,
            'search-url': `The base URL for a search on the site, WITHOUT the search term.
    Example:
    • Google: https://www.google.com/search?q=
    • Or use %s placeholder if not at the end (e.g., https://example.com/search?query=%s&type=games)`,
            'color': `The background color for the button.`
        };

        Object.keys(infoTexts).forEach(id => {
            const btn = document.getElementById(`info-${id}`);
            btn.addEventListener('click', () => alert(infoTexts[id]));
        });

        document.getElementById('save-new-button').addEventListener('click', () => {
            const name = document.getElementById('website-name').value.trim();
            const iconUrl = document.getElementById('icon-url').value.trim();
            const searchUrl = document.getElementById('search-url').value.trim();
            const color = document.getElementById('color').value.trim();

            if (!name || !iconUrl || !searchUrl || !color) {
                alert('Please fill in all fields.');
                return;
            }

            if (buttons.some(b => b.name.toLowerCase() === name.toLowerCase())) {
                alert('A button with this name already exists.');
                return;
            }

            buttons.push({ name, iconUrl, searchUrl, color, status: true });
            GM_setValue('buttons', buttons);
            alert(`✅ "${name}" button added successfully!`);
            window.location.reload();
        });

        document.getElementById('close-button').addEventListener('click', () => addButtonModal.remove());
        document.getElementById('import-json').addEventListener('click', () => {
            const importModal = document.createElement('div');
            Object.assign(importModal.style, {
                position: 'fixed',
                top: '50%',
                left: '50%',
                transform: 'translate(-50%, -50%)',
                backgroundColor: '#242832',
                borderRadius: '10px',
                padding: '20px',
                zIndex: '10000',
                width: '420px',
                color: '#fff',
                textAlign: 'left',
                boxShadow: '0 0 12px rgba(0,0,0,0.5)'
            });
            importModal.innerHTML = `
                <h3>Import Buttons from JSON</h3>
                <p style="font-size:12px;">Paste your JSON below and click Import:</p>
                <textarea id="json-input" placeholder='[{"Website Name":"Example","Icon URL":"https://i.imgur.com/abcd.png","Search URL":"https://example.com/search?q=","Button Color":"#123456"}]'
                    style="width:100%;height:150px;background:#1a1d25;color:#fff;border:1px solid #555;border-radius:5px;padding:8px;resize:none;"></textarea>
                <div style="display:flex;justify-content:space-between;margin-top:10px;">
                    <button id="import-confirm" style="background-color:#fc6399;border:none;color:#fff;padding:6px 12px;border-radius:4px;cursor:pointer;">Import</button>
                    <button id="import-cancel" style="background-color:#4a5e8d;border:none;color:#fff;padding:6px 12px;border-radius:4px;cursor:pointer;">Cancel</button>
                </div>
            `;
            document.body.appendChild(importModal);

            document.getElementById('import-cancel').addEventListener('click', () => importModal.remove());
            document.getElementById('import-confirm').addEventListener('click', () => {
                const raw = document.getElementById('json-input').value.trim();
                if (!raw) return alert('Please paste JSON first.');

                try {
                    const arr = JSON.parse(raw);
                    if (!Array.isArray(arr)) throw new Error('Expected an array of objects.');
                    let added = 0;
                    arr.forEach(entry => {
                        const name = entry['Website Name'];
                        const iconUrl = entry['Icon URL'];
                        const searchUrl = entry['Search URL'];
                        const color = entry['Button Color'];
                        if (name && iconUrl && searchUrl && color && !buttons.some(b => b.name.toLowerCase() === name.toLowerCase())) {
                            buttons.push({ name, iconUrl, searchUrl, color, status: true });
                            added++;
                        }
                    });
                    if (added) {
                        GM_setValue('buttons', buttons);
                        alert(`✅ Imported ${added} new button(s)!`);
                        window.location.reload();
                    } else {
                        alert('No valid or new buttons found.');
                    }
                } catch (e) {
                    alert('❌ Invalid JSON: ' + e.message);
                }
            });
        });
    }


    function waitForElement(selector, callback, maxAttempts = 50) {
        let attempts = 0;
        const interval = setInterval(() => {
            const element = document.querySelector(selector);
            if (element) {
                clearInterval(interval);
                callback(element);
            } else if (++attempts >= maxAttempts) {
                clearInterval(interval);
                console.log(`Element ${selector} not found after ${maxAttempts} attempts`);
            }
        }, 100);
    }

    function addAtButton() {
        const commentRows = document.querySelectorAll('.row.mb-2');
        commentRows.forEach(row => {
            if (!row.querySelector('.at-button')) {
                const atButton = document.createElement('div');
                atButton.className = 'col-auto mt-auto pl-0 pr-1 at-button';
                atButton.innerHTML = '<button class="button-link secondary-link" style="cursor: pointer;">@</button>';

                const usernameDiv = row.querySelector('.col-auto.mt-auto.px-2');
                if (usernameDiv) {
                    const usernameLink = usernameDiv.querySelector('a.secondary-link');
                    if (usernameLink) {
                        const username = usernameLink.textContent.trim();
                        atButton.querySelector('button').addEventListener('click', () => {
                            const commentBox = document.getElementById('comment_body');
                            if (commentBox) {
                                const currentText = commentBox.value;
                                const cursorPosition = commentBox.selectionStart;
                                const textBefore = currentText.substring(0, cursorPosition);
                                const textAfter = currentText.substring(cursorPosition);
                                const newText = `${textBefore}@${username} ${textAfter}`;
                                commentBox.value = newText;
                                commentBox.focus();
                                const newCursorPosition = cursorPosition + username.length + 2;
                                commentBox.setSelectionRange(newCursorPosition, newCursorPosition);
                            }
                        });

                        row.appendChild(atButton);
                    }
                }
            }
        });
    }

    function processElements() {
        addAtButton();
    }

    const style = document.createElement('style');
    style.textContent = `
        .settings-modal button:hover {
            filter: brightness(85%);
        }

        /* Custom main buttons hover effect */
        .custom-button {
            transition: transform 0.15s ease, box-shadow 0.15s ease, border 0.15s ease;
            border: 2px solid transparent; /* default border */
        }

        .custom-button:hover {
            transform: translateY(-3px) scale(1.05);
            border: 2px solid rgba(255, 255, 255, 0.35); /* slightly lighter than button */
            box-shadow: 0 4px 8px rgba(0,0,0,0.3);
        }
        .custom-btn-row {
            display: flex;
            flex-wrap: wrap;
            align-items: flex-end;
            justify-content: flex-start; /* changed from space-between */
            margin-top: 6px;
        }

        .custom-btn-container {
            flex: 0 0 25%;   /* keeps each button container 1/4 of the row */
            max-width: 25%;
            display: flex;
            justify-content: center;
        }


        .custom-button {
            color: #fff;
            cursor: pointer;
        }

        .custom-button img {
            filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3));
        }
    `;
    document.head.appendChild(style);

    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            if (mutation.type === 'childList') {
                const addedNodes = Array.from(mutation.addedNodes);
                addedNodes.forEach(node => {
                    if (node.nodeType === Node.ELEMENT_NODE) {
                        if (node.classList && (node.classList.contains('comments-section') || node.closest('.comments-section'))) {
                            processElements();
                        }
                    }
                });
            }
        });
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    function initializeButtons() {
        waitForElement('hr.mb-3.mt-2.d-none.d-md-flex', () => {
            addSpacer();
            updateButtons();
            processElements();
        });
    }

    initializeButtons();

    let lastUrl = location.href;
    new MutationObserver(() => {
        const url = location.href;
        if (url !== lastUrl) {
            lastUrl = url;
            console.log('URL changed, reinitializing buttons...');
            setTimeout(() => {
                initializeButtons();
            }, 300);
        }
    }).observe(document, { subtree: true, childList: true });

    window.addEventListener('hashchange', () => {
        console.log('Hash changed, reinitializing buttons...');
        setTimeout(() => {
            initializeButtons();
        }, 300);
    });
    const CURRENT_NOTICE_VERSION = 'debug';
    const hasSeenNotice = GM_getValue(CURRENT_NOTICE_VERSION, false);

    if (!hasSeenNotice) {
        const noticeModal = document.createElement('div');
        noticeModal.style.position = 'fixed';
        noticeModal.style.top = '50%';
        noticeModal.style.left = '50%';
        noticeModal.style.transform = 'translate(-50%, -50%)';
        noticeModal.style.backgroundColor = '#242831';
        noticeModal.style.border = '1px solid #444';
        noticeModal.style.borderRadius = '10px';
        noticeModal.style.padding = '20px';
        noticeModal.style.zIndex = '99999';
        noticeModal.style.color = '#fff';
        noticeModal.style.textAlign = 'center';
        noticeModal.style.boxShadow = '0 0 15px rgba(0,0,0,0.6)';
        noticeModal.innerHTML = `
            <h1 style="margin-bottom: 20px;">BACKLOGGD BUTTONS - 2.6</h1>
            <p style="font-size: 19px; margin-bottom: 20px;">
                If you are updating please flush the memory.
                (This will reset all of your settings!)
                You can also export your buttons in the settings.
            </p>
            <div style="display:flex; gap:8px; justify-content:center;">
                <button id="notice-flush-btn" style="
                    background-color: #ff4444;
                    border: none;
                    color: white;
                    padding: 8px 16px;
                    border-radius: 6px;
                    cursor: pointer;
                ">Flush Memory</button>
                <button id="notice-ok-btn" style="
                    background-color: #fc6399;
                    border: none;
                    color: white;
                    padding: 8px 16px;
                    border-radius: 6px;
                    cursor: pointer;
                ">Got it</button>
            </div>
        `;

        document.body.appendChild(noticeModal);

        const originalFlushMemory = () => {
            if (confirm('Are you sure you want to flush all saved buttons and reset the script?')) {
                const preserveNotice = GM_getValue(CURRENT_NOTICE_VERSION, true);
                GM_setValue('buttons', undefined);
                GM_setValue(CURRENT_NOTICE_VERSION, preserveNotice);
                window.location.reload();
            }
        };

        document.getElementById('notice-ok-btn').addEventListener('click', () => {
            GM_setValue(CURRENT_NOTICE_VERSION, true);
            noticeModal.remove();
        });
        document.getElementById('notice-flush-btn').addEventListener('click', () => {
            originalFlushMemory();
        });
    }


    const originalFlushMemory = () => {
        if (confirm('Are you sure you want to flush all saved buttons and reset the script?')) {
            const preserveNotice = GM_getValue(CURRENT_NOTICE_VERSION, true);
            GM_setValue('buttons', undefined);
            GM_setValue(CURRENT_NOTICE_VERSION, preserveNotice);
            window.location.reload();
        }
    };

    document.addEventListener('click', (e) => {
        if (e.target && e.target.id === 'flush-memory-btn') {
            e.preventDefault();
            originalFlushMemory();
        }
    });

})();