feat: replace y-j with configurable Jimaku shortcut

This commit is contained in:
2026-02-09 21:28:56 -08:00
parent 31d90b0296
commit 5c600b0cbe
15 changed files with 276 additions and 12 deletions

View File

@@ -43,7 +43,8 @@ test("parses invisible overlay config and new global shortcuts", () => {
`{
"shortcuts": {
"toggleVisibleOverlayGlobal": "Alt+Shift+U",
"toggleInvisibleOverlayGlobal": "Alt+Shift+I"
"toggleInvisibleOverlayGlobal": "Alt+Shift+I",
"openJimaku": "Ctrl+Alt+J"
},
"invisibleOverlay": {
"startupVisibility": "hidden"
@@ -60,6 +61,7 @@ test("parses invisible overlay config and new global shortcuts", () => {
const config = service.getConfig();
assert.equal(config.shortcuts.toggleVisibleOverlayGlobal, "Alt+Shift+U");
assert.equal(config.shortcuts.toggleInvisibleOverlayGlobal, "Alt+Shift+I");
assert.equal(config.shortcuts.openJimaku, "Ctrl+Alt+J");
assert.equal(config.invisibleOverlay.startupVisibility, "hidden");
assert.equal(config.bind_visible_overlay_to_mpv_sub_visibility, false);
assert.deepEqual(config.youtubeSubgen.primarySubLanguages, ["ja", "jpn", "jp"]);

View File

@@ -152,6 +152,7 @@ export const DEFAULT_CONFIG: ResolvedConfig = {
toggleSecondarySub: "CommandOrControl+Shift+V",
markAudioCard: "CommandOrControl+Shift+A",
openRuntimeOptions: "CommandOrControl+Shift+O",
openJimaku: "Ctrl+Alt+J",
},
secondarySub: {
secondarySubLanguages: [],

View File

@@ -214,6 +214,7 @@ export class ConfigService {
"toggleSecondarySub",
"markAudioCard",
"openRuntimeOptions",
"openJimaku",
] as const;
for (const key of shortcutKeys) {

View File

@@ -2,6 +2,7 @@ import { ConfiguredShortcuts } from "../utils/shortcut-config";
export interface OverlayShortcutFallbackHandlers {
openRuntimeOptions: () => void;
openJimaku: () => void;
markAudioCard: () => void;
copySubtitleMultiple: (timeoutMs: number) => void;
copySubtitle: () => void;
@@ -34,6 +35,12 @@ export function runOverlayShortcutLocalFallback(
handlers.openRuntimeOptions();
},
},
{
accelerator: shortcuts.openJimaku,
run: () => {
handlers.openJimaku();
},
},
{
accelerator: shortcuts.markAudioCard,
run: () => {

View File

@@ -13,6 +13,7 @@ export interface OverlayShortcutHandlers {
toggleSecondarySub: () => void;
markAudioCard: () => void;
openRuntimeOptions: () => void;
openJimaku: () => void;
}
export function registerOverlayShortcutsService(
@@ -118,6 +119,13 @@ export function registerOverlayShortcutsService(
"openRuntimeOptions",
);
}
if (shortcuts.openJimaku) {
registerOverlayShortcut(
shortcuts.openJimaku,
() => handlers.openJimaku(),
"openJimaku",
);
}
return registeredAny;
}
@@ -155,4 +163,7 @@ export function unregisterOverlayShortcutsService(
if (shortcuts.openRuntimeOptions) {
globalShortcut.unregister(shortcuts.openRuntimeOptions);
}
if (shortcuts.openJimaku) {
globalShortcut.unregister(shortcuts.openJimaku);
}
}

View File

@@ -14,6 +14,7 @@ export interface ConfiguredShortcuts {
toggleSecondarySub: string | null | undefined;
markAudioCard: string | null | undefined;
openRuntimeOptions: string | null | undefined;
openJimaku: string | null | undefined;
}
export function resolveConfiguredShortcuts(
@@ -78,5 +79,8 @@ export function resolveConfiguredShortcuts(
config.shortcuts?.openRuntimeOptions ??
defaultConfig.shortcuts?.openRuntimeOptions,
),
openJimaku: normalizeShortcut(
config.shortcuts?.openJimaku ?? defaultConfig.shortcuts?.openJimaku,
),
};
}

View File

@@ -2265,6 +2265,9 @@ function tryHandleOverlayShortcutLocalFallback(input: Electron.Input): boolean {
openRuntimeOptions: () => {
openRuntimeOptionsPalette();
},
openJimaku: () => {
sendToVisibleOverlay("jimaku:open");
},
markAudioCard: () => {
markLastCardAsAudioCard().catch((err) => {
console.error("markLastCardAsAudioCard failed:", err);
@@ -2644,6 +2647,9 @@ function registerOverlayShortcuts(): void {
openRuntimeOptions: () => {
openRuntimeOptionsPalette();
},
openJimaku: () => {
sendToVisibleOverlay("jimaku:open");
},
});
}

View File

@@ -259,6 +259,11 @@ const electronAPI: ElectronAPI = {
callback();
});
},
onOpenJimaku: (callback: () => void) => {
ipcRenderer.on("jimaku:open", () => {
callback();
});
},
notifyOverlayModalClosed: (modal: "runtime-options" | "subsync") => {
ipcRenderer.send("overlay:modal-closed", modal);
},

View File

@@ -1953,7 +1953,6 @@ const CHORD_MAP = new Map<string, ChordAction>([
["KeyR", { type: "mpv", command: ["script-message", "subminer-restart"] }],
["KeyC", { type: "mpv", command: ["script-message", "subminer-status"] }],
["KeyY", { type: "mpv", command: ["script-message", "subminer-menu"] }],
["KeyJ", { type: "electron", action: () => openJimakuModal() }],
[
"KeyD",
{ type: "electron", action: () => window.electronAPI.toggleDevTools() },
@@ -2398,6 +2397,9 @@ async function init(): Promise<void> {
window.electronAPI.notifyOverlayModalClosed("runtime-options");
});
});
window.electronAPI.onOpenJimaku(() => {
openJimakuModal();
});
window.electronAPI.onSubsyncManualOpen((payload: SubsyncManualPayload) => {
openSubsyncModal(payload);
});

View File

@@ -275,6 +275,7 @@ export interface ShortcutsConfig {
toggleSecondarySub?: string | null;
markAudioCard?: string | null;
openRuntimeOptions?: string | null;
openJimaku?: string | null;
}
export type JimakuLanguagePreference = "ja" | "en" | "none";
@@ -606,6 +607,7 @@ export interface ElectronAPI {
callback: (options: RuntimeOptionState[]) => void,
) => void;
onOpenRuntimeOptions: (callback: () => void) => void;
onOpenJimaku: (callback: () => void) => void;
notifyOverlayModalClosed: (modal: "runtime-options" | "subsync") => void;
}