JavDB Watched Marker

自动标记看过的影片

Versione datata 02/02/2025. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         JavDB Watched Marker
// @version      1.0
// @namespace    https://gist.github.com/sqzw-x
// @description  自动标记看过的影片
// @match        https://javdb.com/*
// @grant        GM_registerMenuCommand
// @grant        GM_addElement
// @license MIT
// ==/UserScript==

"use strict";

const get_localStorage = (key) => JSON.parse(localStorage.getItem(key));
const set_localStorage = (key, value) =>
  localStorage.setItem(key, JSON.stringify(value));

const URL_SET_KEY = "javdb-watched-url-set";
const NUM_SET_KEY = "javdb-watched-num-set";

let watchedURLSet = new Set(get_localStorage(URL_SET_KEY));
let watchedNumSet = new Set(get_localStorage(NUM_SET_KEY));

// 创建隐藏的文件输入框
const fileInput = GM_addElement(document.body, "input", {
  type: "file",
  accept: ".json",
  style: "display: none",
});

fileInput.addEventListener("change", handleFileSelect);

// 注册油猴菜单
GM_registerMenuCommand("导入看过列表", () => fileInput.click());

// 处理文件导入
function handleFileSelect(event) {
  const file = event.target.files[0];
  if (!file) return;

  const reader = new FileReader();
  reader.onload = (e) => {
    try {
      const r = JSON.parse(e.target.result);
      // r is an array of objects
      // each object has a url property and a number property
      // add each url to watchedURLSet and each num to watchedNumSet
      r.forEach((item) => {
        watchedURLSet.add(item.url);
        watchedNumSet.add(item.number);
      });
      set_localStorage(URL_SET_KEY, Array.from(watchedURLSet));
      set_localStorage(NUM_SET_KEY, Array.from(watchedNumSet));
    } catch (error) {
      console.error("解析文件失败:", error);
      alert("无法解析文件,请确保是有效的JSON格式");
    }
  };
  reader.readAsText(file);
}

// 标记已看过的视频
function markWatchedVideos() {
  const videos = document.querySelectorAll(".item");

  const watched = (v) => {
    const link = v.querySelector("a");
    if (link) {
      const url = link.getAttribute("href")?.replace("/v/", "");
      return url && watchedURLSet.has(url) ? "看过" : null;
    }
    const num = v.querySelector(".video-title strong").textContent;
    return num && watchedNumSet.has(num) ? "可能看过" : null;
  };

  videos.forEach((v) => {
    const t = watched(v);
    if (t) {
      const marker = document.createElement("span");
      marker.className = "review";
      marker.textContent = t;
      v.querySelector(".cover").appendChild(marker);
    }
  });
}

// 初始化
function init() {
  markWatchedVideos();
}

init();