mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
feat: replace y-j with configurable Jimaku shortcut
This commit is contained in:
@@ -90,6 +90,7 @@ cp plugin/subminer.conf ~/.config/mpv/script-opts/
|
||||
Requires mpv IPC: `--input-ipc-server=/tmp/subminer-socket`
|
||||
|
||||
Default chord prefix: `y` (`y-y` menu, `y-s` start, `y-S` stop, `y-t` toggle visible layer).
|
||||
Overlay Jimaku shortcut default: `Ctrl+Alt+J` (`shortcuts.openJimaku`).
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Settings are stored in `~/.config/SubMiner/config.jsonc`
|
||||
|
||||
### Configuration File
|
||||
|
||||
See `config.example.jsonc` for a comprehensive example configuration file with all available options, default values, and detailed comments. Only include the options you want to customize in your config file.
|
||||
See [config.example.jsonc](/config.example.jsonc) for a comprehensive example configuration file with all available options, default values, and detailed comments. Only include the options you want to customize in your config file.
|
||||
|
||||
Generate a fresh default config from the centralized config registry:
|
||||
|
||||
@@ -17,7 +17,7 @@ subminer.AppImage --generate-config --backup-overwrite
|
||||
- `--generate-config` writes a default JSONC config template.
|
||||
- If the target file exists, SubMiner prompts to create a timestamped backup and overwrite.
|
||||
- In non-interactive shells, use `--backup-overwrite` to explicitly back up and overwrite.
|
||||
- `pnpm run generate:config-example` regenerates repository `config.example.jsonc` from the same centralized defaults.
|
||||
- `pnpm run generate:config-example` regenerates both repository `config.example.jsonc` and docs-served `/config.example.jsonc` from the same centralized defaults.
|
||||
- `make generate-config` builds and runs the same default-config generator via local Electron.
|
||||
|
||||
Invalid config values are handled with warn-and-fallback behavior: SubMiner logs the bad key/value and continues with the default for that option.
|
||||
@@ -164,7 +164,12 @@ When enabled, sentence cards automatically set `IsSentenceCard` to `"x"` and pop
|
||||
|
||||
Kiku extends Lapis with **field grouping** — when a duplicate card is detected (same Word/Expression), SubMiner merges the two cards' content into one using Kiku's `data-group-id` HTML structure, organizing each mining instance into separate pages within the note.
|
||||
|
||||
[](https://github.com/user-attachments/assets/bf2476cb-2351-4622-8143-c90e59b19213)
|
||||
<video controls playsinline preload="metadata" poster="/assets/kiku-integration-poster.jpg" style="width: 100%; max-width: 960px;">
|
||||
<source :src="'/assets/kiku-integration.webm'" type="video/webm" />
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
|
||||
<a :href="'/assets/kiku-integration.webm'" target="_blank" rel="noreferrer">Open demo in a new tab</a>
|
||||
|
||||
|
||||
| Mode | Behavior |
|
||||
@@ -416,6 +421,7 @@ See `config.example.jsonc` for detailed configuration options.
|
||||
"mineSentenceMultiple": "CommandOrControl+Shift+S",
|
||||
"markAudioCard": "CommandOrControl+Shift+A",
|
||||
"openRuntimeOptions": "CommandOrControl+Shift+O",
|
||||
"openJimaku": "Ctrl+Alt+J",
|
||||
"multiCopyTimeoutMs": 3000
|
||||
}
|
||||
}
|
||||
@@ -436,6 +442,7 @@ See `config.example.jsonc` for detailed configuration options.
|
||||
| `toggleSecondarySub` | string \| `null` | Accelerator for cycling secondary subtitle mode (default: `"CommandOrControl+Shift+V"`) |
|
||||
| `markAudioCard` | string \| `null` | Accelerator for marking last card as audio card (default: `"CommandOrControl+Shift+A"`) |
|
||||
| `openRuntimeOptions` | string \| `null` | Opens runtime options palette for live session-only toggles (default: `"CommandOrControl+Shift+O"`) |
|
||||
| `openJimaku` | string \| `null` | Opens the Jimaku search modal (default: `"Ctrl+Alt+J"`) |
|
||||
|
||||
**See `config.example.jsonc`** for the complete list of shortcut configuration options.
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
- Hyprland (uses `hyprctl`)
|
||||
- X11 (uses `xdotool` and `xwininfo`)
|
||||
- mpv (with IPC socket support)
|
||||
- mecab and mecab-ipadic (Japanese morphological analyzer)
|
||||
- mecab and mecab-ipadic (optional fallback Japanese morphological analyzer)
|
||||
- fuse2 (for AppImage support)
|
||||
|
||||
### macOS
|
||||
|
||||
- macOS 10.13 or later
|
||||
- mpv (with IPC socket support)
|
||||
- mecab and mecab-ipadic (Japanese morphological analyzer) - optional
|
||||
- mecab and mecab-ipadic (optional fallback Japanese morphological analyzer)
|
||||
- **Accessibility permission** required for window tracking (see [macOS Installation](#macos-installation))
|
||||
|
||||
**Optional:**
|
||||
@@ -154,8 +154,9 @@ binary_path=/Applications/SubMiner.app/Contents/MacOS/subminer
|
||||
|
||||
The Lua plugin allows you to control the overlay directly from mpv using keybindings:
|
||||
|
||||
> [!IMPORTANT]
|
||||
> `mpv` must be launched with `--input-ipc-server=/tmp/subminer-socket` to allow communication with the application
|
||||
::: warning Important
|
||||
`mpv` must be launched with `--input-ipc-server=/tmp/subminer-socket` to allow communication with the application.
|
||||
:::
|
||||
|
||||
```bash
|
||||
# Copy plugin files to mpv config
|
||||
@@ -182,6 +183,8 @@ All keybindings use chord sequences starting with `y`:
|
||||
|
||||
The menu provides options to start/stop/toggle the visible or invisible overlay layers and open settings. Type to filter or use arrow keys to navigate.
|
||||
|
||||
Jimaku modal shortcut is configured separately in SubMiner overlay shortcuts (`shortcuts.openJimaku`), default `Ctrl+Alt+J`.
|
||||
|
||||
#### Plugin Configuration
|
||||
|
||||
Edit `~/.config/mpv/script-opts/subminer.conf`:
|
||||
@@ -243,4 +246,3 @@ Launch mpv with:
|
||||
```bash
|
||||
mpv --input-ipc-server=\\\\.\\pipe\\subminer-socket video.mkv
|
||||
```
|
||||
|
||||
|
||||
211
docs/public/config.example.jsonc
Normal file
211
docs/public/config.example.jsonc
Normal file
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* SubMiner Example Configuration File
|
||||
*
|
||||
* This file is auto-generated from src/config/definitions.ts.
|
||||
* Copy to ~/.config/SubMiner/config.jsonc and edit as needed.
|
||||
*/
|
||||
{
|
||||
|
||||
// ==========================================
|
||||
// Overlay Auto-Start
|
||||
// When overlay connects to mpv, automatically show overlay and hide mpv subtitles.
|
||||
// ==========================================
|
||||
"auto_start_overlay": false,
|
||||
|
||||
// ==========================================
|
||||
// Visible Overlay Subtitle Binding
|
||||
// Control whether visible overlay toggles also toggle MPV subtitle visibility.
|
||||
// When enabled, visible overlay hides MPV subtitles; when disabled, MPV subtitles are left unchanged.
|
||||
// ==========================================
|
||||
"bind_visible_overlay_to_mpv_sub_visibility": true,
|
||||
|
||||
// ==========================================
|
||||
// Texthooker Server
|
||||
// Control whether browser opens automatically for texthooker.
|
||||
// ==========================================
|
||||
"texthooker": {
|
||||
"openBrowser": true
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// WebSocket Server
|
||||
// Built-in WebSocket server broadcasts subtitle text to connected clients.
|
||||
// Auto mode disables built-in server if mpv_websocket is detected.
|
||||
// ==========================================
|
||||
"websocket": {
|
||||
"enabled": "auto",
|
||||
"port": 6677
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// AnkiConnect Integration
|
||||
// Automatic Anki updates and media generation options.
|
||||
// ==========================================
|
||||
"ankiConnect": {
|
||||
"enabled": false,
|
||||
"url": "http://127.0.0.1:8765",
|
||||
"pollingRate": 3000,
|
||||
"fields": {
|
||||
"audio": "ExpressionAudio",
|
||||
"image": "Picture",
|
||||
"sentence": "Sentence",
|
||||
"miscInfo": "MiscInfo",
|
||||
"translation": "SelectionText"
|
||||
},
|
||||
"ai": {
|
||||
"enabled": false,
|
||||
"alwaysUseAiTranslation": false,
|
||||
"apiKey": "",
|
||||
"model": "openai/gpt-4o-mini",
|
||||
"baseUrl": "https://openrouter.ai/api",
|
||||
"targetLanguage": "English",
|
||||
"systemPrompt": "You are a translation engine. Return only the translated text with no explanations."
|
||||
},
|
||||
"media": {
|
||||
"generateAudio": true,
|
||||
"generateImage": true,
|
||||
"imageType": "static",
|
||||
"imageFormat": "jpg",
|
||||
"imageQuality": 92,
|
||||
"animatedFps": 10,
|
||||
"animatedMaxWidth": 640,
|
||||
"animatedCrf": 35,
|
||||
"audioPadding": 0.5,
|
||||
"fallbackDuration": 3,
|
||||
"maxMediaDuration": 30
|
||||
},
|
||||
"behavior": {
|
||||
"overwriteAudio": true,
|
||||
"overwriteImage": true,
|
||||
"mediaInsertMode": "append",
|
||||
"highlightWord": true,
|
||||
"notificationType": "osd",
|
||||
"autoUpdateNewCards": true
|
||||
},
|
||||
"metadata": {
|
||||
"pattern": "[SubMiner] %f (%t)"
|
||||
},
|
||||
"isLapis": {
|
||||
"enabled": false,
|
||||
"sentenceCardModel": "Japanese sentences",
|
||||
"sentenceCardSentenceField": "Sentence",
|
||||
"sentenceCardAudioField": "SentenceAudio"
|
||||
},
|
||||
"isKiku": {
|
||||
"enabled": false,
|
||||
"fieldGrouping": "disabled",
|
||||
"deleteDuplicateInAuto": true
|
||||
}
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// Keyboard Shortcuts
|
||||
// Overlay keyboard shortcuts. Set a shortcut to null to disable.
|
||||
// ==========================================
|
||||
"shortcuts": {
|
||||
"toggleVisibleOverlayGlobal": "Alt+Shift+O",
|
||||
"toggleInvisibleOverlayGlobal": "Alt+Shift+I",
|
||||
"copySubtitle": "CommandOrControl+C",
|
||||
"copySubtitleMultiple": "CommandOrControl+Shift+C",
|
||||
"updateLastCardFromClipboard": "CommandOrControl+V",
|
||||
"triggerFieldGrouping": "CommandOrControl+G",
|
||||
"triggerSubsync": "Ctrl+Alt+S",
|
||||
"mineSentence": "CommandOrControl+S",
|
||||
"mineSentenceMultiple": "CommandOrControl+Shift+S",
|
||||
"multiCopyTimeoutMs": 3000,
|
||||
"toggleSecondarySub": "CommandOrControl+Shift+V",
|
||||
"markAudioCard": "CommandOrControl+Shift+A",
|
||||
"openRuntimeOptions": "CommandOrControl+Shift+O",
|
||||
"openJimaku": "Ctrl+Alt+J"
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// Invisible Overlay
|
||||
// Startup behavior for the invisible interactive subtitle mining layer.
|
||||
// ==========================================
|
||||
"invisibleOverlay": {
|
||||
"startupVisibility": "platform-default"
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// Keybindings (MPV Commands)
|
||||
// Extra keybindings that are merged with built-in defaults.
|
||||
// Set command to null to disable a default keybinding.
|
||||
// ==========================================
|
||||
"keybindings": [],
|
||||
|
||||
// ==========================================
|
||||
// Subtitle Appearance
|
||||
// Primary and secondary subtitle styling.
|
||||
// ==========================================
|
||||
"subtitleStyle": {
|
||||
"fontFamily": "Noto Sans CJK JP Regular, Noto Sans CJK JP, Arial Unicode MS, Arial, sans-serif",
|
||||
"fontSize": 35,
|
||||
"fontColor": "#cad3f5",
|
||||
"fontWeight": "normal",
|
||||
"fontStyle": "normal",
|
||||
"backgroundColor": "rgba(54, 58, 79, 0.5)",
|
||||
"secondary": {
|
||||
"fontSize": 24,
|
||||
"fontColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fontWeight": "normal",
|
||||
"fontStyle": "normal",
|
||||
"fontFamily": "Noto Sans CJK JP Regular, Noto Sans CJK JP, Arial Unicode MS, Arial, sans-serif"
|
||||
}
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// Secondary Subtitles
|
||||
// Dual subtitle track options.
|
||||
// Used by subminer YouTube subtitle generation as secondary language preferences.
|
||||
// ==========================================
|
||||
"secondarySub": {
|
||||
"secondarySubLanguages": [],
|
||||
"autoLoadSecondarySub": false,
|
||||
"defaultMode": "hover"
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// Auto Subtitle Sync
|
||||
// Subsync engine and executable paths.
|
||||
// ==========================================
|
||||
"subsync": {
|
||||
"defaultMode": "auto",
|
||||
"alass_path": "",
|
||||
"ffsubsync_path": "",
|
||||
"ffmpeg_path": ""
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// Subtitle Position
|
||||
// Initial vertical subtitle position from the bottom.
|
||||
// ==========================================
|
||||
"subtitlePosition": {
|
||||
"yPercent": 10
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// Jimaku
|
||||
// Jimaku API configuration and defaults.
|
||||
// ==========================================
|
||||
"jimaku": {
|
||||
"apiBaseUrl": "https://jimaku.cc",
|
||||
"languagePreference": "ja",
|
||||
"maxEntryResults": 10
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// YouTube Subtitle Generation
|
||||
// Defaults for subminer YouTube subtitle extraction/transcription mode.
|
||||
// ==========================================
|
||||
"youtubeSubgen": {
|
||||
"mode": "automatic",
|
||||
"whisperBin": "",
|
||||
"whisperModel": "",
|
||||
"primarySubLanguages": [
|
||||
"ja",
|
||||
"jpn"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ There are two ways to use SubMiner:
|
||||
| **subminer script** | All-in-one solution. Handles video selection, launches MPV with the correct socket, starts the overlay automatically, and cleans up on exit. |
|
||||
| **MPV plugin** | When you launch MPV yourself or from other tools. Provides in-MPV chord keybindings (e.g. `y-y` for menu) to control visible and invisible overlay layers. Requires `--input-ipc-server=/tmp/subminer-socket`. |
|
||||
|
||||
Jimaku modal shortcut is an overlay shortcut, not an MPV plugin chord: default `Ctrl+Alt+J` via `shortcuts.openJimaku`.
|
||||
|
||||
You can use both together—install the plugin for on-demand control, but use `subminer` when you want the streamlined workflow.
|
||||
|
||||
`subminer` is implemented as a Bun script and runs directly via shebang (no `bun run` needed), for example: `subminer video.mkv`.
|
||||
@@ -113,7 +115,7 @@ Notes:
|
||||
| `Right-click` | Toggle MPV pause (outside subtitle area) |
|
||||
| `Right-click + drag` | Move subtitle position (on subtitle) |
|
||||
|
||||
These keybindings only work when the overlay window has focus. See [Configuration](configuration.md) for customization.
|
||||
These keybindings only work when the overlay window has focus. See [Configuration](/configuration) for customization.
|
||||
|
||||
### Overlay Chord Shortcuts
|
||||
|
||||
@@ -125,7 +127,7 @@ These keybindings only work when the overlay window has focus. See [Configuratio
|
||||
|
||||
1. MPV runs with an IPC socket at `/tmp/subminer-socket`
|
||||
2. The overlay connects and subscribes to subtitle changes
|
||||
3. Subtitles are tokenized with MeCab and merged into natural word boundaries
|
||||
3. Subtitles are tokenized with Yomitan's internal parser, with MeCab fallback when needed
|
||||
4. Words are displayed as clickable spans
|
||||
5. Clicking a word triggers Yomitan popup for dictionary lookup
|
||||
6. Texthooker server runs at `http://127.0.0.1:5174` for external tools
|
||||
|
||||
@@ -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"]);
|
||||
|
||||
@@ -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: [],
|
||||
|
||||
@@ -214,6 +214,7 @@ export class ConfigService {
|
||||
"toggleSecondarySub",
|
||||
"markAudioCard",
|
||||
"openRuntimeOptions",
|
||||
"openJimaku",
|
||||
] as const;
|
||||
|
||||
for (const key of shortcutKeys) {
|
||||
|
||||
@@ -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: () => {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user