From 469091a2a829f8357f3e3508afa49d9b8e638ea4 Mon Sep 17 00:00:00 2001 From: sudacode Date: Mon, 9 Feb 2026 22:39:51 -0800 Subject: [PATCH] refactor: extract secondary subtitle mode runtime service --- .../services/secondary-subtitle-service.ts | 32 +++++++++++++++++++ src/main.ts | 26 ++++++++------- 2 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 src/core/services/secondary-subtitle-service.ts diff --git a/src/core/services/secondary-subtitle-service.ts b/src/core/services/secondary-subtitle-service.ts new file mode 100644 index 0000000..561e71b --- /dev/null +++ b/src/core/services/secondary-subtitle-service.ts @@ -0,0 +1,32 @@ +import { SecondarySubMode } from "../../types"; + +export interface CycleSecondarySubModeDeps { + getSecondarySubMode: () => SecondarySubMode; + setSecondarySubMode: (mode: SecondarySubMode) => void; + getLastSecondarySubToggleAtMs: () => number; + setLastSecondarySubToggleAtMs: (timestampMs: number) => void; + broadcastSecondarySubMode: (mode: SecondarySubMode) => void; + showMpvOsd: (text: string) => void; + now?: () => number; +} + +const SECONDARY_SUB_CYCLE: SecondarySubMode[] = ["hidden", "visible", "hover"]; +const SECONDARY_SUB_TOGGLE_DEBOUNCE_MS = 120; + +export function cycleSecondarySubModeService( + deps: CycleSecondarySubModeDeps, +): void { + const now = deps.now ? deps.now() : Date.now(); + if (now - deps.getLastSecondarySubToggleAtMs() < SECONDARY_SUB_TOGGLE_DEBOUNCE_MS) { + return; + } + deps.setLastSecondarySubToggleAtMs(now); + + const currentMode = deps.getSecondarySubMode(); + const currentIndex = SECONDARY_SUB_CYCLE.indexOf(currentMode); + const nextMode = + SECONDARY_SUB_CYCLE[(currentIndex + 1) % SECONDARY_SUB_CYCLE.length]; + deps.setSecondarySubMode(nextMode); + deps.broadcastSecondarySubMode(nextMode); + deps.showMpvOsd(`Secondary subtitle: ${nextMode}`); +} diff --git a/src/main.ts b/src/main.ts index b5bec02..9fb8c24 100644 --- a/src/main.ts +++ b/src/main.ts @@ -117,6 +117,7 @@ import { runOverlayShortcutLocalFallback } from "./core/services/overlay-shortcu import { createOverlayShortcutRuntimeHandlers } from "./core/services/overlay-shortcut-runtime-service"; import { createNumericShortcutSessionService } from "./core/services/numeric-shortcut-session-service"; import { handleCliCommandService } from "./core/services/cli-command-service"; +import { cycleSecondarySubModeService } from "./core/services/secondary-subtitle-service"; import { showDesktopNotification } from "./core/utils/notification"; import { openYomitanSettingsWindow } from "./core/services/yomitan-settings-service"; import { tokenizeSubtitleService } from "./core/services/tokenizer-service"; @@ -845,17 +846,20 @@ function tryHandleOverlayShortcutLocalFallback(input: Electron.Input): boolean { } function cycleSecondarySubMode(): void { - const now = Date.now(); - if (now - lastSecondarySubToggleAtMs < 120) { - return; - } - lastSecondarySubToggleAtMs = now; - - const cycle: SecondarySubMode[] = ["hidden", "visible", "hover"]; - const idx = cycle.indexOf(secondarySubMode); - secondarySubMode = cycle[(idx + 1) % cycle.length]; - broadcastToOverlayWindows("secondary-subtitle:mode", secondarySubMode); - showMpvOsd(`Secondary subtitle: ${secondarySubMode}`); + cycleSecondarySubModeService({ + getSecondarySubMode: () => secondarySubMode, + setSecondarySubMode: (mode) => { + secondarySubMode = mode; + }, + getLastSecondarySubToggleAtMs: () => lastSecondarySubToggleAtMs, + setLastSecondarySubToggleAtMs: (timestampMs) => { + lastSecondarySubToggleAtMs = timestampMs; + }, + broadcastSecondarySubMode: (mode) => { + broadcastToOverlayWindows("secondary-subtitle:mode", mode); + }, + showMpvOsd: (text) => showMpvOsd(text), + }); } function showMpvOsd(text: string): void {