Reddit Corner Buttons (Saved Posts & Messages) + Reddit AD Button Hider

Adds buttons to access Saved Posts and Messages (bottom-right corner) and hides the 'Advertise' button/link on Reddit using its ID. Handles SPA navigation and iframe issues.

目前為 2025-05-12 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Reddit Corner Buttons (Saved Posts & Messages) + Reddit AD Button Hider
// @namespace    Https://github.com/ctrlcmdshft/RedditQuickAccess
// @version      2.3 // Version updated
// @description  Adds buttons to access Saved Posts and Messages (bottom-right corner) and hides the 'Advertise' button/link on Reddit using its ID. Handles SPA navigation and iframe issues.
// @author       CtrlCmdShft
// @match        https://www.reddit.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=reddit.com
// @noframes     // Crucial: Prevents the script from running in iframes, avoiding duplicate runs on pages like Messages.
// @grant        GM_addStyle
// @run-at       document-start // Run early to set the global flag and inject styles.
// @license      MIT // Example license, feel free to change
// ==/UserScript==

(function() {
    'use strict';

    /* --- Configuration --- */

    // Constants for button IDs and URLs
    const SAVED_URL = 'https://www.reddit.com/user/me/saved';
    const MESSAGES_URL = 'https://www.reddit.com/message/inbox'; // Base URL for messages page check
    const SAVED_BUTTON_ID = 'userscript-reddit-saved-button';
    const MESSAGES_BUTTON_ID = 'userscript-reddit-messages-button';
    const ADVERTISE_BUTTON_ID = 'advertise-button'; // <-- ID of the button to hide

    // SVG Icons for the buttons
    const BOOKMARK_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M17 3H7c-1.1 0-2 .9-2 2v16l7-3 7 3V5c0-1.1-.9-2-2-2z"/></svg>`;
    const MAIL_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor" aria-hidden="true"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6zm-2 0l-8 5-8-5h16zm0 12H4V8l8 5 8-5v10z"/></svg>`;

    /* --- Initialization Guard (Global Flag) --- */

    const GLOBAL_FLAG_NAME = '__redditCornerButtonsInitialized_v2_5__'; // Use a versioned name
    if (window[GLOBAL_FLAG_NAME]) {
        // console.log(`Reddit Corner Buttons & Ad Hider: Global flag ${GLOBAL_FLAG_NAME} found. Aborting secondary execution.`);
        return;
    }
    window[GLOBAL_FLAG_NAME] = true;
    // console.log(`Reddit Corner Buttons & Ad Hider: Global flag ${GLOBAL_FLAG_NAME} set by this instance.`);


    /* --- Styling --- */

    // CSS styles for the buttons and ad hiding.
    const styles = `
        /* Corner Buttons Base Style */
        .userscript-corner-button {
            position: fixed;
            right: 20px;
            z-index: 1001;
            width: 40px;
            height: 40px;
            color: #ffffff;
            border: none;
            border-radius: 50%;
            cursor: pointer;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            transition: background-color 0.2s;
            display: flex !important; /* Use !important needed sometimes on Reddit */
            align-items: center;
            justify-content: center;
            padding: 0;
        }
        .userscript-corner-button svg {
            width: 20px;
            height: 20px;
        }

        /* Saved Posts Button */
        #${SAVED_BUTTON_ID} {
            bottom: 20px;
            background-color: #ff4500; /* Reddit Orange */
        }
        #${SAVED_BUTTON_ID}:hover {
            background-color: #ff5722; /* Lighter orange */
        }

        /* Messages Button */
        #${MESSAGES_BUTTON_ID} {
            bottom: 70px; /* Position above saved button */
            background-color: #0079D3; /* Reddit Blue */
        }
        #${MESSAGES_BUTTON_ID}:hover {
            background-color: #1484D7; /* Lighter blue */
        }

        /* --- Hide the 'Advertise' Button using its ID --- */
        #${ADVERTISE_BUTTON_ID} {
            display: none !important; /* Hide element and remove from layout */
        }
    `;
    // Inject the styles into the page head.
    try {
        GM_addStyle(styles);
        // console.log("Reddit Corner Buttons & Ad Hider: Styles injected.");
    } catch (e) {
        console.error("Reddit Corner Buttons & Ad Hider: Failed to inject styles using GM_addStyle.", e);
    }


    /* --- Core Functions --- */

    /**
     * Creates a button element based on provided options.
     * @param {object} options - Button properties (id, title, svgHTML, url).
     * @returns {HTMLButtonElement|null} The created button element or null on error.
     */
    function createButtonElement(options) {
        try {
            const button = document.createElement('button');
            button.id = options.id;
            button.className = 'userscript-corner-button';
            button.title = options.title;
            button.setAttribute('aria-label', options.title);
            button.innerHTML = options.svgHTML;

            button.onclick = function() {
                window.location.href = options.url;
            };
            return button;
        } catch (e) {
            console.error(`Reddit Corner Buttons & Ad Hider: Error creating button element ${options.id}:`, e);
            return null;
        }
    }

    /**
     * Removes existing corner buttons from the DOM.
     */
    function removeExistingButtons() {
        const idsToRemove = [SAVED_BUTTON_ID, MESSAGES_BUTTON_ID];
        // console.log("Reddit Corner Buttons & Ad Hider: Checking for and removing existing buttons...");
        idsToRemove.forEach(id => {
            const existingButton = document.getElementById(id);
            if (existingButton) {
                // console.log(` - Removing button with ID: ${id}`);
                existingButton.remove();
            }
        });
    }

    /**
     * Ensures corner buttons are present. Removes existing ones and adds new ones.
     */
    function initializeOrRefreshButtons() {
        if (!document.body) {
             console.error("Reddit Corner Buttons & Ad Hider: initializeOrRefreshButtons called but document.body not found!");
             return;
        }
        // console.log("Reddit Corner Buttons & Ad Hider: Running initializeOrRefreshButtons...");

        // 1. Remove potentially lingering buttons
        removeExistingButtons();

        // 2. Define button configurations
        const buttonConfigs = [
            { id: SAVED_BUTTON_ID, title: 'View Saved Posts', svgHTML: BOOKMARK_ICON_SVG, url: SAVED_URL },
            { id: MESSAGES_BUTTON_ID, title: 'View Messages', svgHTML: MAIL_ICON_SVG, url: MESSAGES_URL }
        ];

        // 3. Create and append each button
        buttonConfigs.forEach(config => {
            const buttonElement = createButtonElement(config);
            if (buttonElement) {
                try {
                    document.body.appendChild(buttonElement);
                    // console.log(` - Successfully created and appended button: ${config.id}`);
                } catch(e) {
                    console.error(`Reddit Corner Buttons & Ad Hider: Failed to append button ${config.id} to body:`, e);
                }
            }
        });
        // console.log("Reddit Corner Buttons & Ad Hider: Button refresh/initialization complete.");
    }


    /* --- Initialization Trigger --- */

    // Logic for initializing corner buttons (no changes needed here for the ad hiding part)
    const isOnMessagesPageInitially = window.location.href.startsWith(MESSAGES_URL);

    if (isOnMessagesPageInitially) {
        // Special Handling for Messages Page
        // console.log("Reddit Corner Buttons & Ad Hider: On messages page. Waiting for 'load' event.");
        if (document.readyState === 'complete') {
            // console.log("Reddit Corner Buttons & Ad Hider: 'load' event already complete, running initialization now.");
            initializeOrRefreshButtons();
        } else {
            window.addEventListener('load', initializeOrRefreshButtons);
        }
    } else {
        // Standard Handling for Other Pages
        // console.log("Reddit Corner Buttons & Ad Hider: Not on messages page. Waiting for 'DOMContentLoaded'.");
        if (document.readyState === 'interactive' || document.readyState === 'complete') {
            // console.log("Reddit Corner Buttons & Ad Hider: 'DOMContentLoaded' already complete, running initialization now.");
            initializeOrRefreshButtons();
        } else {
            window.addEventListener('DOMContentLoaded', initializeOrRefreshButtons);
        }
    }


    /* --- Global Flag Cleanup --- */

    window.addEventListener('beforeunload', () => {
        // console.log(`Reddit Corner Buttons & Ad Hider: Clearing global flag ${GLOBAL_FLAG_NAME} on beforeunload.`);
        delete window[GLOBAL_FLAG_NAME];
    });

})(); // End of UserScript IIFE