Mastodon Threads Ultimate (Home Fix)

修正域名跳转问题。自适应 threads.com 或 threads.net。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Mastodon Threads Ultimate (Home Fix)
// @namespace    http://tampermonkey.net/
// @version      1.29.1
// @description  修正域名跳转问题。自适应 threads.com 或 threads.net。
// @author       Gemini
// @match        *://*/*
// @grant        none
// @run-at       document-start
// ==/UserScript==
// @license MIT
(function() {
    'use strict';

    const currentHost = window.location.hostname;
    const currentPath = window.location.pathname;

    // --- 核心跳转逻辑:动态获取当前域名 ---
    function handleFollow(handle) {
        let finalID = handle.trim();
        if (!finalID.startsWith('@')) finalID = `@${finalID}`;
        navigator.clipboard.writeText(finalID);

        // 动态识别当前在用的是 .com 还是 .net
        // 如果是在 Mastodon 触发,默认跳转到 threads.net(或你可以改成 threads.com)
        // 这里我们优先尝试 threads.com,因为你提到家中用的是这个
        const targetHost = "www.threads.com";
        window.open(`https://${targetHost}/fediverse_profile/${finalID}`, '_blank');
    }

    // --- 逻辑 A:Threads 端逻辑 ---
    if (currentHost.includes('threads.net') || currentHost.includes('threads.com')) {
        if (currentPath.includes('fediverse_profile')) {
            const targetHandle = currentPath.split('/').pop();
            const check = () => {
                if (document.body && (document.body.innerText.includes("迷路者") || document.body.innerText.includes("丢失"))) {
                    // 跳转时保持当前域名
                    window.location.replace(`https://${currentHost}/search?auto_activate=${encodeURIComponent(targetHandle)}`);
                }
            };
            setInterval(check, 1000);
        }
        if (currentPath.includes('/search')) {
            const urlParams = new URLSearchParams(window.location.search);
            const activateTarget = urlParams.get('auto_activate');
            if (activateTarget) {
                window.onload = async () => {
                    let input = null;
                    for(let i=0; i<30; i++) {
                        input = document.querySelector('input[placeholder*="搜索"], input[aria-label*="搜索"]');
                        if(input) break;
                        await new Promise(r => setTimeout(r, 400));
                    }
                    if(input) {
                        input.focus();
                        const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
                        setter.call(input, activateTarget);
                        input.dispatchEvent(new Event('input', { bubbles: true }));
                        setInterval(() => {
                            const items = document.querySelectorAll('div[role="link"], div[tabindex="0"]');
                            items.forEach(item => {
                                if(item.innerText.includes(activateTarget)) {
                                    item.click();
                                    // 激活成功后跳转回个人主页,保持当前域名
                                    setTimeout(() => { window.location.href = `https://${currentHost}/fediverse_profile/${activateTarget}`; }, 6000);
                                }
                            });
                        }, 1000);
                    }
                };
            }
        }
        return;
    }

    // --- 逻辑 B:Mastodon 端逻辑 (1.29 版原封不动) ---
    function inject() {
        const isProfilePage = currentPath.startsWith('/@') && !['/@home','/@notifications','/@explore'].some(p => currentPath.includes(p));
        if (isProfilePage) {
            const profileHeader = document.querySelector('.account__header__tabs__name h1 small');
            if (profileHeader && !document.getElementById('threads-hero-inline-btn')) {
                let user = currentPath.split('/')[1].replace('@', '');
                if (!user.includes('@')) user = `${user}@${currentHost}`;
                const heroBtn = document.createElement('span');
                heroBtn.id = 'threads-hero-inline-btn';
                heroBtn.innerHTML = 'Threads 关注';
                heroBtn.style = "cursor:pointer; background:#000; color:#fff !important; padding:2px 8px; border-radius:4px; font-size:13px; font-weight:600; margin-left:8px; display:inline-block; vertical-align:middle; border:1px solid #444; line-height:1.4;";
                heroBtn.onclick = (e) => { e.preventDefault(); e.stopPropagation(); handleFollow(user); };
                profileHeader.appendChild(heroBtn);
            }
        }
        const accounts = document.querySelectorAll('.status__display-name .display-name__account, .account__display-name small');
        accounts.forEach(acc => {
            if (acc.closest('.account__header__tabs__name') || acc.querySelector('.threads-mini-btn')) return;
            let h = acc.innerText.trim().replace('@', '');
            if (!h || !h.includes('@')) h = `${h}@${currentHost}`;
            const mini = document.createElement('span');
            mini.className = 'threads-mini-btn';
            mini.innerHTML = ' Threads 关注';
            mini.style = "cursor:pointer; font-size:10px; background:#000; color:#fff !important; padding:2px 5px; border-radius:4px; margin-left:5px; vertical-align:middle; opacity:0.8;";
            mini.onclick = (e) => { e.preventDefault(); e.stopPropagation(); handleFollow(h); };
            acc.appendChild(mini);
        });
    }
    setInterval(inject, 1500);
})();