feat: add mark-watched action, background app reuse, and N+1 compat

- Add `--mark-watched` CLI flag + mpv session binding; marks video watched, shows OSD, advances playlist
- Launcher detects running background app via `--app-ping` and borrows it instead of owning its lifecycle
- Preserve N+1 highlighting for existing configs with `knownWords.highlightEnabled` set
- Fix `resolveConfiguredShortcuts` to respect explicit `null` overrides (disabling defaults)
- Split session-help modal into focused modules (colors, render, sections, tabs)
This commit is contained in:
2026-05-19 01:30:49 -07:00
parent 24b95eda9d
commit f4845513f3
42 changed files with 1429 additions and 505 deletions
+14
View File
@@ -4655,6 +4655,7 @@ function compileCurrentSessionBindings(): {
keybindings: appState.keybindings,
shortcuts: getConfiguredShortcuts(),
statsToggleKey: getResolvedConfig().stats.toggleKey,
statsMarkWatchedKey: getResolvedConfig().stats.markWatchedKey,
platform: resolveSessionBindingPlatform(),
rawConfig: getResolvedConfig(),
});
@@ -5141,6 +5142,17 @@ async function dispatchSessionAction(request: SessionActionDispatchRequest): Pro
toggleSecondarySub: () => handleCycleSecondarySubMode(),
toggleSubtitleSidebar: () => toggleSubtitleSidebar(),
markLastCardAsAudioCard: () => markLastCardAsAudioCard(),
markActiveVideoWatched: async () => {
const marked = (await appState.immersionTracker?.markActiveVideoWatched()) ?? false;
if (marked) {
try {
await maybeRunAnilistPostWatchUpdate({ force: true });
} catch (error) {
logger.warn('Failed to run AniList post-watch update after manual watched mark:', error);
}
}
return marked;
},
openRuntimeOptionsPalette: () => openRuntimeOptionsPalette(),
openJimaku: () => openJimakuOverlay(),
openSessionHelp: () => openSessionHelpOverlay(),
@@ -5162,6 +5174,8 @@ async function dispatchSessionAction(request: SessionActionDispatchRequest): Pro
(text) => showMpvOsd(text),
);
},
playNextPlaylistItem: () =>
sendMpvCommandRuntime(appState.mpvClient, ['playlist-next', 'force']),
showMpvOsd: (text) => showMpvOsd(text),
});
}