From 444873c803fdd424e80d17d97839b7eccfcf8636 Mon Sep 17 00:00:00 2001 From: sudacode Date: Tue, 10 Feb 2026 01:17:34 -0800 Subject: [PATCH] refactor: extract overlay visibility facade deps runtime service --- package.json | 2 +- ...bility-facade-deps-runtime-service.test.ts | 46 +++++++++++++++ ...-visibility-facade-deps-runtime-service.ts | 35 ++++++++++++ src/main.ts | 56 ++++++++++--------- 4 files changed, 111 insertions(+), 28 deletions(-) create mode 100644 src/core/services/overlay-visibility-facade-deps-runtime-service.test.ts create mode 100644 src/core/services/overlay-visibility-facade-deps-runtime-service.ts diff --git a/package.json b/package.json index e01d924..b94c7cd 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "docs:build": "vitepress build docs", "docs:preview": "vitepress preview docs --host 0.0.0.0 --port 4173 --strictPort", "test:config": "pnpm run build && node --test dist/config/config.test.js", - "test:core": "pnpm run build && node --test dist/cli/args.test.js dist/cli/help.test.js dist/core/services/cli-command-service.test.js dist/core/services/cli-command-deps-runtime-service.test.js dist/core/services/ipc-deps-runtime-service.test.js dist/core/services/anki-jimaku-ipc-deps-runtime-service.test.js dist/core/services/field-grouping-overlay-runtime-service.test.js dist/core/services/subsync-deps-runtime-service.test.js dist/core/services/numeric-shortcut-runtime-service.test.js dist/core/services/numeric-shortcut-session-service.test.js dist/core/services/secondary-subtitle-service.test.js dist/core/services/mpv-render-metrics-service.test.js dist/core/services/mpv-runtime-service.test.js dist/core/services/runtime-options-runtime-service.test.js dist/core/services/overlay-modal-restore-service.test.js dist/core/services/runtime-config-service.test.js dist/core/services/overlay-bridge-runtime-service.test.js dist/core/services/overlay-visibility-facade-service.test.js dist/core/services/overlay-broadcast-runtime-service.test.js dist/core/services/app-ready-runtime-service.test.js dist/core/services/app-shutdown-runtime-service.test.js dist/core/services/mpv-client-deps-runtime-service.test.js dist/core/services/app-lifecycle-deps-runtime-service.test.js dist/core/services/runtime-options-manager-runtime-service.test.js dist/core/services/config-warning-runtime-service.test.js dist/core/services/app-logging-runtime-service.test.js dist/core/services/startup-resource-runtime-service.test.js dist/core/services/config-generation-runtime-service.test.js", + "test:core": "pnpm run build && node --test dist/cli/args.test.js dist/cli/help.test.js dist/core/services/cli-command-service.test.js dist/core/services/cli-command-deps-runtime-service.test.js dist/core/services/ipc-deps-runtime-service.test.js dist/core/services/anki-jimaku-ipc-deps-runtime-service.test.js dist/core/services/field-grouping-overlay-runtime-service.test.js dist/core/services/subsync-deps-runtime-service.test.js dist/core/services/numeric-shortcut-runtime-service.test.js dist/core/services/numeric-shortcut-session-service.test.js dist/core/services/overlay-visibility-facade-deps-runtime-service.test.js dist/core/services/secondary-subtitle-service.test.js dist/core/services/mpv-render-metrics-service.test.js dist/core/services/mpv-runtime-service.test.js dist/core/services/runtime-options-runtime-service.test.js dist/core/services/overlay-modal-restore-service.test.js dist/core/services/runtime-config-service.test.js dist/core/services/overlay-bridge-runtime-service.test.js dist/core/services/overlay-visibility-facade-service.test.js dist/core/services/overlay-broadcast-runtime-service.test.js dist/core/services/app-ready-runtime-service.test.js dist/core/services/app-shutdown-runtime-service.test.js dist/core/services/mpv-client-deps-runtime-service.test.js dist/core/services/app-lifecycle-deps-runtime-service.test.js dist/core/services/runtime-options-manager-runtime-service.test.js dist/core/services/config-warning-runtime-service.test.js dist/core/services/app-logging-runtime-service.test.js dist/core/services/startup-resource-runtime-service.test.js dist/core/services/config-generation-runtime-service.test.js", "test:subtitle": "pnpm run build && node --test dist/subtitle/stages.test.js dist/subtitle/pipeline.test.js", "generate:config-example": "pnpm run build && node dist/generate-config-example.js", "start": "pnpm run build && electron . --start", diff --git a/src/core/services/overlay-visibility-facade-deps-runtime-service.test.ts b/src/core/services/overlay-visibility-facade-deps-runtime-service.test.ts new file mode 100644 index 0000000..78a1d99 --- /dev/null +++ b/src/core/services/overlay-visibility-facade-deps-runtime-service.test.ts @@ -0,0 +1,46 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { createOverlayVisibilityFacadeDepsRuntimeService } from "./overlay-visibility-facade-deps-runtime-service"; + +test("createOverlayVisibilityFacadeDepsRuntimeService returns working deps object", () => { + let visible = false; + let invisible = true; + let mpvSubVisible: boolean | null = null; + let syncCalls = 0; + + const deps = createOverlayVisibilityFacadeDepsRuntimeService({ + getVisibleOverlayVisible: () => visible, + getInvisibleOverlayVisible: () => invisible, + setVisibleOverlayVisibleState: (nextVisible) => { + visible = nextVisible; + }, + setInvisibleOverlayVisibleState: (nextVisible) => { + invisible = nextVisible; + }, + updateVisibleOverlayVisibility: () => {}, + updateInvisibleOverlayVisibility: () => {}, + syncInvisibleOverlayMousePassthrough: () => { + syncCalls += 1; + }, + shouldBindVisibleOverlayToMpvSubVisibility: () => true, + isMpvConnected: () => true, + setMpvSubVisibility: (nextVisible) => { + mpvSubVisible = nextVisible; + }, + }); + + assert.equal(deps.getVisibleOverlayVisible(), false); + assert.equal(deps.getInvisibleOverlayVisible(), true); + + deps.setVisibleOverlayVisibleState(true); + deps.setInvisibleOverlayVisibleState(false); + deps.syncInvisibleOverlayMousePassthrough(); + deps.setMpvSubVisibility(false); + + assert.equal(visible, true); + assert.equal(invisible, false); + assert.equal(syncCalls, 1); + assert.equal(mpvSubVisible, false); + assert.equal(deps.shouldBindVisibleOverlayToMpvSubVisibility(), true); + assert.equal(deps.isMpvConnected(), true); +}); diff --git a/src/core/services/overlay-visibility-facade-deps-runtime-service.ts b/src/core/services/overlay-visibility-facade-deps-runtime-service.ts new file mode 100644 index 0000000..e138cfe --- /dev/null +++ b/src/core/services/overlay-visibility-facade-deps-runtime-service.ts @@ -0,0 +1,35 @@ +import { + OverlayVisibilityFacadeDeps, +} from "./overlay-visibility-facade-service"; + +export interface OverlayVisibilityFacadeDepsRuntimeOptions { + getVisibleOverlayVisible: () => boolean; + getInvisibleOverlayVisible: () => boolean; + setVisibleOverlayVisibleState: (nextVisible: boolean) => void; + setInvisibleOverlayVisibleState: (nextVisible: boolean) => void; + updateVisibleOverlayVisibility: () => void; + updateInvisibleOverlayVisibility: () => void; + syncInvisibleOverlayMousePassthrough: () => void; + shouldBindVisibleOverlayToMpvSubVisibility: () => boolean; + isMpvConnected: () => boolean; + setMpvSubVisibility: (mpvSubVisible: boolean) => void; +} + +export function createOverlayVisibilityFacadeDepsRuntimeService( + options: OverlayVisibilityFacadeDepsRuntimeOptions, +): OverlayVisibilityFacadeDeps { + return { + getVisibleOverlayVisible: options.getVisibleOverlayVisible, + getInvisibleOverlayVisible: options.getInvisibleOverlayVisible, + setVisibleOverlayVisibleState: options.setVisibleOverlayVisibleState, + setInvisibleOverlayVisibleState: options.setInvisibleOverlayVisibleState, + updateVisibleOverlayVisibility: options.updateVisibleOverlayVisibility, + updateInvisibleOverlayVisibility: options.updateInvisibleOverlayVisibility, + syncInvisibleOverlayMousePassthrough: + options.syncInvisibleOverlayMousePassthrough, + shouldBindVisibleOverlayToMpvSubVisibility: + options.shouldBindVisibleOverlayToMpvSubVisibility, + isMpvConnected: options.isMpvConnected, + setMpvSubVisibility: options.setMpvSubVisibility, + }; +} diff --git a/src/main.ts b/src/main.ts index 55dcc12..4e69d79 100644 --- a/src/main.ts +++ b/src/main.ts @@ -205,6 +205,7 @@ import { createAnkiJimakuIpcDepsRuntimeService } from "./core/services/anki-jima import { createFieldGroupingOverlayRuntimeService } from "./core/services/field-grouping-overlay-runtime-service"; import { createSubsyncRuntimeDepsService } from "./core/services/subsync-deps-runtime-service"; import { createNumericShortcutRuntimeService } from "./core/services/numeric-shortcut-runtime-service"; +import { createOverlayVisibilityFacadeDepsRuntimeService } from "./core/services/overlay-visibility-facade-deps-runtime-service"; import { createRuntimeOptionsManagerRuntimeService } from "./core/services/runtime-options-manager-runtime-service"; import { createAppLoggingRuntimeService } from "./core/services/app-logging-runtime-service"; import { @@ -967,6 +968,27 @@ const numericShortcutRuntime = createNumericShortcutRuntimeService({ }); const multiCopySession = numericShortcutRuntime.createSession(); const mineSentenceSession = numericShortcutRuntime.createSession(); +const overlayVisibilityFacadeDeps = + createOverlayVisibilityFacadeDepsRuntimeService({ + getVisibleOverlayVisible: () => visibleOverlayVisible, + getInvisibleOverlayVisible: () => invisibleOverlayVisible, + setVisibleOverlayVisibleState: (nextVisible: boolean) => { + visibleOverlayVisible = nextVisible; + }, + setInvisibleOverlayVisibleState: (nextVisible: boolean) => { + invisibleOverlayVisible = nextVisible; + }, + updateVisibleOverlayVisibility: () => updateVisibleOverlayVisibility(), + updateInvisibleOverlayVisibility: () => updateInvisibleOverlayVisibility(), + syncInvisibleOverlayMousePassthrough: () => + syncInvisibleOverlayMousePassthrough(), + shouldBindVisibleOverlayToMpvSubVisibility: () => + shouldBindVisibleOverlayToMpvSubVisibility(), + isMpvConnected: () => Boolean(mpvClient && mpvClient.connected), + setMpvSubVisibility: (mpvSubVisible: boolean) => { + setMpvSubVisibilityRuntimeService(mpvClient, mpvSubVisible); + }, + }); function getSubsyncRuntimeDeps() { return createSubsyncRuntimeDepsService({ @@ -1169,41 +1191,21 @@ function syncInvisibleOverlayMousePassthrough(): void { } function setVisibleOverlayVisible(visible: boolean): void { - setVisibleOverlayVisibleRuntimeFacadeService(visible, getOverlayVisibilityFacadeDeps()); + setVisibleOverlayVisibleRuntimeFacadeService(visible, overlayVisibilityFacadeDeps); } function setInvisibleOverlayVisible(visible: boolean): void { - setInvisibleOverlayVisibleRuntimeFacadeService(visible, getOverlayVisibilityFacadeDeps()); -} - -function getOverlayVisibilityFacadeDeps() { - return { - getVisibleOverlayVisible: () => visibleOverlayVisible, - getInvisibleOverlayVisible: () => invisibleOverlayVisible, - setVisibleOverlayVisibleState: (nextVisible: boolean) => { - visibleOverlayVisible = nextVisible; - }, - setInvisibleOverlayVisibleState: (nextVisible: boolean) => { - invisibleOverlayVisible = nextVisible; - }, - updateVisibleOverlayVisibility: () => updateVisibleOverlayVisibility(), - updateInvisibleOverlayVisibility: () => updateInvisibleOverlayVisibility(), - syncInvisibleOverlayMousePassthrough: () => - syncInvisibleOverlayMousePassthrough(), - shouldBindVisibleOverlayToMpvSubVisibility: () => - shouldBindVisibleOverlayToMpvSubVisibility(), - isMpvConnected: () => Boolean(mpvClient && mpvClient.connected), - setMpvSubVisibility: (mpvSubVisible: boolean) => { - setMpvSubVisibilityRuntimeService(mpvClient, mpvSubVisible); - }, - }; + setInvisibleOverlayVisibleRuntimeFacadeService( + visible, + overlayVisibilityFacadeDeps, + ); } function toggleVisibleOverlay(): void { - toggleVisibleOverlayRuntimeFacadeService(getOverlayVisibilityFacadeDeps()); + toggleVisibleOverlayRuntimeFacadeService(overlayVisibilityFacadeDeps); } function toggleInvisibleOverlay(): void { - toggleInvisibleOverlayRuntimeFacadeService(getOverlayVisibilityFacadeDeps()); + toggleInvisibleOverlayRuntimeFacadeService(overlayVisibilityFacadeDeps); } function setOverlayVisible(visible: boolean): void { setVisibleOverlayVisible(visible); } function toggleOverlay(): void { toggleVisibleOverlay(); }