LINUX SB 快照站

这样我就知道哪个帖子我看过了,分享个插件

原帖: linux.sb/topic/12840 · 共 11 楼 · 标题快照 2026-08-15 18:27:04

楼主
发帖 2026-08-15 18:22:54 · 快照 2026-08-15 18:27:04

截图

// ==UserScript==
// @name         Linux SB 已读帖子灰显
// @namespace    https://linux.sb/
// @version      1.0.0
// @description  将看过的 Linux SB 帖子标题灰显;已读记录 60 天后自动清理。
// @author       Cindy
// @match        https://linux.sb/*
// @grant        GM_registerMenuCommand
// @run-at       document-start
// ==/UserScript==

(() => {
  'use strict';

  const STORAGE_KEY = 'linuxSbReadTopicsV1';
  const RETENTION_DAYS = 60;
  const MAX_ENTRIES = 3000;
  const CLEANUP_INTERVAL_MS = 24 * 60 * 60 * 1000;
  const TOPIC_PATH = /^\/topic\/(\d+)(?:\/|$)/;

  function readStore() {
    try {
      const stored = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
      return stored && typeof stored === 'object' ? stored : {};
    } catch {
      return {};
    }
  }

  function writeStore(store) {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(store));
  }

  function topicKey(url = location.href) {
    const { pathname } = new URL(url, location.origin);
    const match = pathname.match(TOPIC_PATH);
    return match ? `/topic/${match[1]}` : null;
  }

  function prune(store, now = Date.now()) {
    const expiresAt = now - RETENTION_DAYS * 24 * 60 * 60 * 1000;
    const entries = Object.entries(store)
      .filter(([key, timestamp]) => TOPIC_PATH.test(key) && Number.isFinite(timestamp) && timestamp >= expiresAt)
      .sort(([, left], [, right]) => right - left)
      .slice(0, MAX_ENTRIES);

    return Object.fromEntries(entries);
  }

  function markCurrentTopicRead() {
    const key = topicKey();
    if (!key) return;

    const store = readStore();
    store[key] = Date.now();
    writeStore(prune(store));
  }

  function installStyle() {
    const style = document.createElement('style');
    style.id = 'linux-sb-read-marker-style';
    style.textContent = `
      .post-title.linux-sb-read-marker {
        color: #9ca3af !important;
        opacity: 0.72;
      }
      .post-title.linux-sb-read-marker:hover {
        color: #6b7280 !important;
        opacity: 1;
      }
    `;
    document.documentElement.append(style);
  }

  function renderReadTopics() {
    const store = prune(readStore());
    writeStore(store);

    for (const link of document.querySelectorAll('a.post-title[href]')) {
      const key = topicKey(link.href);
      link.classList.toggle('linux-sb-read-marker', Boolean(key && store[key]));
    }
  }

  function resetReadTopics() {
    localStorage.removeItem(STORAGE_KEY);
    renderReadTopics();
  }

  function start() {
    markCurrentTopicRead();
    installStyle();
    renderReadTopics();

    const observer = new MutationObserver(renderReadTopics);
    observer.observe(document.body, { childList: true, subtree: true });
    window.setInterval(renderReadTopics, CLEANUP_INTERVAL_MS);
  }

  if (typeof GM_registerMenuCommand === 'function') {
    GM_registerMenuCommand('清空 Linux SB 已读记录', resetReadTopics);
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', start, { once: true });
  } else {
    start();
  }
})();

虽然写一下很简单,给大家省点token

#1
发帖 2026-08-15 18:30:19 · 快照 2026-08-15 18:30:55

6,这个真的很实用

#3
发帖 2026-08-15 20:37:45 · 快照 2026-08-15 20:38:10

这个很好呀

#6
发帖 2026-08-15 21:19:38 · 快照 2026-08-15 21:21:05

已实现 看看有什么问题没有