Hide For You (schedule)

Hides the 'For You' tab and auto-switches to 'Following' on X.com during configured time windows

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==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);
})();