TornPDA Quick Link Sidebar (Improved)

Custom sidebar with user-defined quick links (mobile optimized)

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         TornPDA Quick Link Sidebar (Improved)
// @namespace    torn.custom.sidebar
// @version      2.1
// @description  Custom sidebar with user-defined quick links (mobile optimized)
// @match        https://www.torn.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const STORAGE_KEY = "torn_custom_links";

    function getLinks() {
        return JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];
    }

    function saveLinks(links) {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(links));
    }

    // -------------------------
    // TOGGLE TAB
    // -------------------------
    const toggle = document.createElement("div");
    toggle.innerText = "☰";
    toggle.style.position = "fixed";
    toggle.style.left = "0";
    toggle.style.top = "45%";
    toggle.style.width = "30px";
    toggle.style.height = "60px";
    toggle.style.background = "#111";
    toggle.style.color = "#fff";
    toggle.style.display = "flex";
    toggle.style.alignItems = "center";
    toggle.style.justifyContent = "center";
    toggle.style.borderRadius = "0 8px 8px 0";
    toggle.style.zIndex = "9999";
    toggle.style.cursor = "pointer";
    document.body.appendChild(toggle);

    // -------------------------
    // SIDEBAR PANEL
    // -------------------------
    const panel = document.createElement("div");
    panel.style.position = "fixed";
    panel.style.left = "-45%";
    panel.style.top = "10%"; // keeps the offset
    panel.style.width = "45%"; // wider panel
    panel.style.height = "90%";
    panel.style.background = "#2b2b2b"; // grey background
    panel.style.color = "#fff";
    panel.style.zIndex = "9998";
    panel.style.transition = "0.3s";
    panel.style.padding = "10px";
    panel.style.boxSizing = "border-box";
    panel.style.overflowY = "auto";
    panel.style.boxShadow = "2px 0 10px rgba(0,0,0,0.6)";
    document.body.appendChild(panel);

    let isOpen = false;

    toggle.onclick = () => {
        isOpen = !isOpen;
        panel.style.left = isOpen ? "0" : "-45%";
    };

    // -------------------------
    // PANEL CONTENT
    // -------------------------
    const title = document.createElement("h3");
    title.innerText = "Quick Links";
    title.style.marginTop = "0";
    panel.appendChild(title);

    // ADD BUTTON (BLACK)
    const addBtn = document.createElement("button");
    addBtn.innerText = "➕ Add Button";
    addBtn.style.width = "100%";
    addBtn.style.marginBottom = "10px";
    addBtn.style.background = "#000";
    addBtn.style.color = "#fff";
    addBtn.style.border = "none";
    addBtn.style.padding = "10px";
    addBtn.style.borderRadius = "6px";
    panel.appendChild(addBtn);

    // INPUT CONTAINER (NO PROMPTS)
    const inputContainer = document.createElement("div");
    inputContainer.style.display = "none";
    inputContainer.style.marginBottom = "10px";

    const nameInput = document.createElement("input");
    nameInput.placeholder = "Button name";
    nameInput.style.width = "100%";
    nameInput.style.marginBottom = "5px";

    const urlInput = document.createElement("input");
    urlInput.placeholder = "Torn link";
    urlInput.style.width = "100%";
    urlInput.style.marginBottom = "5px";

    const saveBtn = document.createElement("button");
    saveBtn.innerText = "Save";
    saveBtn.style.width = "100%";
    saveBtn.style.background = "#444";
    saveBtn.style.color = "#fff";
    saveBtn.style.border = "none";
    saveBtn.style.padding = "8px";

    inputContainer.appendChild(nameInput);
    inputContainer.appendChild(urlInput);
    inputContainer.appendChild(saveBtn);
    panel.appendChild(inputContainer);

    const listContainer = document.createElement("div");
    panel.appendChild(listContainer);

    // -------------------------
    // CLEAR ALL BUTTON
    // -------------------------
    const clearBtn = document.createElement("button");
    clearBtn.innerText = "🧹 Clear All Buttons";
    clearBtn.style.width = "100%";
    clearBtn.style.marginTop = "20px";
    clearBtn.style.background = "#444";
    clearBtn.style.color = "#fff";
    clearBtn.style.border = "none";
    clearBtn.style.padding = "10px";
    clearBtn.style.borderRadius = "6px";
    panel.appendChild(clearBtn);

    // -------------------------
    // RENDER LINKS
    // -------------------------
    function renderLinks() {
        listContainer.innerHTML = "";
        const links = getLinks();

        links.forEach((link, index) => {
            const btn = document.createElement("button");
            btn.innerText = link.name;
            btn.style.width = "100%";
            btn.style.marginBottom = "8px";
            btn.style.padding = "10px";
            btn.style.background = "#3a3a3a";
            btn.style.color = "#fff";
            btn.style.border = "none";
            btn.style.borderRadius = "6px";

            btn.onclick = () => {
                window.location.href = link.url;
                panel.style.left = "-45%"; // close panel after click
            };

            // LONG PRESS DELETE
            let pressTimer;
            btn.onmousedown = () => {
                pressTimer = setTimeout(() => {
                    if (confirm("Delete this button?")) {
                        const links = getLinks();
                        links.splice(index, 1);
                        saveLinks(links);
                        renderLinks();
                    }
                }, 800);
            };

            btn.onmouseup = () => clearTimeout(pressTimer);
            btn.onmouseleave = () => clearTimeout(pressTimer);

            listContainer.appendChild(btn);
        });
    }

    // -------------------------
    // ADD BUTTON FLOW
    // -------------------------
    addBtn.onclick = () => {
        inputContainer.style.display =
            inputContainer.style.display === "none" ? "block" : "none";
    };

    saveBtn.onclick = () => {
        const name = nameInput.value.trim();
        const url = urlInput.value.trim();

        if (!name || !url) {
            alert("Fill in both fields");
            return;
        }

        const links = getLinks();
        links.push({ name, url });
        saveLinks(links);

        nameInput.value = "";
        urlInput.value = "";
        inputContainer.style.display = "none";

        renderLinks();
    };

    // -------------------------
    // CLEAR ALL FLOW
    // -------------------------
    clearBtn.onclick = () => {
        if (confirm("Are you sure you want to delete all buttons?")) {
            saveLinks([]);
            renderLinks();
        }
    };

    // INIT
    renderLinks();

})();