refactor: extract overlay visibility facade deps runtime service

This commit is contained in:
2026-02-10 01:17:34 -08:00
parent f1cf13b59c
commit 444873c803
4 changed files with 111 additions and 28 deletions

View File

@@ -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);
});

View File

@@ -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,
};
}

View File

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