MyAnonamouse RSS Nicknames

Add nicknames to MyAnonamouse RSS feeds.

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

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

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

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

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         MyAnonamouse RSS Nicknames
// @version      1.0
// @description  Add nicknames to MyAnonamouse RSS feeds.
// @author       Gorginian
// @namespace    https://www.myanonamouse.net/u/253587
// @match        https://www.myanonamouse.net/getrss.php*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_listValues
// @grant        GM_deleteValue
// ==/UserScript==

(function () {
    'use strict';

    window.addEventListener('load', async () => {
        const container = document.querySelector('#mainBody .blockBodyCon.left');
        if (!container) return;

        const feedLinks = container.querySelectorAll('a[href^="https://"][href*="/rss/"]');
        for (const feedLink of feedLinks) {
            const match = feedLink.href.match(/\/rss\/([a-f0-9]{8})/i);
            if (!match) continue;

            const feedId = match[1];
            const originalText = feedId;

            const nickname = await GM_getValue(feedId);
            if (nickname) {
                feedLink.textContent = nickname;
            }

            const nicknameBtn = document.createElement('a');
            nicknameBtn.href = '#';
            nicknameBtn.textContent = 'rename';
            nicknameBtn.style.margin = '0 5px';
            nicknameBtn.style.cursor = 'pointer';

            nicknameBtn.addEventListener('click', async (e) => {
                e.preventDefault();
                const current = await GM_getValue(feedId, feedLink.textContent);
                const newNick = prompt('Enter nickname (blank to reset):', current);

                if (newNick === null) return;

                if (newNick.trim() === '') {
                    await GM_deleteValue(feedId);
                    feedLink.textContent = originalText;
                } else {
                    await GM_setValue(feedId, newNick.trim());
                    feedLink.textContent = newNick.trim();
                }
            });

            let next = feedLink.nextSibling;
            while (next && !(next.tagName === 'A' && next.textContent === 'edit')) {
                next = next.nextSibling;
            }

            if (next) {
                container.insertBefore(nicknameBtn, next);
            } else {
                feedLink.after(nicknameBtn);
            }
        }

        const controlDiv = document.createElement('div');
        controlDiv.style.marginTop = '2em';

        const exportBtn = document.createElement('button');
        exportBtn.textContent = 'Export Nicknames';
        exportBtn.style.marginRight = '10px';
        exportBtn.addEventListener('click', async () => {
            const keys = await GM_listValues();
            const data = await Promise.all(keys.map(async k => `${k}|${await GM_getValue(k)}`));
            const blob = new Blob([data.join('\n')], { type: 'text/plain' });
            const url = URL.createObjectURL(blob);

            const a = document.createElement('a');
            a.href = url;
            a.download = 'rss_nicknames.txt';
            a.click();

            URL.revokeObjectURL(url);
        });

        const importBtn = document.createElement('button');
        importBtn.textContent = 'Import Nicknames';
        importBtn.addEventListener('click', () => {
            const input = document.createElement('input');
            input.type = 'file';
            input.accept = '.txt';

            input.addEventListener('change', async () => {
                const file = input.files[0];
                if (!file) return;

                const text = await file.text();
                const lines = text.split('\n');
                for (const line of lines) {
                    const [key, value] = line.split('|');
                    if (key && value) {
                        await GM_setValue(key.trim(), value.trim());
                    }
                }

                alert('Nicknames imported! Refreshing the page...');
                location.reload();
            });

            input.click();
        });

        controlDiv.appendChild(exportBtn);
        controlDiv.appendChild(importBtn);
        container.appendChild(controlDiv);
    });
})();