Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 2x 2x 99x 99x 1x 2x 231x 231x 2x 15x 15x 10x 10x | // SPDX-License-Identifier: GPL-3.0-only
// Copyright (C) 2026 Max Boksem. See NOTICE for additional terms under GPLv3 section 7.
// The subtitles the player showed when its page last closed, kept in
// sessionStorage. Playback goes on while another page is open, and mpv
// doesn't draw the subtitles the app draws itself. So when the player page
// opens again on the same item, it shows these again.
import { readStorage, removeStorage, writeStorage } from "./storage";
import type { SubtitlePosition } from "./subtitle-position";
import type { SubtitleCue, SubtitleEntry } from "./types";
const KEY = "mvp_lastSubtitles";
/** The language, and the place in it, to pick subtitles from for the next episode. */
export interface SubtitlePreference {
languageCode: string;
rankInLanguage: number;
}
export interface SubtitleSession {
/** The item the subtitles were shown over. */
channelId: string;
/** The URL the player last loaded for it, or null while it hadn't started. */
url: string | null;
/** The subtitle file picked, or null for none. */
fileId: number | null;
entry: SubtitleEntry | null;
cues: SubtitleCue[];
/** The delay picked for the subtitles, in seconds. */
delay: number;
position: SubtitlePosition;
fontSize: number;
fontFamily: string;
preference: SubtitlePreference | null;
/** Whether the next episode's subtitles were still loading. */
autoLoad: boolean;
}
/** The subtitles saved when the player page last closed, or null. */
export const readSubtitleSession = (): SubtitleSession | null => {
try {
return JSON.parse(readStorage(KEY, "session") ?? "null") as SubtitleSession | null;
} catch {
return null;
}
};
/**
* Saves the subtitles for when the player page opens again, or forgets them
* for null. The old ones go first, so a save that fails leaves none.
*/
export const saveSubtitleSession = (session: SubtitleSession | null): void => {
removeStorage(KEY, "session");
if (session) writeStorage(KEY, JSON.stringify(session), "session");
};
/**
* Changes the saved subtitles of the item `channelId` when the player last
* loaded `url` for it, as the page saved them. Returns false, and changes
* nothing, when none are saved or they're for another item or stream.
*/
export const updateSubtitleSession = (
channelId: string,
url: string | null,
change: Partial<SubtitleSession>
): boolean => {
const saved = readSubtitleSession();
if (!saved || saved.channelId !== channelId || saved.url !== url) return false;
saveSubtitleSession({ ...saved, ...change });
return true;
};
|