fix: lazy initialize immersion tracker

This commit is contained in:
2026-02-27 21:20:35 -08:00
parent 1e645f961b
commit 30a76d7767
7 changed files with 108 additions and 63 deletions

View File

@@ -42,11 +42,13 @@ export function composeAppReadyRuntime(options: AppReadyComposerOptions): AppRea
createBuildAppReadyRuntimeMainDepsHandler({
...options.appReadyRuntimeMainDeps,
reloadConfig,
createImmersionTracker: createImmersionTrackerStartupHandler(
createBuildImmersionTrackerStartupMainDepsHandler(
options.immersionTrackerStartupMainDeps,
)(),
),
createImmersionTracker:
options.appReadyRuntimeMainDeps.createImmersionTracker ??
createImmersionTrackerStartupHandler(
createBuildImmersionTrackerStartupMainDepsHandler(
options.immersionTrackerStartupMainDeps,
)(),
),
onCriticalConfigErrors: criticalConfigError,
})(),
);

View File

@@ -75,6 +75,7 @@ test('composeMpvRuntimeHandlers returns callable handlers and forwards to inject
broadcastToOverlayWindows: () => {},
onSubtitleChange: () => {},
refreshDiscordPresence: () => {},
ensureImmersionTrackerInitialized: () => {},
updateCurrentMediaPath: () => {},
restoreMpvSubVisibility: () => {},
getCurrentAnilistMediaKey: () => null,

View File

@@ -40,6 +40,7 @@ test('mpv main event main deps map app state updates and delegate callbacks', as
broadcastToOverlayWindows: (channel, payload) =>
calls.push(`broadcast:${channel}:${String(payload)}`),
onSubtitleChange: (text) => calls.push(`subtitle-change:${text}`),
ensureImmersionTrackerInitialized: () => calls.push('ensure-immersion'),
updateCurrentMediaPath: (path) => calls.push(`path:${path}`),
restoreMpvSubVisibility: () => calls.push('restore-mpv-sub'),
getCurrentAnilistMediaKey: () => 'media-key',
@@ -97,6 +98,7 @@ test('mpv main event main deps map app state updates and delegate callbacks', as
assert.ok(calls.includes('remote-stopped'));
assert.ok(calls.includes('sync-overlay-mpv-sub'));
assert.ok(calls.includes('anilist-post-watch'));
assert.ok(calls.includes('ensure-immersion'));
assert.ok(calls.includes('sync-immersion'));
assert.ok(calls.includes('metrics'));
assert.ok(calls.includes('presence-refresh'));

View File

@@ -38,6 +38,7 @@ export function createBuildBindMpvMainEventHandlersMainDepsHandler(deps: {
reportJellyfinRemoteProgress: (forceImmediate: boolean) => void;
updateSubtitleRenderMetrics: (patch: Record<string, unknown>) => void;
refreshDiscordPresence: () => void;
ensureImmersionTrackerInitialized: () => void;
}) {
return () => ({
reportJellyfinRemoteStopped: () => deps.reportJellyfinRemoteStopped(),
@@ -48,8 +49,10 @@ export function createBuildBindMpvMainEventHandlersMainDepsHandler(deps: {
scheduleQuitCheck: (callback: () => void) => deps.scheduleQuitCheck(callback),
isMpvConnected: () => Boolean(deps.appState.mpvClient?.connected),
quitApp: () => deps.quitApp(),
recordImmersionSubtitleLine: (text: string, start: number, end: number) =>
deps.appState.immersionTracker?.recordSubtitleLine?.(text, start, end),
recordImmersionSubtitleLine: (text: string, start: number, end: number) => {
deps.ensureImmersionTrackerInitialized();
deps.appState.immersionTracker?.recordSubtitleLine?.(text, start, end);
},
hasSubtitleTimingTracker: () => Boolean(deps.appState.subtitleTimingTracker),
recordSubtitleTiming: (text: string, start: number, end: number) =>
deps.appState.subtitleTimingTracker?.recordSubtitle?.(text, start, end),
@@ -71,8 +74,7 @@ export function createBuildBindMpvMainEventHandlersMainDepsHandler(deps: {
broadcastSecondarySubtitle: (text: string) =>
deps.broadcastToOverlayWindows('secondary-subtitle:set', text),
updateCurrentMediaPath: (path: string) => deps.updateCurrentMediaPath(path),
restoreMpvSubVisibility: () =>
deps.restoreMpvSubVisibility(),
restoreMpvSubVisibility: () => deps.restoreMpvSubVisibility(),
getCurrentAnilistMediaKey: () => deps.getCurrentAnilistMediaKey(),
resetAnilistMediaTracking: (mediaKey: string | null) =>
deps.resetAnilistMediaTracking(mediaKey),
@@ -81,14 +83,19 @@ export function createBuildBindMpvMainEventHandlersMainDepsHandler(deps: {
syncImmersionMediaState: () => deps.syncImmersionMediaState(),
updateCurrentMediaTitle: (title: string) => deps.updateCurrentMediaTitle(title),
resetAnilistMediaGuessState: () => deps.resetAnilistMediaGuessState(),
notifyImmersionTitleUpdate: (title: string) =>
deps.appState.immersionTracker?.handleMediaTitleUpdate?.(title),
recordPlaybackPosition: (time: number) =>
deps.appState.immersionTracker?.recordPlaybackPosition?.(time),
notifyImmersionTitleUpdate: (title: string) => {
deps.ensureImmersionTrackerInitialized();
deps.appState.immersionTracker?.handleMediaTitleUpdate?.(title);
},
recordPlaybackPosition: (time: number) => {
deps.ensureImmersionTrackerInitialized();
deps.appState.immersionTracker?.recordPlaybackPosition?.(time);
},
reportJellyfinRemoteProgress: (forceImmediate: boolean) =>
deps.reportJellyfinRemoteProgress(forceImmediate),
recordPauseState: (paused: boolean) => {
deps.appState.playbackPaused = paused;
deps.ensureImmersionTrackerInitialized();
deps.appState.immersionTracker?.recordPauseState?.(paused);
},
updateSubtitleRenderMetrics: (patch: Record<string, unknown>) =>