您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Hides the 'For You' tab and auto-switches to 'Following' on X.com during configured time windows
// ==UserScript== // @name Hide For You (schedule) // @namespace f_d // @version 1.2 // @description Hides the 'For You' tab and auto-switches to 'Following' on X.com during configured time windows // @author GPT-5 // @match https://x.com/* // @match https://twitter.com/* // @icon https://abs.twimg.com/favicons/twitter.ico // @grant none // ==/UserScript== /*** ────────────────────────────────────────────────────────────── * SCHEDULE CONFIG * * Time is local browser time, 24h "HH:MM". * Days: 0=Sun, 1=Mon, ..., 6=Sat * The filter is ACTIVE if the current time falls into ANY range * listed for the current day. "default" applies when a day has no * explicit entry. Overnight ranges are supported (e.g. 22:00–03:00). * * My Settings: * - Mon–Fri: block active all day * - Sat & Sun: active until 16:00 * ───────────────────────────────────────────────────────────────*/ const SCHEDULE = { // Sunday 0: [{ start: "00:00", end: "16:00" }], // Monday–Friday 1: [{ start: "00:00", end: "24:00" }], 2: [{ start: "00:00", end: "24:00" }], 3: [{ start: "00:00", end: "24:00" }], 4: [{ start: "00:00", end: "24:00" }], 5: [{ start: "00:00", end: "24:00" }], // Saturday 6: [{ start: "00:00", end: "16:00" }], // Fallback if a day is not listed default: [{ start: "00:00", end: "24:00" }], }; /*** ─────────────────────────────────────────────────────────── ***/ (function () { 'use strict'; // Match both English and German labels, fall back to exact text match const LABELS_FOR_YOU = new Set(["For you", "Für dich"]); const LABELS_FOLLOWING = new Set(["Following", "Folge ich"]); const HIDDEN_ATTR = "data-hidden-by-userscript-for-you"; function timeToMinutes(t) { const [h, m] = t.split(":").map(Number); return h * 60 + (m || 0); } function inRange(nowMin, startMin, endMin) { // Handles normal and overnight (wrap-around) ranges if (startMin === endMin) return false; // empty range if (startMin < endMin) return nowMin >= startMin && nowMin < endMin; return nowMin >= startMin || nowMin < endMin; } function isFeatureActiveNow() { const now = new Date(); const day = now.getDay(); // 0..6 const minutes = now.getHours() * 60 + now.getMinutes(); const ranges = SCHEDULE.hasOwnProperty(day) ? SCHEDULE[day] : SCHEDULE.default; if (!ranges || ranges.length === 0) return false; return ranges.some(({ start, end }) => inRange(minutes, timeToMinutes(start), timeToMinutes(end))); } function getTabs() { const tabs = Array.from(document.querySelectorAll('[role="tab"]')); let forYouTab = null, followingTab = null; tabs.forEach(tab => { const text = (tab.textContent || "").trim(); if (LABELS_FOR_YOU.has(text)) forYouTab = tab; if (LABELS_FOLLOWING.has(text)) followingTab = tab; }); return { forYouTab, followingTab }; } function hideForYouAndSwitch() { const { forYouTab, followingTab } = getTabs(); if (!forYouTab) return; // Hide the "For you" tab if (forYouTab.style.display !== "none") { forYouTab.style.display = "none"; forYouTab.setAttribute(HIDDEN_ATTR, "true"); } // If "For you" was active, switch to "Following" if (forYouTab.getAttribute('aria-selected') === 'true' && followingTab) { // Some builds require a mouse event to trigger navigation properly followingTab.click(); } } function unhideForYou() { const { forYouTab } = getTabs(); if (!forYouTab) return; if (forYouTab.getAttribute(HIDDEN_ATTR) === "true") { forYouTab.style.display = ""; forYouTab.removeAttribute(HIDDEN_ATTR); } } function applyBehavior() { if (isFeatureActiveNow()) { hideForYouAndSwitch(); } else { unhideForYou(); } } // Run immediately applyBehavior(); // Observe DOM changes (tabs re-render frequently) const observer = new MutationObserver(() => applyBehavior()); observer.observe(document.body, { childList: true, subtree: true }); // Re-check schedule every minute in case the hour changes without DOM mutations const intervalId = setInterval(applyBehavior, 60 * 1000); // Cleanup on unload window.addEventListener('unload', () => { observer.disconnect(); clearInterval(intervalId); }, false); })();