feat(overlay): add subtitle selection modal and Jellyfin 12 fixes

- Add an optional subtitle selection modal for primary/secondary mpv tracks (subtitleSelection.enabled, g-s sequence shortcut) with key-sequence conflict handling
- Authenticate Jellyfin URLs with the ApiKey query, answer remote keep-alives, clear now-playing on stop, and restore episode titles in Anki misc info
- Honor the configured mpv executable when Jellyfin starts playback via a shared mpv-process launcher
- Bump electron-builder to 26.16.1
- Condense and reconcile changelog fragments; update config example and docs
This commit is contained in:
sudacode committed 2026-09-22 18:51:59 -07:00
commit cacaa2b371
114 files changed
+2404 -381

No files matched your search

+3
View File
@@ -126,6 +126,7 @@ export interface ShortcutsConfig {
openRuntimeOptions?: string | null;
openJimaku?: string | null;
openTsukihime?: string | null;
openSubtitleSelection?: string | null;
openSubtitleGeneration?: string | null;
openSessionHelp?: string | null;
openControllerSelect?: string | null;
@@ -156,6 +157,7 @@ export interface Config {
shortcuts?: RawShortcutsConfig;
secondarySub?: SecondarySubConfig;
subsync?: SubsyncConfig;
subtitleSelection?: { enabled?: boolean };
subtitleGeneration?: Partial<SubtitleGenerationConfig>;
startupWarmups?: StartupWarmupsConfig;
subtitleStyle?: SubtitleStyleConfig;
@@ -310,6 +312,7 @@ export interface ResolvedConfig {
shortcuts: Required<ShortcutsConfig>;
secondarySub: Required<SecondarySubConfig>;
subsync: Required<SubsyncConfig>;
subtitleSelection: { enabled: boolean };
subtitleGeneration: SubtitleGenerationConfig;
startupWarmups: {
lowPowerMode: boolean;
+10
View File
@@ -525,6 +525,13 @@ export interface ElectronAPI {
focusMainWindow: () => Promise<void>;
activatePlaybackWindowForOverlayInteraction: () => Promise<boolean>;
getSubtitleStyle: () => Promise<SubtitleRendererStyleConfig | null>;
onSubtitleSelectionOpen: (callback: () => void) => void;
getSubtitleSelection: () => Promise<
import('../shared/subtitle-selection').SubtitleSelectionState
>;
applySubtitleSelection: (
request: import('../shared/subtitle-selection').SubtitleSelectionRequest,
) => Promise<void>;
onSubsyncManualOpen: (callback: (payload: SubsyncManualPayload) => void) => void;
runSubsyncManual: (request: SubsyncManualRunRequest) => Promise<SubsyncResult>;
onKikuFieldGroupingRequest: (callback: (data: KikuFieldGroupingRequestData) => void) => void;
@@ -604,6 +611,7 @@ export interface ElectronAPI {
modal:
| 'runtime-options'
| 'subsync'
| 'subtitle-selection'
| 'subtitle-generation'
| 'jimaku'
| 'tsukihime'
@@ -622,6 +630,7 @@ export interface ElectronAPI {
modal:
| 'runtime-options'
| 'subsync'
| 'subtitle-selection'
| 'subtitle-generation'
| 'jimaku'
| 'tsukihime'
@@ -637,6 +646,7 @@ export interface ElectronAPI {
| 'changelog',
) => void;
reportOverlayContentBounds: (measurement: OverlayContentMeasurement) => void;
onSessionBindingsChanged: (callback: (bindings: CompiledSessionBinding[]) => void) => void;
onConfigHotReload: (callback: (payload: ConfigHotReloadPayload) => void) => void;
}
+1
View File
@@ -23,6 +23,7 @@ export type SessionActionId =
| 'openControllerDebug'
| 'openJimaku'
| 'openTsukihime'
| 'openSubtitleSelection'
| 'openSubtitleGeneration'
| 'openYoutubePicker'
| 'openPlaylistBrowser'