TornPDA Quick Link Sidebar (Improved)

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

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==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();

})();