feat(config): unify mpv plugin options under main config and add CSS/Ani

- Replace subminer.conf plugin config with mpv.* fields in config.jsonc
- Add socketPath, backend, autoStartSubMiner, pauseUntilOverlayReady, aniskipEnabled/buttonKey, subminerBinaryPath to mpv config
- Add subtitleSidebar.css field; migrate legacy sidebar appearance fields
- Add paintOrder and WebkitTextStroke to subtitle style options
- Update default subtitle/sidebar fontFamily to CJK-first stack
- Fix overlay visible state surviving mpv y-r restart
- Fix live config saves applying subtitle CSS immediately to open overlays
- Migrate legacy primary/secondary subtitle appearance into subtitleStyle.css on load
- Switch AniSkip button key setting to click-to-learn key capture
This commit is contained in:
2026-05-17 18:01:39 -07:00
parent 81830b3372
commit 6ba91780c1
91 changed files with 2241 additions and 727 deletions
+17 -1
View File
@@ -30,6 +30,7 @@ import type {
FrequencyDictionaryMatchMode,
FrequencyDictionaryMode,
NPlusOneMatchMode,
ResolvedSubtitleSidebarConfig,
SecondarySubConfig,
SubtitlePosition,
SubtitleSidebarConfig,
@@ -52,10 +53,18 @@ export interface TexthookerConfig {
}
export type MpvLaunchMode = 'normal' | 'maximized' | 'fullscreen';
export type MpvBackend = 'auto' | 'hyprland' | 'sway' | 'x11' | 'macos' | 'windows';
export interface MpvConfig {
executablePath?: string;
launchMode?: MpvLaunchMode;
socketPath?: string;
backend?: MpvBackend;
autoStartSubMiner?: boolean;
pauseUntilOverlayReady?: boolean;
subminerBinaryPath?: string;
aniskipEnabled?: boolean;
aniskipButtonKey?: string;
}
export type SubsyncMode = 'auto' | 'manual';
@@ -150,6 +159,13 @@ export interface ResolvedConfig {
mpv: {
executablePath: string;
launchMode: MpvLaunchMode;
socketPath: string;
backend: MpvBackend;
autoStartSubMiner: boolean;
pauseUntilOverlayReady: boolean;
subminerBinaryPath: string;
aniskipEnabled: boolean;
aniskipButtonKey: string;
};
controller: {
enabled: boolean;
@@ -260,7 +276,7 @@ export interface ResolvedConfig {
bandedColors: [string, string, string, string, string];
};
};
subtitleSidebar: Required<SubtitleSidebarConfig>;
subtitleSidebar: ResolvedSubtitleSidebarConfig;
auto_start_overlay: boolean;
jimaku: JimakuConfig & {
apiBaseUrl: string;
+2 -2
View File
@@ -26,10 +26,10 @@ import type {
} from './integrations';
import type {
PrimarySubMode,
ResolvedSubtitleSidebarConfig,
SecondarySubMode,
SubtitleData,
SubtitlePosition,
SubtitleSidebarConfig,
SubtitleSidebarSnapshot,
SubtitleRendererStyleConfig,
SubtitleStyleConfig,
@@ -345,7 +345,7 @@ export interface ConfigHotReloadPayload {
sessionBindings: CompiledSessionBinding[];
sessionBindingWarnings: SessionBindingWarning[];
subtitleStyle: SubtitleRendererStyleConfig | null;
subtitleSidebar: Required<SubtitleSidebarConfig>;
subtitleSidebar: ResolvedSubtitleSidebarConfig;
primarySubMode: PrimarySubMode;
secondarySubMode: SecondarySubMode;
}
+1 -1
View File
@@ -4,7 +4,6 @@ export type ConfigSettingsCategory =
| 'appearance'
| 'behavior'
| 'mining-anki'
| 'playback-sources'
| 'input'
| 'integrations'
| 'tracking-app'
@@ -22,6 +21,7 @@ export type ConfigSettingsControl =
| 'secret'
| 'keyboard-shortcut'
| 'key-code'
| 'mpv-key'
| 'known-words-decks'
| 'anki-note-type'
| 'anki-field'
+14 -1
View File
@@ -90,6 +90,8 @@ export interface SubtitleStyleConfig {
fontKerning?: string;
textRendering?: string;
textShadow?: string;
paintOrder?: string;
WebkitTextStroke?: string;
backdropFilter?: string;
backgroundColor?: string;
nPlusOneColor?: string;
@@ -123,6 +125,8 @@ export interface SubtitleStyleConfig {
fontKerning?: string;
textRendering?: string;
textShadow?: string;
paintOrder?: string;
WebkitTextStroke?: string;
backdropFilter?: string;
backgroundColor?: string;
};
@@ -167,6 +171,7 @@ export interface SubtitleSidebarConfig {
toggleKey?: string;
pauseVideoOnHover?: boolean;
autoScroll?: boolean;
css?: Record<string, string>;
maxWidth?: number;
opacity?: number;
backgroundColor?: string;
@@ -179,6 +184,14 @@ export interface SubtitleSidebarConfig {
hoverLineBackgroundColor?: string;
}
export type ResolvedSubtitleSidebarConfig = Required<Omit<SubtitleSidebarConfig, 'css'>> & {
css: Record<string, string>;
};
export type SubtitleSidebarSnapshotConfig = Required<Omit<SubtitleSidebarConfig, 'css'>> & {
css?: Record<string, string>;
};
export interface SubtitleData {
text: string;
tokens: MergedToken[] | null;
@@ -194,7 +207,7 @@ export interface SubtitleSidebarSnapshot {
startTime: number | null;
endTime: number | null;
};
config: Required<SubtitleSidebarConfig>;
config: SubtitleSidebarSnapshotConfig;
}
export interface SubtitleHoverTokenPayload {