refactor(tsukihime): swap Animetosho backend for TsukiHime API (#165)

This commit is contained in:
2026-07-13 22:03:35 -07:00
committed by GitHub
parent 49b926e08c
commit 2e2ee3f028
90 changed files with 2253 additions and 1695 deletions
+2 -2
View File
@@ -229,7 +229,7 @@ export interface MpvCommandRuntimeServiceDepsParams {
triggerSubsyncFromConfig: HandleMpvCommandFromIpcOptions['triggerSubsyncFromConfig'];
openRuntimeOptionsPalette: HandleMpvCommandFromIpcOptions['openRuntimeOptionsPalette'];
openJimaku: HandleMpvCommandFromIpcOptions['openJimaku'];
openAnimetosho: HandleMpvCommandFromIpcOptions['openAnimetosho'];
openTsukihime: HandleMpvCommandFromIpcOptions['openTsukihime'];
openYoutubeTrackPicker: HandleMpvCommandFromIpcOptions['openYoutubeTrackPicker'];
openPlaylistBrowser: HandleMpvCommandFromIpcOptions['openPlaylistBrowser'];
showMpvOsd: HandleMpvCommandFromIpcOptions['showMpvOsd'];
@@ -437,7 +437,7 @@ export function createMpvCommandRuntimeServiceDeps(
triggerSubsyncFromConfig: params.triggerSubsyncFromConfig,
openRuntimeOptionsPalette: params.openRuntimeOptionsPalette,
openJimaku: params.openJimaku,
openAnimetosho: params.openAnimetosho,
openTsukihime: params.openTsukihime,
openYoutubeTrackPicker: params.openYoutubeTrackPicker,
openPlaylistBrowser: params.openPlaylistBrowser,
runtimeOptionsCycle: params.runtimeOptionsCycle,
+2 -2
View File
@@ -13,7 +13,7 @@ export interface MpvCommandFromIpcRuntimeDeps {
triggerSubsyncFromConfig: () => void;
openRuntimeOptionsPalette: () => void;
openJimaku: () => void;
openAnimetosho: () => void;
openTsukihime: () => void;
openYoutubeTrackPicker: () => void | Promise<void>;
openPlaylistBrowser: () => void | Promise<void>;
cycleRuntimeOption: (id: RuntimeOptionId, direction: 1 | -1) => RuntimeOptionApplyResult;
@@ -39,7 +39,7 @@ export function handleMpvCommandFromIpcRuntime(
triggerSubsyncFromConfig: deps.triggerSubsyncFromConfig,
openRuntimeOptionsPalette: deps.openRuntimeOptionsPalette,
openJimaku: deps.openJimaku,
openAnimetosho: deps.openAnimetosho,
openTsukihime: deps.openTsukihime,
openYoutubeTrackPicker: deps.openYoutubeTrackPicker,
openPlaylistBrowser: deps.openPlaylistBrowser,
runtimeOptionsCycle: deps.cycleRuntimeOption,
+5 -5
View File
@@ -49,7 +49,7 @@ export interface OverlayModalRuntime {
) => boolean;
openRuntimeOptionsPalette: () => void;
openJimaku: () => void;
openAnimetosho: () => void;
openTsukihime: () => void;
handleOverlayModalClosed: (modal: OverlayHostedModal) => void;
notifyOverlayModalOpened: (modal: OverlayHostedModal) => void;
waitForModalOpen: (modal: OverlayHostedModal, timeoutMs: number) => Promise<boolean>;
@@ -433,9 +433,9 @@ export function createOverlayModalRuntimeService(
});
};
const openAnimetosho = (): void => {
sendToActiveOverlayWindow('animetosho:open', undefined, {
restoreOnModalClose: 'animetosho',
const openTsukihime = (): void => {
sendToActiveOverlayWindow('tsukihime:open', undefined, {
restoreOnModalClose: 'tsukihime',
});
};
@@ -518,7 +518,7 @@ export function createOverlayModalRuntimeService(
sendToActiveOverlayWindow,
openRuntimeOptionsPalette,
openJimaku,
openAnimetosho,
openTsukihime,
handleOverlayModalClosed,
notifyOverlayModalOpened,
waitForModalOpen,
+3 -3
View File
@@ -21,7 +21,7 @@ export interface OverlayShortcutRuntimeServiceInput {
openRuntimeOptionsPalette: () => void;
openCharacterDictionaryManager: () => void;
openJimaku: () => void;
openAnimetosho: () => void;
openTsukihime: () => void;
markAudioCard: () => Promise<void>;
copySubtitleMultiple: (timeoutMs: number) => void;
copySubtitle: () => void;
@@ -57,8 +57,8 @@ export function createOverlayShortcutsRuntimeService(
openJimaku: () => {
input.openJimaku();
},
openAnimetosho: () => {
input.openAnimetosho();
openTsukihime: () => {
input.openTsukihime();
},
markAudioCard: () => {
return input.markAudioCard();
@@ -11,7 +11,7 @@ test('composeIpcRuntimeHandlers returns callable IPC handlers and registration b
triggerSubsyncFromConfig: async () => {},
openRuntimeOptionsPalette: () => {},
openJimaku: () => {},
openAnimetosho: () => {},
openTsukihime: () => {},
openYoutubeTrackPicker: () => {},
openPlaylistBrowser: () => {},
cycleRuntimeOption: () => ({ ok: true }),
@@ -55,7 +55,7 @@ function makeArgs(overrides: Partial<CliArgs> = {}): CliArgs {
openControllerSelect: false,
openControllerDebug: false,
openJimaku: false,
openAnimetosho: false,
openTsukihime: false,
openYoutubePicker: false,
openPlaylistBrowser: false,
replayCurrentSubtitle: false,
+1 -1
View File
@@ -97,7 +97,7 @@ function hasAnyStartupCommandBeyondSetup(args: CliArgs): boolean {
args.openControllerSelect ||
args.openControllerDebug ||
args.openJimaku ||
args.openAnimetosho ||
args.openTsukihime ||
args.openYoutubePicker ||
args.openPlaylistBrowser ||
args.replayCurrentSubtitle ||
@@ -19,7 +19,7 @@ function createShortcuts(): ConfiguredShortcuts {
openCharacterDictionaryManager: null,
openRuntimeOptions: null,
openJimaku: null,
openAnimetosho: null,
openTsukihime: null,
openSessionHelp: null,
openControllerSelect: null,
openControllerDebug: null,
+1 -1
View File
@@ -23,7 +23,7 @@ function createShortcuts(): ConfiguredShortcuts {
openCharacterDictionaryManager: null,
openRuntimeOptions: null,
openJimaku: null,
openAnimetosho: null,
openTsukihime: null,
openSessionHelp: null,
openControllerSelect: null,
openControllerDebug: null,
@@ -14,7 +14,7 @@ test('ipc bridge action main deps builders map callbacks', async () => {
triggerSubsyncFromConfig: async () => {},
openRuntimeOptionsPalette: () => {},
openJimaku: () => {},
openAnimetosho: () => {},
openTsukihime: () => {},
openYoutubeTrackPicker: () => {},
openPlaylistBrowser: () => {},
cycleRuntimeOption: () => ({ ok: false as const, error: 'x' }),
+1 -1
View File
@@ -11,7 +11,7 @@ test('handle mpv command handler forwards command and built deps', () => {
triggerSubsyncFromConfig: () => {},
openRuntimeOptionsPalette: () => {},
openJimaku: () => {},
openAnimetosho: () => {},
openTsukihime: () => {},
openYoutubeTrackPicker: () => {},
openPlaylistBrowser: () => {},
cycleRuntimeOption: () => ({ ok: false as const, error: 'x' }),
@@ -8,7 +8,7 @@ test('ipc mpv command main deps builder maps callbacks', () => {
triggerSubsyncFromConfig: () => calls.push('subsync'),
openRuntimeOptionsPalette: () => calls.push('palette'),
openJimaku: () => calls.push('jimaku'),
openAnimetosho: () => calls.push('animetosho'),
openTsukihime: () => calls.push('tsukihime'),
openYoutubeTrackPicker: () => {
calls.push('youtube-picker');
},
@@ -30,7 +30,7 @@ test('ipc mpv command main deps builder maps callbacks', () => {
deps.triggerSubsyncFromConfig();
deps.openRuntimeOptionsPalette();
deps.openJimaku();
deps.openAnimetosho();
deps.openTsukihime();
void deps.openYoutubeTrackPicker();
void deps.openPlaylistBrowser();
assert.deepEqual(deps.cycleRuntimeOption('anki.nPlusOneMatchMode', 1), { ok: false, error: 'x' });
@@ -47,7 +47,7 @@ test('ipc mpv command main deps builder maps callbacks', () => {
'subsync',
'palette',
'jimaku',
'animetosho',
'tsukihime',
'youtube-picker',
'playlist-browser',
'osd:hello',
@@ -10,7 +10,7 @@ export function createBuildMpvCommandFromIpcRuntimeMainDepsHandler(
triggerSubsyncFromConfig: () => deps.triggerSubsyncFromConfig(),
openRuntimeOptionsPalette: () => deps.openRuntimeOptionsPalette(),
openJimaku: () => deps.openJimaku(),
openAnimetosho: () => deps.openAnimetosho(),
openTsukihime: () => deps.openTsukihime(),
openYoutubeTrackPicker: () => deps.openYoutubeTrackPicker(),
openPlaylistBrowser: () => deps.openPlaylistBrowser(),
cycleRuntimeOption: (id, direction) => deps.cycleRuntimeOption(id, direction),
@@ -18,7 +18,7 @@ test('overlay shortcuts runtime main deps builder maps lifecycle and action call
openRuntimeOptionsPalette: () => calls.push('runtime-options'),
openCharacterDictionaryManager: () => calls.push('character-dictionary-manager'),
openJimaku: () => calls.push('jimaku'),
openAnimetosho: () => calls.push('animetosho'),
openTsukihime: () => calls.push('tsukihime'),
markAudioCard: async () => {
calls.push('mark-audio');
},
@@ -13,7 +13,7 @@ export function createBuildOverlayShortcutsRuntimeMainDepsHandler(
openRuntimeOptionsPalette: () => deps.openRuntimeOptionsPalette(),
openCharacterDictionaryManager: () => deps.openCharacterDictionaryManager(),
openJimaku: () => deps.openJimaku(),
openAnimetosho: () => deps.openAnimetosho(),
openTsukihime: () => deps.openTsukihime(),
markAudioCard: () => deps.markAudioCard(),
copySubtitleMultiple: (timeoutMs: number) => deps.copySubtitleMultiple(timeoutMs),
copySubtitle: () => deps.copySubtitle(),
@@ -2,10 +2,10 @@ import type { OverlayHostedModal } from '../../shared/ipc/contracts';
import { IPC_CHANNELS } from '../../shared/ipc/contracts';
import { openOverlayHostedModal, retryOverlayModalOpen } from './overlay-hosted-modal-open';
const ANIMETOSHO_MODAL: OverlayHostedModal = 'animetosho';
const ANIMETOSHO_OPEN_TIMEOUT_MS = 1500;
const TSUKIHIME_MODAL: OverlayHostedModal = 'tsukihime';
const TSUKIHIME_OPEN_TIMEOUT_MS = 1500;
export async function openAnimetoshoModal(deps: {
export async function openTsukihimeModal(deps: {
ensureOverlayStartupPrereqs: () => void;
ensureOverlayWindowsReadyForVisibilityActions: () => void;
sendToActiveOverlayWindow: (
@@ -25,10 +25,10 @@ export async function openAnimetoshoModal(deps: {
logWarn: deps.logWarn,
},
{
modal: ANIMETOSHO_MODAL,
timeoutMs: ANIMETOSHO_OPEN_TIMEOUT_MS,
modal: TSUKIHIME_MODAL,
timeoutMs: TSUKIHIME_OPEN_TIMEOUT_MS,
retryWarning:
'Animetosho modal did not acknowledge modal open on first attempt; retrying dedicated modal window.',
'Tsukihime modal did not acknowledge modal open on first attempt; retrying dedicated modal window.',
sendOpen: () =>
openOverlayHostedModal(
{
@@ -38,8 +38,8 @@ export async function openAnimetoshoModal(deps: {
sendToActiveOverlayWindow: deps.sendToActiveOverlayWindow,
},
{
channel: IPC_CHANNELS.event.animetoshoOpen,
modal: ANIMETOSHO_MODAL,
channel: IPC_CHANNELS.event.tsukihimeOpen,
modal: TSUKIHIME_MODAL,
preferModalWindow: true,
},
),