mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-07-27 16:49:51 -07:00
b5eb20e8fe
The animetosho backend was swapped for TsukiHime and never shipped in a release (the integration landed after v0.18.0), so no config migration or legacy aliases are needed. Renames the module, IPC channels, config key, session action, shortcut id, CLI flag, DOM ids, and CSS classes. "animetosho" is kept only where it names the upstream service: the imported-entry flag TsukiHime returns, the /tosho/ storage mirror path, and storage.animetosho.org, which that mirror currently redirects to. Also drops two stray NUL bytes that have sat inside the dedup-key template literals since the integration landed (#159). They were harmless (any separator groups correctly) but made grep treat the file as binary.
418 lines
11 KiB
TypeScript
418 lines
11 KiB
TypeScript
import type { AnkiConnectConfig } from './anki';
|
|
import type {
|
|
AiConfig,
|
|
AiFeatureConfig,
|
|
AnilistCharacterDictionaryCollapsibleSectionsConfig,
|
|
AnilistCharacterDictionaryEvictionPolicy,
|
|
AnilistCharacterDictionaryProfileScope,
|
|
AnilistConfig,
|
|
DiscordPresenceConfig,
|
|
ImmersionTrackingConfig,
|
|
ImmersionTrackingRetentionMode,
|
|
ImmersionTrackingRetentionPreset,
|
|
TsukihimeConfig,
|
|
JellyfinConfig,
|
|
JimakuConfig,
|
|
JimakuLanguagePreference,
|
|
StatsConfig,
|
|
YomitanConfig,
|
|
YoutubeConfig,
|
|
YoutubeMediaCacheMode,
|
|
YoutubeSubgenConfig,
|
|
} from './integrations';
|
|
import type {
|
|
ControllerButtonIndicesConfig,
|
|
ControllerConfig,
|
|
ResolvedControllerProfileConfig,
|
|
ControllerTriggerInputMode,
|
|
Keybinding,
|
|
ResolvedControllerBindingsConfig,
|
|
} from './runtime';
|
|
import type {
|
|
FrequencyDictionaryMatchMode,
|
|
FrequencyDictionaryMode,
|
|
NPlusOneMatchMode,
|
|
ResolvedSubtitleSidebarConfig,
|
|
SecondarySubConfig,
|
|
SubtitlePosition,
|
|
SubtitleSidebarConfig,
|
|
SubtitleStyleConfig,
|
|
} from './subtitle';
|
|
import type { NotificationType, OverlayNotificationPosition } from './notification';
|
|
|
|
export interface WebSocketConfig {
|
|
enabled?: boolean | 'auto';
|
|
port?: number;
|
|
}
|
|
|
|
export interface AnnotationWebSocketConfig {
|
|
enabled?: boolean;
|
|
port?: number;
|
|
}
|
|
|
|
export interface TexthookerConfig {
|
|
launchAtStartup?: boolean;
|
|
openBrowser?: boolean;
|
|
}
|
|
|
|
export type MpvLaunchMode = 'normal' | 'maximized' | 'fullscreen';
|
|
export type MpvBackend = 'auto' | 'hyprland' | 'sway' | 'x11' | 'macos' | 'windows';
|
|
|
|
export interface MpvConfig {
|
|
executablePath?: string;
|
|
launchMode?: MpvLaunchMode;
|
|
profile?: string;
|
|
socketPath?: string;
|
|
backend?: MpvBackend;
|
|
autoStartSubMiner?: boolean;
|
|
pauseUntilOverlayReady?: boolean;
|
|
subminerBinaryPath?: string;
|
|
aniskipEnabled?: boolean;
|
|
aniskipButtonKey?: string;
|
|
}
|
|
|
|
export interface SubsyncConfig {
|
|
alass_path?: string;
|
|
ffsubsync_path?: string;
|
|
ffmpeg_path?: string;
|
|
replace?: boolean;
|
|
}
|
|
|
|
export interface StartupWarmupsConfig {
|
|
lowPowerMode?: boolean;
|
|
mecab?: boolean;
|
|
yomitanExtension?: boolean;
|
|
subtitleDictionaries?: boolean;
|
|
jellyfinRemoteSession?: boolean;
|
|
}
|
|
|
|
export type UpdateNotificationType = NotificationType;
|
|
export type UpdateChannel = 'stable' | 'prerelease';
|
|
|
|
export interface UpdatesConfig {
|
|
enabled?: boolean;
|
|
checkIntervalHours?: number;
|
|
notificationType?: UpdateNotificationType;
|
|
channel?: UpdateChannel;
|
|
}
|
|
|
|
export interface NotificationsConfig {
|
|
overlayPosition?: OverlayNotificationPosition;
|
|
}
|
|
|
|
export type LogRotation = number;
|
|
|
|
export interface LogFilesConfig {
|
|
app?: boolean;
|
|
launcher?: boolean;
|
|
mpv?: boolean;
|
|
}
|
|
|
|
export interface ShortcutsConfig {
|
|
toggleVisibleOverlayGlobal?: string | null;
|
|
copySubtitle?: string | null;
|
|
copySubtitleMultiple?: string | null;
|
|
updateLastCardFromClipboard?: string | null;
|
|
triggerFieldGrouping?: string | null;
|
|
triggerSubsync?: string | null;
|
|
mineSentence?: string | null;
|
|
mineSentenceMultiple?: string | null;
|
|
multiCopyTimeoutMs?: number;
|
|
toggleSecondarySub?: string | null;
|
|
markAudioCard?: string | null;
|
|
openCharacterDictionaryManager?: string | null;
|
|
openRuntimeOptions?: string | null;
|
|
openJimaku?: string | null;
|
|
openTsukihime?: string | null;
|
|
openSessionHelp?: string | null;
|
|
openControllerSelect?: string | null;
|
|
openControllerDebug?: string | null;
|
|
toggleSubtitleSidebar?: string | null;
|
|
toggleNotificationHistory?: string | null;
|
|
appendClipboardVideoToQueue?: string | null;
|
|
}
|
|
|
|
export interface Config {
|
|
subtitlePosition?: SubtitlePosition;
|
|
keybindings?: Keybinding[];
|
|
websocket?: WebSocketConfig;
|
|
annotationWebsocket?: AnnotationWebSocketConfig;
|
|
texthooker?: TexthookerConfig;
|
|
mpv?: MpvConfig;
|
|
controller?: ControllerConfig;
|
|
ankiConnect?: AnkiConnectConfig;
|
|
shortcuts?: ShortcutsConfig;
|
|
secondarySub?: SecondarySubConfig;
|
|
subsync?: SubsyncConfig;
|
|
startupWarmups?: StartupWarmupsConfig;
|
|
subtitleStyle?: SubtitleStyleConfig;
|
|
subtitleSidebar?: SubtitleSidebarConfig;
|
|
auto_start_overlay?: boolean;
|
|
jimaku?: JimakuConfig;
|
|
tsukihime?: TsukihimeConfig;
|
|
anilist?: AnilistConfig;
|
|
yomitan?: YomitanConfig;
|
|
jellyfin?: JellyfinConfig;
|
|
discordPresence?: DiscordPresenceConfig;
|
|
ai?: AiConfig;
|
|
youtube?: YoutubeConfig;
|
|
youtubeSubgen?: YoutubeSubgenConfig;
|
|
immersionTracking?: ImmersionTrackingConfig;
|
|
stats?: StatsConfig;
|
|
updates?: UpdatesConfig;
|
|
notifications?: NotificationsConfig;
|
|
logging?: {
|
|
level?: 'debug' | 'info' | 'warn' | 'error';
|
|
rotation?: LogRotation;
|
|
files?: LogFilesConfig;
|
|
};
|
|
}
|
|
|
|
export type RawConfig = Config;
|
|
|
|
export interface ResolvedConfig {
|
|
subtitlePosition: SubtitlePosition;
|
|
keybindings: Keybinding[];
|
|
websocket: Required<WebSocketConfig>;
|
|
annotationWebsocket: Required<AnnotationWebSocketConfig>;
|
|
texthooker: Required<TexthookerConfig>;
|
|
mpv: {
|
|
executablePath: string;
|
|
launchMode: MpvLaunchMode;
|
|
profile: string;
|
|
socketPath: string;
|
|
backend: MpvBackend;
|
|
autoStartSubMiner: boolean;
|
|
pauseUntilOverlayReady: boolean;
|
|
subminerBinaryPath: string;
|
|
aniskipEnabled: boolean;
|
|
aniskipButtonKey: string;
|
|
};
|
|
controller: {
|
|
enabled: boolean;
|
|
preferredGamepadId: string;
|
|
preferredGamepadLabel: string;
|
|
smoothScroll: boolean;
|
|
scrollPixelsPerSecond: number;
|
|
horizontalJumpPixels: number;
|
|
stickDeadzone: number;
|
|
triggerInputMode: ControllerTriggerInputMode;
|
|
triggerDeadzone: number;
|
|
repeatDelayMs: number;
|
|
repeatIntervalMs: number;
|
|
buttonIndices: Required<ControllerButtonIndicesConfig>;
|
|
bindings: Required<ResolvedControllerBindingsConfig>;
|
|
profiles: Record<string, ResolvedControllerProfileConfig>;
|
|
};
|
|
ankiConnect: AnkiConnectConfig & {
|
|
enabled: boolean;
|
|
url: string;
|
|
pollingRate: number;
|
|
proxy: {
|
|
enabled: boolean;
|
|
host: string;
|
|
port: number;
|
|
upstreamUrl: string;
|
|
};
|
|
tags: string[];
|
|
fields: {
|
|
word: string;
|
|
audio: string;
|
|
image: string;
|
|
sentence: string;
|
|
miscInfo: string;
|
|
translation: string;
|
|
};
|
|
ai: AiFeatureConfig & {
|
|
enabled: boolean;
|
|
};
|
|
media: {
|
|
generateAudio: boolean;
|
|
generateImage: boolean;
|
|
imageType: 'static' | 'avif';
|
|
imageFormat: 'jpg' | 'png' | 'webp';
|
|
imageQuality: number;
|
|
imageMaxWidth?: number;
|
|
imageMaxHeight?: number;
|
|
animatedFps: number;
|
|
animatedMaxWidth: number;
|
|
animatedMaxHeight?: number;
|
|
animatedCrf: number;
|
|
syncAnimatedImageToWordAudio: boolean;
|
|
normalizeAudio: boolean;
|
|
mirrorMpvVolume: boolean;
|
|
audioPadding: number;
|
|
fallbackDuration: number;
|
|
maxMediaDuration: number;
|
|
};
|
|
knownWords: {
|
|
highlightEnabled: boolean;
|
|
refreshMinutes: number;
|
|
addMinedWordsImmediately: boolean;
|
|
matchMode: NPlusOneMatchMode;
|
|
decks: Record<string, string[]>;
|
|
};
|
|
nPlusOne: {
|
|
enabled: boolean;
|
|
minSentenceWords: number;
|
|
};
|
|
behavior: {
|
|
overwriteAudio: boolean;
|
|
overwriteImage: boolean;
|
|
mediaInsertMode: 'append' | 'prepend';
|
|
highlightWord: boolean;
|
|
notificationType: NotificationType;
|
|
autoUpdateNewCards: boolean;
|
|
};
|
|
metadata: {
|
|
pattern: string;
|
|
};
|
|
isLapis: {
|
|
enabled: boolean;
|
|
sentenceCardModel: string;
|
|
};
|
|
isKiku: {
|
|
enabled: boolean;
|
|
fieldGrouping: 'auto' | 'manual' | 'disabled';
|
|
deleteDuplicateInAuto: boolean;
|
|
};
|
|
};
|
|
shortcuts: Required<ShortcutsConfig>;
|
|
secondarySub: Required<SecondarySubConfig>;
|
|
subsync: Required<SubsyncConfig>;
|
|
startupWarmups: {
|
|
lowPowerMode: boolean;
|
|
mecab: boolean;
|
|
yomitanExtension: boolean;
|
|
subtitleDictionaries: boolean;
|
|
jellyfinRemoteSession: boolean;
|
|
};
|
|
subtitleStyle: Required<Omit<SubtitleStyleConfig, 'secondary' | 'frequencyDictionary'>> & {
|
|
secondary: Required<NonNullable<SubtitleStyleConfig['secondary']>>;
|
|
frequencyDictionary: {
|
|
enabled: boolean;
|
|
sourcePath: string;
|
|
topX: number;
|
|
mode: FrequencyDictionaryMode;
|
|
matchMode: FrequencyDictionaryMatchMode;
|
|
singleColor: string;
|
|
bandedColors: [string, string, string, string, string];
|
|
};
|
|
};
|
|
subtitleSidebar: ResolvedSubtitleSidebarConfig;
|
|
auto_start_overlay: boolean;
|
|
jimaku: JimakuConfig & {
|
|
apiBaseUrl: string;
|
|
languagePreference: JimakuLanguagePreference;
|
|
maxEntryResults: number;
|
|
};
|
|
tsukihime: TsukihimeConfig & {
|
|
apiBaseUrl: string;
|
|
maxSearchResults: number;
|
|
};
|
|
anilist: {
|
|
enabled: boolean;
|
|
accessToken: string;
|
|
characterDictionary: {
|
|
refreshTtlHours: number;
|
|
maxLoaded: number;
|
|
evictionPolicy: AnilistCharacterDictionaryEvictionPolicy;
|
|
profileScope: AnilistCharacterDictionaryProfileScope;
|
|
collapsibleSections: Required<AnilistCharacterDictionaryCollapsibleSectionsConfig>;
|
|
};
|
|
};
|
|
yomitan: {
|
|
externalProfilePath: string;
|
|
};
|
|
jellyfin: {
|
|
enabled: boolean;
|
|
serverUrl: string;
|
|
recentServers: string[];
|
|
username: string;
|
|
defaultLibraryId: string;
|
|
remoteControlEnabled: boolean;
|
|
remoteControlAutoConnect: boolean;
|
|
autoAnnounce: boolean;
|
|
pullPictures: boolean;
|
|
iconCacheDir: string;
|
|
directPlayPreferred: boolean;
|
|
directPlayContainers: string[];
|
|
transcodeVideoCodec: string;
|
|
};
|
|
discordPresence: {
|
|
enabled: boolean;
|
|
presenceStyle: import('./integrations').DiscordPresenceStylePreset;
|
|
updateIntervalMs: number;
|
|
debounceMs: number;
|
|
};
|
|
ai: AiConfig & {
|
|
enabled: boolean;
|
|
apiKey: string;
|
|
apiKeyCommand: string;
|
|
baseUrl: string;
|
|
model: string;
|
|
systemPrompt: string;
|
|
requestTimeoutMs: number;
|
|
};
|
|
youtube: YoutubeConfig & {
|
|
primarySubLanguages: string[];
|
|
mediaCache: {
|
|
mode: YoutubeMediaCacheMode;
|
|
maxHeight: number;
|
|
};
|
|
};
|
|
youtubeSubgen: YoutubeSubgenConfig & {
|
|
whisperBin: string;
|
|
whisperModel: string;
|
|
whisperVadModel: string;
|
|
whisperThreads: number;
|
|
fixWithAi: boolean;
|
|
ai: AiFeatureConfig;
|
|
};
|
|
immersionTracking: {
|
|
enabled: boolean;
|
|
dbPath?: string;
|
|
batchSize: number;
|
|
flushIntervalMs: number;
|
|
queueCap: number;
|
|
payloadCapBytes: number;
|
|
maintenanceIntervalMs: number;
|
|
retentionMode: ImmersionTrackingRetentionMode;
|
|
retentionPreset: ImmersionTrackingRetentionPreset;
|
|
retention: {
|
|
eventsDays: number;
|
|
telemetryDays: number;
|
|
sessionsDays: number;
|
|
dailyRollupsDays: number;
|
|
monthlyRollupsDays: number;
|
|
vacuumIntervalDays: number;
|
|
};
|
|
lifetimeSummaries: {
|
|
global: boolean;
|
|
anime: boolean;
|
|
media: boolean;
|
|
};
|
|
};
|
|
stats: {
|
|
toggleKey: string;
|
|
markWatchedKey: string;
|
|
serverPort: number;
|
|
autoStartServer: boolean;
|
|
autoOpenBrowser: boolean;
|
|
};
|
|
updates: Required<UpdatesConfig>;
|
|
notifications: Required<NotificationsConfig>;
|
|
logging: {
|
|
level: 'debug' | 'info' | 'warn' | 'error';
|
|
rotation: LogRotation;
|
|
files: Required<LogFilesConfig>;
|
|
};
|
|
}
|
|
|
|
export interface ConfigValidationWarning {
|
|
path: string;
|
|
value: unknown;
|
|
fallback: unknown;
|
|
message: string;
|
|
}
|