mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
refactor: extract app shutdown orchestration service
This commit is contained in:
32
src/core/services/app-shutdown-runtime-service.test.ts
Normal file
32
src/core/services/app-shutdown-runtime-service.test.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { runAppShutdownRuntimeService } from "./app-shutdown-runtime-service";
|
||||
|
||||
test("runAppShutdownRuntimeService runs teardown steps in order", () => {
|
||||
const calls: string[] = [];
|
||||
runAppShutdownRuntimeService({
|
||||
unregisterAllGlobalShortcuts: () => calls.push("unregisterAllGlobalShortcuts"),
|
||||
stopSubtitleWebsocket: () => calls.push("stopSubtitleWebsocket"),
|
||||
stopTexthookerService: () => calls.push("stopTexthookerService"),
|
||||
destroyYomitanParserWindow: () => calls.push("destroyYomitanParserWindow"),
|
||||
clearYomitanParserPromises: () => calls.push("clearYomitanParserPromises"),
|
||||
stopWindowTracker: () => calls.push("stopWindowTracker"),
|
||||
destroyMpvSocket: () => calls.push("destroyMpvSocket"),
|
||||
clearReconnectTimer: () => calls.push("clearReconnectTimer"),
|
||||
destroySubtitleTimingTracker: () => calls.push("destroySubtitleTimingTracker"),
|
||||
destroyAnkiIntegration: () => calls.push("destroyAnkiIntegration"),
|
||||
});
|
||||
|
||||
assert.deepEqual(calls, [
|
||||
"unregisterAllGlobalShortcuts",
|
||||
"stopSubtitleWebsocket",
|
||||
"stopTexthookerService",
|
||||
"destroyYomitanParserWindow",
|
||||
"clearYomitanParserPromises",
|
||||
"stopWindowTracker",
|
||||
"destroyMpvSocket",
|
||||
"clearReconnectTimer",
|
||||
"destroySubtitleTimingTracker",
|
||||
"destroyAnkiIntegration",
|
||||
]);
|
||||
});
|
||||
27
src/core/services/app-shutdown-runtime-service.ts
Normal file
27
src/core/services/app-shutdown-runtime-service.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
export interface AppShutdownRuntimeDeps {
|
||||
unregisterAllGlobalShortcuts: () => void;
|
||||
stopSubtitleWebsocket: () => void;
|
||||
stopTexthookerService: () => void;
|
||||
destroyYomitanParserWindow: () => void;
|
||||
clearYomitanParserPromises: () => void;
|
||||
stopWindowTracker: () => void;
|
||||
destroyMpvSocket: () => void;
|
||||
clearReconnectTimer: () => void;
|
||||
destroySubtitleTimingTracker: () => void;
|
||||
destroyAnkiIntegration: () => void;
|
||||
}
|
||||
|
||||
export function runAppShutdownRuntimeService(
|
||||
deps: AppShutdownRuntimeDeps,
|
||||
): void {
|
||||
deps.unregisterAllGlobalShortcuts();
|
||||
deps.stopSubtitleWebsocket();
|
||||
deps.stopTexthookerService();
|
||||
deps.destroyYomitanParserWindow();
|
||||
deps.clearYomitanParserPromises();
|
||||
deps.stopWindowTracker();
|
||||
deps.destroyMpvSocket();
|
||||
deps.clearReconnectTimer();
|
||||
deps.destroySubtitleTimingTracker();
|
||||
deps.destroyAnkiIntegration();
|
||||
}
|
||||
71
src/main.ts
71
src/main.ts
@@ -202,6 +202,7 @@ import {
|
||||
setOverlayDebugVisualizationEnabledRuntimeService,
|
||||
} from "./core/services/overlay-broadcast-runtime-service";
|
||||
import { runAppReadyRuntimeService } from "./core/services/app-ready-runtime-service";
|
||||
import { runAppShutdownRuntimeService } from "./core/services/app-shutdown-runtime-service";
|
||||
import {
|
||||
runSubsyncManualFromIpcRuntimeService,
|
||||
triggerSubsyncFromConfigRuntimeService,
|
||||
@@ -564,30 +565,52 @@ if (initialArgs.generateConfig && !shouldStartApp(initialArgs)) {
|
||||
});
|
||||
},
|
||||
onWillQuitCleanup: () => {
|
||||
globalShortcut.unregisterAll();
|
||||
subtitleWsService.stop();
|
||||
texthookerService.stop();
|
||||
if (yomitanParserWindow && !yomitanParserWindow.isDestroyed()) {
|
||||
yomitanParserWindow.destroy();
|
||||
}
|
||||
yomitanParserWindow = null;
|
||||
yomitanParserReadyPromise = null;
|
||||
yomitanParserInitPromise = null;
|
||||
if (windowTracker) {
|
||||
windowTracker.stop();
|
||||
}
|
||||
if (mpvClient && mpvClient.socket) {
|
||||
mpvClient.socket.destroy();
|
||||
}
|
||||
if (reconnectTimer) {
|
||||
clearTimeout(reconnectTimer);
|
||||
}
|
||||
if (subtitleTimingTracker) {
|
||||
subtitleTimingTracker.destroy();
|
||||
}
|
||||
if (ankiIntegration) {
|
||||
ankiIntegration.destroy();
|
||||
}
|
||||
runAppShutdownRuntimeService({
|
||||
unregisterAllGlobalShortcuts: () => {
|
||||
globalShortcut.unregisterAll();
|
||||
},
|
||||
stopSubtitleWebsocket: () => {
|
||||
subtitleWsService.stop();
|
||||
},
|
||||
stopTexthookerService: () => {
|
||||
texthookerService.stop();
|
||||
},
|
||||
destroyYomitanParserWindow: () => {
|
||||
if (yomitanParserWindow && !yomitanParserWindow.isDestroyed()) {
|
||||
yomitanParserWindow.destroy();
|
||||
}
|
||||
yomitanParserWindow = null;
|
||||
},
|
||||
clearYomitanParserPromises: () => {
|
||||
yomitanParserReadyPromise = null;
|
||||
yomitanParserInitPromise = null;
|
||||
},
|
||||
stopWindowTracker: () => {
|
||||
if (windowTracker) {
|
||||
windowTracker.stop();
|
||||
}
|
||||
},
|
||||
destroyMpvSocket: () => {
|
||||
if (mpvClient && mpvClient.socket) {
|
||||
mpvClient.socket.destroy();
|
||||
}
|
||||
},
|
||||
clearReconnectTimer: () => {
|
||||
if (reconnectTimer) {
|
||||
clearTimeout(reconnectTimer);
|
||||
}
|
||||
},
|
||||
destroySubtitleTimingTracker: () => {
|
||||
if (subtitleTimingTracker) {
|
||||
subtitleTimingTracker.destroy();
|
||||
}
|
||||
},
|
||||
destroyAnkiIntegration: () => {
|
||||
if (ankiIntegration) {
|
||||
ankiIntegration.destroy();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
shouldRestoreWindowsOnActivate: () =>
|
||||
overlayRuntimeInitialized && BrowserWindow.getAllWindows().length === 0,
|
||||
|
||||
Reference in New Issue
Block a user