mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
refactor: extract overlay broadcast runtime helpers
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
"docs:build": "vitepress build docs",
|
"docs:build": "vitepress build docs",
|
||||||
"docs:preview": "vitepress preview docs --host 0.0.0.0 --port 4173 --strictPort",
|
"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: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/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",
|
"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/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",
|
||||||
"test:subtitle": "pnpm run build && node --test dist/subtitle/stages.test.js dist/subtitle/pipeline.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",
|
"generate:config-example": "pnpm run build && node dist/generate-config-example.js",
|
||||||
"start": "pnpm run build && electron . --start",
|
"start": "pnpm run build && electron . --start",
|
||||||
|
|||||||
58
src/core/services/overlay-broadcast-runtime-service.test.ts
Normal file
58
src/core/services/overlay-broadcast-runtime-service.test.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import test from "node:test";
|
||||||
|
import assert from "node:assert/strict";
|
||||||
|
import {
|
||||||
|
broadcastRuntimeOptionsChangedRuntimeService,
|
||||||
|
broadcastToOverlayWindowsRuntimeService,
|
||||||
|
getOverlayWindowsRuntimeService,
|
||||||
|
setOverlayDebugVisualizationEnabledRuntimeService,
|
||||||
|
} from "./overlay-broadcast-runtime-service";
|
||||||
|
|
||||||
|
test("getOverlayWindowsRuntimeService returns non-destroyed windows only", () => {
|
||||||
|
const alive = { isDestroyed: () => false } as unknown as Electron.BrowserWindow;
|
||||||
|
const dead = { isDestroyed: () => true } as unknown as Electron.BrowserWindow;
|
||||||
|
const windows = getOverlayWindowsRuntimeService({
|
||||||
|
mainWindow: alive,
|
||||||
|
invisibleWindow: dead,
|
||||||
|
});
|
||||||
|
assert.deepEqual(windows, [alive]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("broadcastToOverlayWindowsRuntimeService sends channel to each window", () => {
|
||||||
|
const calls: unknown[][] = [];
|
||||||
|
const window = {
|
||||||
|
webContents: {
|
||||||
|
send: (...args: unknown[]) => {
|
||||||
|
calls.push(args);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as Electron.BrowserWindow;
|
||||||
|
broadcastToOverlayWindowsRuntimeService([window], "x", 1, "a");
|
||||||
|
assert.deepEqual(calls, [["x", 1, "a"]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("runtime-option and debug broadcasts use expected channels", () => {
|
||||||
|
const broadcasts: unknown[][] = [];
|
||||||
|
broadcastRuntimeOptionsChangedRuntimeService(
|
||||||
|
() => [],
|
||||||
|
(channel, ...args) => {
|
||||||
|
broadcasts.push([channel, ...args]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let state = false;
|
||||||
|
const changed = setOverlayDebugVisualizationEnabledRuntimeService(
|
||||||
|
state,
|
||||||
|
true,
|
||||||
|
(enabled) => {
|
||||||
|
state = enabled;
|
||||||
|
},
|
||||||
|
(channel, ...args) => {
|
||||||
|
broadcasts.push([channel, ...args]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
assert.equal(changed, true);
|
||||||
|
assert.equal(state, true);
|
||||||
|
assert.deepEqual(broadcasts, [
|
||||||
|
["runtime-options:changed", []],
|
||||||
|
["overlay-debug-visualization:set", true],
|
||||||
|
]);
|
||||||
|
});
|
||||||
45
src/core/services/overlay-broadcast-runtime-service.ts
Normal file
45
src/core/services/overlay-broadcast-runtime-service.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { BrowserWindow } from "electron";
|
||||||
|
import { RuntimeOptionState } from "../../types";
|
||||||
|
|
||||||
|
export function getOverlayWindowsRuntimeService(options: {
|
||||||
|
mainWindow: BrowserWindow | null;
|
||||||
|
invisibleWindow: BrowserWindow | null;
|
||||||
|
}): BrowserWindow[] {
|
||||||
|
const windows: BrowserWindow[] = [];
|
||||||
|
if (options.mainWindow && !options.mainWindow.isDestroyed()) {
|
||||||
|
windows.push(options.mainWindow);
|
||||||
|
}
|
||||||
|
if (options.invisibleWindow && !options.invisibleWindow.isDestroyed()) {
|
||||||
|
windows.push(options.invisibleWindow);
|
||||||
|
}
|
||||||
|
return windows;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function broadcastToOverlayWindowsRuntimeService(
|
||||||
|
windows: BrowserWindow[],
|
||||||
|
channel: string,
|
||||||
|
...args: unknown[]
|
||||||
|
): void {
|
||||||
|
for (const window of windows) {
|
||||||
|
window.webContents.send(channel, ...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function broadcastRuntimeOptionsChangedRuntimeService(
|
||||||
|
getRuntimeOptionsState: () => RuntimeOptionState[],
|
||||||
|
broadcastToOverlayWindows: (channel: string, ...args: unknown[]) => void,
|
||||||
|
): void {
|
||||||
|
broadcastToOverlayWindows("runtime-options:changed", getRuntimeOptionsState());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setOverlayDebugVisualizationEnabledRuntimeService(
|
||||||
|
currentEnabled: boolean,
|
||||||
|
nextEnabled: boolean,
|
||||||
|
setState: (enabled: boolean) => void,
|
||||||
|
broadcastToOverlayWindows: (channel: string, ...args: unknown[]) => void,
|
||||||
|
): boolean {
|
||||||
|
if (currentEnabled === nextEnabled) return false;
|
||||||
|
setState(nextEnabled);
|
||||||
|
broadcastToOverlayWindows("overlay-debug-visualization:set", nextEnabled);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
37
src/main.ts
37
src/main.ts
@@ -195,6 +195,12 @@ import {
|
|||||||
createFieldGroupingCallbackRuntimeService,
|
createFieldGroupingCallbackRuntimeService,
|
||||||
sendToVisibleOverlayRuntimeService,
|
sendToVisibleOverlayRuntimeService,
|
||||||
} from "./core/services/overlay-bridge-runtime-service";
|
} from "./core/services/overlay-bridge-runtime-service";
|
||||||
|
import {
|
||||||
|
broadcastRuntimeOptionsChangedRuntimeService,
|
||||||
|
broadcastToOverlayWindowsRuntimeService,
|
||||||
|
getOverlayWindowsRuntimeService,
|
||||||
|
setOverlayDebugVisualizationEnabledRuntimeService,
|
||||||
|
} from "./core/services/overlay-broadcast-runtime-service";
|
||||||
import {
|
import {
|
||||||
runSubsyncManualFromIpcRuntimeService,
|
runSubsyncManualFromIpcRuntimeService,
|
||||||
triggerSubsyncFromConfigRuntimeService,
|
triggerSubsyncFromConfigRuntimeService,
|
||||||
@@ -305,25 +311,30 @@ const SUBTITLE_POSITIONS_DIR = path.join(CONFIG_DIR, "subtitle-positions");
|
|||||||
function getRuntimeOptionsState(): RuntimeOptionState[] { if (!runtimeOptionsManager) return []; return runtimeOptionsManager.listOptions(); }
|
function getRuntimeOptionsState(): RuntimeOptionState[] { if (!runtimeOptionsManager) return []; return runtimeOptionsManager.listOptions(); }
|
||||||
|
|
||||||
function getOverlayWindows(): BrowserWindow[] {
|
function getOverlayWindows(): BrowserWindow[] {
|
||||||
const windows: BrowserWindow[] = [];
|
return getOverlayWindowsRuntimeService({ mainWindow, invisibleWindow });
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
|
||||||
windows.push(mainWindow);
|
|
||||||
}
|
|
||||||
if (invisibleWindow && !invisibleWindow.isDestroyed()) {
|
|
||||||
windows.push(invisibleWindow);
|
|
||||||
}
|
|
||||||
return windows;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function broadcastToOverlayWindows(channel: string, ...args: unknown[]): void {
|
function broadcastToOverlayWindows(channel: string, ...args: unknown[]): void {
|
||||||
for (const window of getOverlayWindows()) {
|
broadcastToOverlayWindowsRuntimeService(getOverlayWindows(), channel, ...args);
|
||||||
window.webContents.send(channel, ...args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function broadcastRuntimeOptionsChanged(): void { broadcastToOverlayWindows("runtime-options:changed", getRuntimeOptionsState()); }
|
function broadcastRuntimeOptionsChanged(): void {
|
||||||
|
broadcastRuntimeOptionsChangedRuntimeService(
|
||||||
|
() => getRuntimeOptionsState(),
|
||||||
|
(channel, ...args) => broadcastToOverlayWindows(channel, ...args),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function setOverlayDebugVisualizationEnabled(enabled: boolean): void { if (overlayDebugVisualizationEnabled === enabled) return; overlayDebugVisualizationEnabled = enabled; broadcastToOverlayWindows("overlay-debug-visualization:set", overlayDebugVisualizationEnabled); }
|
function setOverlayDebugVisualizationEnabled(enabled: boolean): void {
|
||||||
|
setOverlayDebugVisualizationEnabledRuntimeService(
|
||||||
|
overlayDebugVisualizationEnabled,
|
||||||
|
enabled,
|
||||||
|
(next) => {
|
||||||
|
overlayDebugVisualizationEnabled = next;
|
||||||
|
},
|
||||||
|
(channel, ...args) => broadcastToOverlayWindows(channel, ...args),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function openRuntimeOptionsPalette(): void { sendToVisibleOverlay("runtime-options:open", undefined, { restoreOnModalClose: "runtime-options" }); }
|
function openRuntimeOptionsPalette(): void { sendToVisibleOverlay("runtime-options:open", undefined, { restoreOnModalClose: "runtime-options" }); }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user