Vinted Dark Mode

Global Dark Mode for Vinted (buttons, inputs, chips, navigation, stars, titles, footer, SPA support, app store badges)

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name         Vinted Dark Mode
// @namespace    https://greasyfork.org/en/users/1550823-nigel1992
// @version      0.30
// @description  Global Dark Mode for Vinted (buttons, inputs, chips, navigation, stars, titles, footer, SPA support, app store badges)
// @author       Nigel1992
// @match        *://*.vinted.at/*
// @match        *://*.vinted.be/*
// @match        *://*.vinted.co.uk/*
// @match        *://*.vinted.cz/*
// @match        *://*.vinted.de/*
// @match        *://*.vinted.dk/*
// @match        *://*.vinted.es/*
// @match        *://*.vinted.fr/*
// @match        *://*.vinted.hu/*
// @match        *://*.vinted.it/*
// @match        *://*.vinted.lt/*
// @match        *://*.vinted.lu/*
// @match        *://*.vinted.nl/*
// @match        *://*.vinted.pl/*
// @match        *://*.vinted.pt/*
// @match        *://*.vinted.ro/*
// @match        *://*.vinted.se/*
// @match        *://*.vinted.sk/*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at      document-start
// @license MIT
// ==/UserScript==

(function () {
    'use strict';

    const darkCSS = `
    /* ===== Base Dark Mode Colors ===== */
    html.dark-mode {
        --color-background-primary: #121212 !important;
        --color-background-secondary: #1a1a1a !important;
        --color-text-primary: #e0e0e0 !important;
        --color-text-secondary: #aaaaaa !important;
        --color-border-primary: #333333 !important;
        --color-button-primary-background: #007782 !important;
        --color-button-primary-text: #ffffff !important;
    }
    html.dark-mode, html.dark-mode body, html.dark-mode #content, html.dark-mode .viewport, html.dark-mode .web_ui__Page__page, html.dark-mode [class*="u-background-white"] {
        background-color: #121212 !important;
        color: #e0e0e0 !important;
        transition: background 0.3s ease, color 0.3s ease;
    }

    /* ===== Headers, Tabs ===== */
    html.dark-mode .l-header, html.dark-mode .l-header__main, html.dark-mode .l-header__navigation, html.dark-mode .web_ui__Tabs__tabs {
        background-color: #121212 !important;
        border-bottom: 1px solid #333 !important;
    }

    /* ===== Text, feeds ===== */
    html.dark-mode svg { fill: #ffffff !important; stroke: #ffffff !important; }
    html.dark-mode .feed-grid, html.dark-mode .catalog-container, html.dark-mode .u-bg-white { background-color: #121212 !important; }
    html.dark-mode .web_ui__Text__text, html.dark-mode p, html.dark-mode span, html.dark-mode h1, html.dark-mode h2, html.dark-mode h3 { color: #e0e0e0 !important; }

    /* ===== Inbox / Thread ===== */
    html.dark-mode .inbox-page__container, html.dark-mode .inbox-page__block, html.dark-mode .thread__wrapper, html.dark-mode .thread__messages-container, html.dark-mode .thread__content { background-color: #121212 !important; }
    html.dark-mode .inbox-page__block--sidebar, html.dark-mode .conversation-list-toolbar, html.dark-mode .u-fill-height.u-overflow-auto { background-color: #121212 !important; }
    html.dark-mode [data-testid^="inbox-list-item"], html.dark-mode .web_ui__Cell__cell { background-color: #121212 !important; border-bottom: 1px solid #2a2a2a !important; }
    html.dark-mode .u-background-gray { background-color: #1a1a1a !important; }
    html.dark-mode .web_ui__Cell__navigating:hover { background-color: #1e1e1e !important; }
    html.dark-mode .web_ui__Card__card, html.dark-mode .web_ui__Card__lifted { background-color: #1a1a1a !important; border: 1px solid #2a2a2a !important; }
    html.dark-mode .conversation-header { background-color: #121212 !important; border-bottom: 1px solid #333 !important; }
    html.dark-mode .web_ui__Bubble__bubble { background-color: #1e1e1e !important; color: #e0e0e0 !important; }
    html.dark-mode .web_ui__Bubble__inverse { background-color: #007782 !important; color: #ffffff !important; }
    html.dark-mode .web_ui__Text__caption { color: #999 !important; }
    html.dark-mode .web_ui__Divider__divider { background-color: #2a2a2a !important; }

    /* ===== Dark Mode Buttons: Toggle & Bug ===== */
    #vinted-dark-toggle, #vinted-bug-report {
        position: fixed;
        right: 20px;
        z-index: 9999;
        padding: 10px 18px;
        border-radius: 50px;
        font-weight: bold;
        cursor: pointer;
        box-shadow: 0 4px 15px rgba(0,0,0,0.6);
        text-align: center;
        font-family: sans-serif;
    }
    #vinted-dark-toggle { bottom: 70px; background: #2a2a2a; color: #ffffff; border: 1px solid #555; }
    #vinted-bug-report { bottom: 20px; background: #ff5555; color: #fff; border: 1px solid #cc0000; }
    #vinted-dark-toggle:hover { background: #3a3a3a; }
    #vinted-bug-report:hover { background: #ff3333; }

    @media (max-width: 600px) {
        #vinted-dark-toggle, #vinted-bug-report { right: 10px; padding: 8px 14px; font-size: 14px; }
        #vinted-dark-toggle { bottom: 60px; }
        #vinted-bug-report { bottom: 10px; }
    }

    /* ===== Chips ===== */
    html.dark-mode .web_ui__Chip__chip {
        background-color: #007782 !important;
        color: #ffffff !important;
        border-color: #005f63 !important;
    }
    html.dark-mode .web_ui__Chip__chip .web_ui__Text__text { color: #ffffff !important; }
    html.dark-mode .web_ui__Chip__chip svg { fill: #ffffff !important; stroke: #ffffff !important; }
    html.dark-mode .web_ui__Chip__chip.web_ui__Chip__outlined { border-color: #ffffff !important; }

    /* ===== Inputs ===== */
    html.dark-mode .web_ui__Input__input { background-color: #1a1a1a !important; border: 1px solid #333 !important; color: #e0e0e0 !important; }
    html.dark-mode .web_ui__Input__title { color: #e0e0e0 !important; }
    html.dark-mode .web_ui__Input__value { background-color: #222 !important; color: #ffffff !important; border: none !important; caret-color: #ffffff !important; }

    /* ===== Navigation & Buttons ===== */
    html.dark-mode .web_ui__Button__button {
        background-color: #007782 !important;
        color: #ffffff !important;
        border: 1px solid #005f63 !important;
    }
    html.dark-mode .web_ui__Button__button .web_ui__Button__content,
    html.dark-mode .web_ui__Button__button .web_ui__Button__icon,
    html.dark-mode .web_ui__Button__button svg {
        color: #ffffff !important;
        fill: #ffffff !important;
        stroke: #ffffff !important;
    }

    /* ===== Star Ratings ===== */
    html.dark-mode .web_ui__Rating__star .web_ui__Icon__icon svg path {
        fill: #007782 !important;
    }

    /* ===== Cell Titles ===== */
    html.dark-mode .web_ui__Cell__title {
        color: #007782 !important;
    }

    /* ===== Footer Dark Mode ===== */
    html.dark-mode .main-footer__content {
        background-color: #121212 !important;
        color: #e0e0e0 !important;
    }
    html.dark-mode .main-footer__links-section-label {
        color: #007782 !important;
    }
    html.dark-mode .main-footer__links-section-link,
    html.dark-mode .main-footer__privacy-section-link,
    html.dark-mode .main-footer__privacy-section-link button {
        color: #007782 !important;
    }
    html.dark-mode .web_ui__Divider__divider {
        background-color: #2a2a2a !important;
    }

    /* ===== Footer Social Icons ===== */
    html.dark-mode .main-footer__social-media-link img {
        filter: brightness(0) invert(1);
    }

    /* ===== Footer App Store Badges ===== */
    html.dark-mode .main-footer__social-section-app-store {
        background-color: #121212 !important;
        padding: 10px 0;
    }
    html.dark-mode .main-footer__social-app-store-item {
        margin-right: 10px;
    }
    html.dark-mode .main-footer__social-app-store-item a {
        display: inline-block;
    }
    html.dark-mode .main-footer__social-app-store-item img {
        filter: none !important;
        background-color: #121212;
        border-radius: 5px;
        padding: 2px;
    }
    `;

    GM_addStyle(darkCSS);

    const htmlEl = document.documentElement;

    // Dark mode preference
    let isDark = GM_getValue('darkMode', null);
    if (isDark === null) {
        isDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
        GM_setValue('darkMode', isDark);
    }
    if (isDark) htmlEl.classList.add('dark-mode');

    function onBodyReady(callback) {
        if (document.body) return callback();
        new MutationObserver((obs) => {
            if (document.body) {
                obs.disconnect();
                callback();
            }
        }).observe(document.documentElement, { childList: true, subtree: true });
    }

    onBodyReady(() => {
        // ===== Create Toggle & Bug Buttons =====
        const darkBtn = document.createElement('button');
        darkBtn.id = 'vinted-dark-toggle';
        darkBtn.textContent = isDark ? '☀️ Light' : '🌙 Dark';
        document.body.appendChild(darkBtn);

        const bugBtn = document.createElement('button');
        bugBtn.id = 'vinted-bug-report';
        bugBtn.textContent = '🐞 Report Issue';
        document.body.appendChild(bugBtn);

        bugBtn.addEventListener('click', () => {
            if (document.getElementById('vinted-bug-modal')) return;
            const overlay = document.createElement('div');
            overlay.id = 'vinted-bug-modal';
            Object.assign(overlay.style, {
                position: 'fixed', top: 0, left: 0, width: '100%', height: '100%',
                background: 'rgba(0,0,0,0.6)', display: 'flex', alignItems: 'center',
                justifyContent: 'center', zIndex: 9999
            });

            const modal = document.createElement('div');
            Object.assign(modal.style, {
                background: '#1a1a1a', color: '#e0e0e0', padding: '20px 25px', borderRadius: '10px',
                maxWidth: '400px', textAlign: 'center', fontFamily: 'sans-serif',
                boxShadow: '0 4px 15px rgba(0,0,0,0.5)'
            });

            modal.innerHTML = `
                <p>⚠️ Please check the known issues first:</p>
                <p><a href="https://greasyfork.org/en/scripts/560002-vinted-dark-mode-toggle" target="_blank" style="color:#00bcd4; text-decoration:underline;">Vinted Dark Mode Known Issues</a></p>
                <button id="vinted-bug-ok" style="
                    margin-top: 15px;
                    padding: 8px 16px;
                    border:none;
                    border-radius:5px;
                    background:#007782;
                    color:#fff;
                    font-weight:bold;
                    cursor:pointer;
                ">Unknown issue? Click here to report</button>
            `;
            overlay.appendChild(modal);
            document.body.appendChild(overlay);

            document.getElementById('vinted-bug-ok').addEventListener('click', () => {
                document.body.removeChild(overlay);
                window.open('https://greasyfork.org/en/scripts/560002-vinted-dark-mode-toggle/feedback', '_blank');
            });
        });

        // ===== Dark Mode Toggle Event =====
        darkBtn.addEventListener('click', () => {
            isDark = !isDark;
            htmlEl.classList.toggle('dark-mode', isDark);
            darkBtn.textContent = isDark ? '☀️ Light' : '🌙 Dark';
            GM_setValue('darkMode', isDark);
        });
    });

    // ===== SPA & URL Observer (throttled) =====
    let lastUrl = location.href;
    let throttleTimeout = null;
    new MutationObserver(() => {
        if (throttleTimeout) return;
        throttleTimeout = setTimeout(() => {
            throttleTimeout = null;
            const currentUrl = location.href;
            if (currentUrl !== lastUrl) {
                lastUrl = currentUrl;
                if (GM_getValue('darkMode', false)) htmlEl.classList.add('dark-mode');
            }
        }, 200);
    }).observe(document.body || document.documentElement, { childList: true, subtree: true });

})();