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 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 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