feat(tracking): store secondary subtitle text and source path in occurrence data

- Add secondary_text column to imm_subtitle_lines with migration
- Pass currentSecondarySubText through recordSubtitleLine flow
- Include secondaryText and sourcePath in word/kanji occurrence queries
- Update all type interfaces (backend + frontend)
This commit is contained in:
2026-03-16 01:43:05 -07:00
parent 5a30446809
commit a1f30fd482
7 changed files with 46 additions and 13 deletions

View File

@@ -4,13 +4,14 @@ export function createBuildBindMpvMainEventHandlersMainDepsHandler(deps: {
appState: {
initialArgs?: { jellyfinPlay?: unknown } | null;
overlayRuntimeInitialized: boolean;
mpvClient: { connected?: boolean } | null;
mpvClient: { connected?: boolean; currentSecondarySubText?: string } | null;
immersionTracker: {
recordSubtitleLine?: (
text: string,
start: number,
end: number,
tokens?: MergedToken[] | null,
secondaryText?: string | null,
) => void;
handleMediaTitleUpdate?: (title: string) => void;
recordPlaybackPosition?: (time: number) => void;
@@ -70,25 +71,26 @@ export function createBuildBindMpvMainEventHandlersMainDepsHandler(deps: {
if (!tracker?.recordSubtitleLine) {
return;
}
const secondaryText = deps.appState.mpvClient?.currentSecondarySubText || null;
const cachedTokens =
deps.appState.currentSubtitleData?.text === text
? deps.appState.currentSubtitleData.tokens
: null;
if (cachedTokens) {
tracker.recordSubtitleLine(text, start, end, cachedTokens);
tracker.recordSubtitleLine(text, start, end, cachedTokens, secondaryText);
return;
}
if (!deps.tokenizeSubtitleForImmersion) {
tracker.recordSubtitleLine(text, start, end, null);
tracker.recordSubtitleLine(text, start, end, null, secondaryText);
return;
}
void deps
.tokenizeSubtitleForImmersion(text)
.then((payload) => {
tracker.recordSubtitleLine?.(text, start, end, payload?.tokens ?? null);
tracker.recordSubtitleLine?.(text, start, end, payload?.tokens ?? null, secondaryText);
})
.catch(() => {
tracker.recordSubtitleLine?.(text, start, end, null);
tracker.recordSubtitleLine?.(text, start, end, null, secondaryText);
});
},
hasSubtitleTimingTracker: () => Boolean(deps.appState.subtitleTimingTracker),