diff --git a/README.md b/README.md index 6cfe9c8e..b2a5f535 100644 --- a/README.md +++ b/README.md @@ -243,7 +243,14 @@ See the [build-from-source guide](https://docs.subminer.moe/installation#from-so ### 2. First Launch -Run the app. On first launch SubMiner starts in the system tray, creates a default config, and opens a setup popup to finish config, install the mpv plugin, and configure Yomitan dictionaries. +```bash +subminer app --setup # launch the first-run setup wizard +``` + +SubMiner creates a default config, starts in the system tray, and opens a setup popup that walks you through installing the mpv plugin and configuring Yomitan dictionaries. Follow the on-screen steps to complete setup. + +> [!NOTE] +> On Windows, run `SubMiner.exe` directly — it opens the setup wizard automatically on first launch. ### 3. Verify Setup diff --git a/docs-site/installation.md b/docs-site/installation.md index 6affaec6..82512c96 100644 --- a/docs-site/installation.md +++ b/docs-site/installation.md @@ -390,12 +390,39 @@ For enrichment configuration (sentence, audio, screenshot fields), see [Anki Int ## First-Run Setup -On first launch SubMiner creates a default config file automatically and opens a setup popup. You do **not** need to create the config manually — SubMiner handles it. +Run the setup wizard to create a default config and finish initial configuration. You do **not** need to create the config manually — SubMiner handles it. ```bash -# Play a file (default plugin config auto-starts visible overlay and waits for annotation readiness; first launch opens first-run setup popup) -subminer video.mkv +subminer app --setup +``` +> [!NOTE] +> On Windows, run `SubMiner.exe` directly — it opens the setup wizard automatically on first launch. + +The setup popup walks you through: + +- **Config file**: auto-created at `~/.config/SubMiner/config.jsonc` (Linux/macOS) or `%APPDATA%\SubMiner\config.jsonc` (Windows) +- **mpv plugin**: install the bundled Lua plugin for in-player keybindings +- **Yomitan dictionaries**: import at least one dictionary so lookups work +- **Windows shortcut** _(Windows only)_: optionally create a `SubMiner mpv` Start Menu/Desktop shortcut + +The `Finish setup` button stays disabled until the plugin is installed and at least one dictionary is imported. Once you finish, SubMiner will not show the popup again. + +> [!TIP] +> You can re-open the setup popup at any time with `subminer app --setup` or `SubMiner.AppImage --setup`. + +Once setup is complete, play a video to verify everything works: + +```bash +subminer video.mkv +``` + +You should see the overlay appear over mpv. If subtitles are loaded in the video, they will appear as interactive text in the overlay. + +
+More launch examples + +```bash # Optional explicit overlay start for setups with plugin auto_start=no subminer --start video.mkv @@ -410,19 +437,7 @@ SubMiner.AppImage --start --dev SubMiner.AppImage --help # Show all CLI options ``` -The setup popup walks you through: - -- **Config file**: auto-created at `~/.config/SubMiner/config.jsonc` (Linux/macOS) or `%APPDATA%\SubMiner\config.jsonc` (Windows) -- **mpv plugin**: install the bundled Lua plugin for in-player keybindings -- **Yomitan dictionaries**: import at least one dictionary so lookups work -- **Windows shortcut** _(Windows only)_: optionally create a `SubMiner mpv` Start Menu/Desktop shortcut - -The `Finish setup` button stays disabled until the plugin is installed and at least one dictionary is imported. Once you finish, SubMiner will not show the popup again. - -> [!TIP] -> You can re-open the setup popup at any time with `subminer --setup` or `SubMiner.AppImage --setup`. - -You should see the overlay appear over mpv. If subtitles are loaded in the video, they will appear as interactive text in the overlay. +
## Verify Setup diff --git a/src/main.ts b/src/main.ts index 628d9332..f8f0c8d4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2318,8 +2318,8 @@ const openFirstRunSetupWindowHandler = createOpenFirstRunSetupWindowHandler({ logError: (message, error) => logger.error(message, error), }); -function openFirstRunSetupWindow(): void { - if (firstRunSetupService.isSetupCompleted()) { +function openFirstRunSetupWindow(force = false): void { + if (!force && firstRunSetupService.isSetupCompleted()) { return; } openFirstRunSetupWindowHandler(); @@ -3238,12 +3238,12 @@ const { appReadyRuntimeRunner } = composeAppReadyRuntime({ handleFirstRunSetup: async () => { const snapshot = await firstRunSetupService.ensureSetupStateInitialized(); appState.firstRunSetupCompleted = snapshot.state.status === 'completed'; - if ( - appState.initialArgs && - shouldAutoOpenFirstRunSetup(appState.initialArgs) && - snapshot.state.status !== 'completed' - ) { - openFirstRunSetupWindow(); + const args = appState.initialArgs; + if (args && shouldAutoOpenFirstRunSetup(args)) { + const force = Boolean(args.setup); + if (force || snapshot.state.status !== 'completed') { + openFirstRunSetupWindow(force); + } } }, startJellyfinRemoteSession: async () => {