import { RuntimeOptionId, RuntimeOptionValue, SubsyncManualPayload } from '../types'; import { SubsyncResolvedConfig } from '../subsync/utils'; import type { SubsyncRuntimeDeps } from '../core/services/subsync-runner'; import type { IpcDepsRuntimeOptions } from '../core/services/ipc'; import type { AnkiJimakuIpcRuntimeOptions } from '../core/services/anki-jimaku'; import type { CliCommandDepsRuntimeOptions } from '../core/services/cli-command'; import type { HandleMpvCommandFromIpcOptions } from '../core/services/ipc-command'; import { cycleRuntimeOptionFromIpcRuntime, setRuntimeOptionFromIpcRuntime, } from '../core/services/runtime-options-ipc'; import { RuntimeOptionsManager } from '../runtime-options'; export interface RuntimeOptionsIpcDepsParams { getRuntimeOptionsManager: () => RuntimeOptionsManager | null; showMpvOsd: (text: string) => void; } export interface SubsyncRuntimeDepsParams { getMpvClient: () => ReturnType; getResolvedSubsyncConfig: () => SubsyncResolvedConfig; isSubsyncInProgress: () => boolean; setSubsyncInProgress: (inProgress: boolean) => void; showMpvOsd: (text: string) => void; openManualPicker: (payload: SubsyncManualPayload) => void; } export function createRuntimeOptionsIpcDeps(params: RuntimeOptionsIpcDepsParams): { setRuntimeOption: (id: RuntimeOptionId, value: RuntimeOptionValue) => unknown; cycleRuntimeOption: (id: RuntimeOptionId, direction: 1 | -1) => unknown; } { return { setRuntimeOption: (id, value) => setRuntimeOptionFromIpcRuntime(params.getRuntimeOptionsManager(), id, value, (text) => params.showMpvOsd(text), ), cycleRuntimeOption: (id, direction) => cycleRuntimeOptionFromIpcRuntime(params.getRuntimeOptionsManager(), id, direction, (text) => params.showMpvOsd(text), ), }; } export function createSubsyncRuntimeDeps(params: SubsyncRuntimeDepsParams): SubsyncRuntimeDeps { return { getMpvClient: params.getMpvClient, getResolvedSubsyncConfig: params.getResolvedSubsyncConfig, isSubsyncInProgress: params.isSubsyncInProgress, setSubsyncInProgress: params.setSubsyncInProgress, showMpvOsd: params.showMpvOsd, openManualPicker: params.openManualPicker, }; } export interface MainIpcRuntimeServiceDepsParams { getMainWindow: IpcDepsRuntimeOptions['getMainWindow']; getVisibleOverlayVisibility: IpcDepsRuntimeOptions['getVisibleOverlayVisibility']; onOverlayModalClosed: IpcDepsRuntimeOptions['onOverlayModalClosed']; onOverlayModalOpened?: IpcDepsRuntimeOptions['onOverlayModalOpened']; openYomitanSettings: IpcDepsRuntimeOptions['openYomitanSettings']; quitApp: IpcDepsRuntimeOptions['quitApp']; toggleVisibleOverlay: IpcDepsRuntimeOptions['toggleVisibleOverlay']; tokenizeCurrentSubtitle: IpcDepsRuntimeOptions['tokenizeCurrentSubtitle']; getCurrentSubtitleRaw: IpcDepsRuntimeOptions['getCurrentSubtitleRaw']; getCurrentSubtitleAss: IpcDepsRuntimeOptions['getCurrentSubtitleAss']; getPlaybackPaused: IpcDepsRuntimeOptions['getPlaybackPaused']; focusMainWindow?: IpcDepsRuntimeOptions['focusMainWindow']; getSubtitlePosition: IpcDepsRuntimeOptions['getSubtitlePosition']; getSubtitleStyle: IpcDepsRuntimeOptions['getSubtitleStyle']; saveSubtitlePosition: IpcDepsRuntimeOptions['saveSubtitlePosition']; getMecabTokenizer: IpcDepsRuntimeOptions['getMecabTokenizer']; handleMpvCommand: IpcDepsRuntimeOptions['handleMpvCommand']; getKeybindings: IpcDepsRuntimeOptions['getKeybindings']; getConfiguredShortcuts: IpcDepsRuntimeOptions['getConfiguredShortcuts']; getSecondarySubMode: IpcDepsRuntimeOptions['getSecondarySubMode']; getMpvClient: IpcDepsRuntimeOptions['getMpvClient']; runSubsyncManual: IpcDepsRuntimeOptions['runSubsyncManual']; getAnkiConnectStatus: IpcDepsRuntimeOptions['getAnkiConnectStatus']; getRuntimeOptions: IpcDepsRuntimeOptions['getRuntimeOptions']; setRuntimeOption: IpcDepsRuntimeOptions['setRuntimeOption']; cycleRuntimeOption: IpcDepsRuntimeOptions['cycleRuntimeOption']; reportOverlayContentBounds: IpcDepsRuntimeOptions['reportOverlayContentBounds']; getAnilistStatus: IpcDepsRuntimeOptions['getAnilistStatus']; clearAnilistToken: IpcDepsRuntimeOptions['clearAnilistToken']; openAnilistSetup: IpcDepsRuntimeOptions['openAnilistSetup']; getAnilistQueueStatus: IpcDepsRuntimeOptions['getAnilistQueueStatus']; retryAnilistQueueNow: IpcDepsRuntimeOptions['retryAnilistQueueNow']; appendClipboardVideoToQueue: IpcDepsRuntimeOptions['appendClipboardVideoToQueue']; } export interface AnkiJimakuIpcRuntimeServiceDepsParams { patchAnkiConnectEnabled: AnkiJimakuIpcRuntimeOptions['patchAnkiConnectEnabled']; getResolvedConfig: AnkiJimakuIpcRuntimeOptions['getResolvedConfig']; getRuntimeOptionsManager: AnkiJimakuIpcRuntimeOptions['getRuntimeOptionsManager']; getSubtitleTimingTracker: AnkiJimakuIpcRuntimeOptions['getSubtitleTimingTracker']; getMpvClient: AnkiJimakuIpcRuntimeOptions['getMpvClient']; getAnkiIntegration: AnkiJimakuIpcRuntimeOptions['getAnkiIntegration']; setAnkiIntegration: AnkiJimakuIpcRuntimeOptions['setAnkiIntegration']; getKnownWordCacheStatePath: AnkiJimakuIpcRuntimeOptions['getKnownWordCacheStatePath']; showDesktopNotification: AnkiJimakuIpcRuntimeOptions['showDesktopNotification']; createFieldGroupingCallback: AnkiJimakuIpcRuntimeOptions['createFieldGroupingCallback']; broadcastRuntimeOptionsChanged: AnkiJimakuIpcRuntimeOptions['broadcastRuntimeOptionsChanged']; getFieldGroupingResolver: AnkiJimakuIpcRuntimeOptions['getFieldGroupingResolver']; setFieldGroupingResolver: AnkiJimakuIpcRuntimeOptions['setFieldGroupingResolver']; parseMediaInfo: AnkiJimakuIpcRuntimeOptions['parseMediaInfo']; getCurrentMediaPath: AnkiJimakuIpcRuntimeOptions['getCurrentMediaPath']; jimakuFetchJson: AnkiJimakuIpcRuntimeOptions['jimakuFetchJson']; getJimakuMaxEntryResults: AnkiJimakuIpcRuntimeOptions['getJimakuMaxEntryResults']; getJimakuLanguagePreference: AnkiJimakuIpcRuntimeOptions['getJimakuLanguagePreference']; resolveJimakuApiKey: AnkiJimakuIpcRuntimeOptions['resolveJimakuApiKey']; isRemoteMediaPath: AnkiJimakuIpcRuntimeOptions['isRemoteMediaPath']; downloadToFile: AnkiJimakuIpcRuntimeOptions['downloadToFile']; } export interface CliCommandRuntimeServiceDepsParams { setLogLevel?: CliCommandDepsRuntimeOptions['setLogLevel']; mpv: { getSocketPath: CliCommandDepsRuntimeOptions['mpv']['getSocketPath']; setSocketPath: CliCommandDepsRuntimeOptions['mpv']['setSocketPath']; getClient: CliCommandDepsRuntimeOptions['mpv']['getClient']; showOsd: CliCommandDepsRuntimeOptions['mpv']['showOsd']; }; texthooker: { service: CliCommandDepsRuntimeOptions['texthooker']['service']; getPort: CliCommandDepsRuntimeOptions['texthooker']['getPort']; setPort: CliCommandDepsRuntimeOptions['texthooker']['setPort']; shouldOpenBrowser: CliCommandDepsRuntimeOptions['texthooker']['shouldOpenBrowser']; openInBrowser: CliCommandDepsRuntimeOptions['texthooker']['openInBrowser']; }; overlay: { isInitialized: CliCommandDepsRuntimeOptions['overlay']['isInitialized']; initialize: CliCommandDepsRuntimeOptions['overlay']['initialize']; toggleVisible: CliCommandDepsRuntimeOptions['overlay']['toggleVisible']; setVisible: CliCommandDepsRuntimeOptions['overlay']['setVisible']; }; mining: { copyCurrentSubtitle: CliCommandDepsRuntimeOptions['mining']['copyCurrentSubtitle']; startPendingMultiCopy: CliCommandDepsRuntimeOptions['mining']['startPendingMultiCopy']; mineSentenceCard: CliCommandDepsRuntimeOptions['mining']['mineSentenceCard']; startPendingMineSentenceMultiple: CliCommandDepsRuntimeOptions['mining']['startPendingMineSentenceMultiple']; updateLastCardFromClipboard: CliCommandDepsRuntimeOptions['mining']['updateLastCardFromClipboard']; refreshKnownWords: CliCommandDepsRuntimeOptions['mining']['refreshKnownWords']; triggerFieldGrouping: CliCommandDepsRuntimeOptions['mining']['triggerFieldGrouping']; triggerSubsyncFromConfig: CliCommandDepsRuntimeOptions['mining']['triggerSubsyncFromConfig']; markLastCardAsAudioCard: CliCommandDepsRuntimeOptions['mining']['markLastCardAsAudioCard']; }; anilist: { getStatus: CliCommandDepsRuntimeOptions['anilist']['getStatus']; clearToken: CliCommandDepsRuntimeOptions['anilist']['clearToken']; openSetup: CliCommandDepsRuntimeOptions['anilist']['openSetup']; getQueueStatus: CliCommandDepsRuntimeOptions['anilist']['getQueueStatus']; retryQueueNow: CliCommandDepsRuntimeOptions['anilist']['retryQueueNow']; }; jellyfin: { openSetup: CliCommandDepsRuntimeOptions['jellyfin']['openSetup']; runCommand: CliCommandDepsRuntimeOptions['jellyfin']['runCommand']; }; ui: { openYomitanSettings: CliCommandDepsRuntimeOptions['ui']['openYomitanSettings']; cycleSecondarySubMode: CliCommandDepsRuntimeOptions['ui']['cycleSecondarySubMode']; openRuntimeOptionsPalette: CliCommandDepsRuntimeOptions['ui']['openRuntimeOptionsPalette']; printHelp: CliCommandDepsRuntimeOptions['ui']['printHelp']; }; app: { stop: CliCommandDepsRuntimeOptions['app']['stop']; hasMainWindow: CliCommandDepsRuntimeOptions['app']['hasMainWindow']; }; getMultiCopyTimeoutMs: CliCommandDepsRuntimeOptions['getMultiCopyTimeoutMs']; schedule: CliCommandDepsRuntimeOptions['schedule']; log: CliCommandDepsRuntimeOptions['log']; warn: CliCommandDepsRuntimeOptions['warn']; error: CliCommandDepsRuntimeOptions['error']; } export interface MpvCommandRuntimeServiceDepsParams { specialCommands: HandleMpvCommandFromIpcOptions['specialCommands']; runtimeOptionsCycle: HandleMpvCommandFromIpcOptions['runtimeOptionsCycle']; triggerSubsyncFromConfig: HandleMpvCommandFromIpcOptions['triggerSubsyncFromConfig']; openRuntimeOptionsPalette: HandleMpvCommandFromIpcOptions['openRuntimeOptionsPalette']; showMpvOsd: HandleMpvCommandFromIpcOptions['showMpvOsd']; mpvReplaySubtitle: HandleMpvCommandFromIpcOptions['mpvReplaySubtitle']; mpvPlayNextSubtitle: HandleMpvCommandFromIpcOptions['mpvPlayNextSubtitle']; shiftSubDelayToAdjacentSubtitle: HandleMpvCommandFromIpcOptions['shiftSubDelayToAdjacentSubtitle']; mpvSendCommand: HandleMpvCommandFromIpcOptions['mpvSendCommand']; isMpvConnected: HandleMpvCommandFromIpcOptions['isMpvConnected']; hasRuntimeOptionsManager: HandleMpvCommandFromIpcOptions['hasRuntimeOptionsManager']; } export function createMainIpcRuntimeServiceDeps( params: MainIpcRuntimeServiceDepsParams, ): IpcDepsRuntimeOptions { return { getMainWindow: params.getMainWindow, getVisibleOverlayVisibility: params.getVisibleOverlayVisibility, onOverlayModalClosed: params.onOverlayModalClosed, onOverlayModalOpened: params.onOverlayModalOpened, openYomitanSettings: params.openYomitanSettings, quitApp: params.quitApp, toggleVisibleOverlay: params.toggleVisibleOverlay, tokenizeCurrentSubtitle: params.tokenizeCurrentSubtitle, getCurrentSubtitleRaw: params.getCurrentSubtitleRaw, getCurrentSubtitleAss: params.getCurrentSubtitleAss, getPlaybackPaused: params.getPlaybackPaused, getSubtitlePosition: params.getSubtitlePosition, getSubtitleStyle: params.getSubtitleStyle, saveSubtitlePosition: params.saveSubtitlePosition, getMecabTokenizer: params.getMecabTokenizer, handleMpvCommand: params.handleMpvCommand, getKeybindings: params.getKeybindings, getConfiguredShortcuts: params.getConfiguredShortcuts, focusMainWindow: params.focusMainWindow ?? (() => {}), getSecondarySubMode: params.getSecondarySubMode, getMpvClient: params.getMpvClient, runSubsyncManual: params.runSubsyncManual, getAnkiConnectStatus: params.getAnkiConnectStatus, getRuntimeOptions: params.getRuntimeOptions, setRuntimeOption: params.setRuntimeOption, cycleRuntimeOption: params.cycleRuntimeOption, reportOverlayContentBounds: params.reportOverlayContentBounds, getAnilistStatus: params.getAnilistStatus, clearAnilistToken: params.clearAnilistToken, openAnilistSetup: params.openAnilistSetup, getAnilistQueueStatus: params.getAnilistQueueStatus, retryAnilistQueueNow: params.retryAnilistQueueNow, appendClipboardVideoToQueue: params.appendClipboardVideoToQueue, }; } export function createAnkiJimakuIpcRuntimeServiceDeps( params: AnkiJimakuIpcRuntimeServiceDepsParams, ): AnkiJimakuIpcRuntimeOptions { return { patchAnkiConnectEnabled: params.patchAnkiConnectEnabled, getResolvedConfig: params.getResolvedConfig, getRuntimeOptionsManager: params.getRuntimeOptionsManager, getSubtitleTimingTracker: params.getSubtitleTimingTracker, getMpvClient: params.getMpvClient, getAnkiIntegration: params.getAnkiIntegration, setAnkiIntegration: params.setAnkiIntegration, getKnownWordCacheStatePath: params.getKnownWordCacheStatePath, showDesktopNotification: params.showDesktopNotification, createFieldGroupingCallback: params.createFieldGroupingCallback, broadcastRuntimeOptionsChanged: params.broadcastRuntimeOptionsChanged, getFieldGroupingResolver: params.getFieldGroupingResolver, setFieldGroupingResolver: params.setFieldGroupingResolver, parseMediaInfo: params.parseMediaInfo, getCurrentMediaPath: params.getCurrentMediaPath, jimakuFetchJson: params.jimakuFetchJson, getJimakuMaxEntryResults: params.getJimakuMaxEntryResults, getJimakuLanguagePreference: params.getJimakuLanguagePreference, resolveJimakuApiKey: params.resolveJimakuApiKey, isRemoteMediaPath: params.isRemoteMediaPath, downloadToFile: params.downloadToFile, }; } export function createCliCommandRuntimeServiceDeps( params: CliCommandRuntimeServiceDepsParams, ): CliCommandDepsRuntimeOptions { return { setLogLevel: params.setLogLevel, mpv: { getSocketPath: params.mpv.getSocketPath, setSocketPath: params.mpv.setSocketPath, getClient: params.mpv.getClient, showOsd: params.mpv.showOsd, }, texthooker: { service: params.texthooker.service, getPort: params.texthooker.getPort, setPort: params.texthooker.setPort, shouldOpenBrowser: params.texthooker.shouldOpenBrowser, openInBrowser: params.texthooker.openInBrowser, }, overlay: { isInitialized: params.overlay.isInitialized, initialize: params.overlay.initialize, toggleVisible: params.overlay.toggleVisible, setVisible: params.overlay.setVisible, }, mining: { copyCurrentSubtitle: params.mining.copyCurrentSubtitle, startPendingMultiCopy: params.mining.startPendingMultiCopy, mineSentenceCard: params.mining.mineSentenceCard, startPendingMineSentenceMultiple: params.mining.startPendingMineSentenceMultiple, updateLastCardFromClipboard: params.mining.updateLastCardFromClipboard, refreshKnownWords: params.mining.refreshKnownWords, triggerFieldGrouping: params.mining.triggerFieldGrouping, triggerSubsyncFromConfig: params.mining.triggerSubsyncFromConfig, markLastCardAsAudioCard: params.mining.markLastCardAsAudioCard, }, anilist: { getStatus: params.anilist.getStatus, clearToken: params.anilist.clearToken, openSetup: params.anilist.openSetup, getQueueStatus: params.anilist.getQueueStatus, retryQueueNow: params.anilist.retryQueueNow, }, jellyfin: { openSetup: params.jellyfin.openSetup, runCommand: params.jellyfin.runCommand, }, ui: { openYomitanSettings: params.ui.openYomitanSettings, cycleSecondarySubMode: params.ui.cycleSecondarySubMode, openRuntimeOptionsPalette: params.ui.openRuntimeOptionsPalette, printHelp: params.ui.printHelp, }, app: { stop: params.app.stop, hasMainWindow: params.app.hasMainWindow, }, getMultiCopyTimeoutMs: params.getMultiCopyTimeoutMs, schedule: params.schedule, log: params.log, warn: params.warn, error: params.error, }; } export function createMpvCommandRuntimeServiceDeps( params: MpvCommandRuntimeServiceDepsParams, ): HandleMpvCommandFromIpcOptions { return { specialCommands: params.specialCommands, triggerSubsyncFromConfig: params.triggerSubsyncFromConfig, openRuntimeOptionsPalette: params.openRuntimeOptionsPalette, runtimeOptionsCycle: params.runtimeOptionsCycle, showMpvOsd: params.showMpvOsd, mpvReplaySubtitle: params.mpvReplaySubtitle, mpvPlayNextSubtitle: params.mpvPlayNextSubtitle, shiftSubDelayToAdjacentSubtitle: params.shiftSubDelayToAdjacentSubtitle, mpvSendCommand: params.mpvSendCommand, isMpvConnected: params.isMpvConnected, hasRuntimeOptionsManager: params.hasRuntimeOptionsManager, }; }