mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-13 08:12:54 -07:00
feat(config): update default startup and subtitle style options
- Disable texthooker, websocket, and annotationWebsocket servers by default - Update primary subtitle font family to include Hiragino Sans - Switch subtitle backgrounds to transparent for primary and secondary - Unify text shadow to stronger two-layer value for both subtitle tracks - Set JLPT N4 default color to #8bd5ca - Keep Yomitan popup auto-pause enabled and secondary font stack unchanged - Update tests, generated config examples, and docs-site to match
This commit is contained in:
@@ -0,0 +1,68 @@
|
|||||||
|
---
|
||||||
|
id: TASK-359
|
||||||
|
title: Update default startup and subtitle style options
|
||||||
|
status: Done
|
||||||
|
assignee:
|
||||||
|
- Codex
|
||||||
|
created_date: '2026-05-13 06:16'
|
||||||
|
updated_date: '2026-05-13 06:28'
|
||||||
|
labels:
|
||||||
|
- config
|
||||||
|
dependencies: []
|
||||||
|
priority: medium
|
||||||
|
---
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||||
|
Change fresh-install defaults so texthooker and associated subtitle websocket servers are disabled unless explicitly enabled, Yomitan popup auto-pause remains enabled by default, and primary/secondary subtitle style defaults match the requested font, transparent background, and stronger shadow. Keep generated example config and docs aligned with resolved defaults.
|
||||||
|
<!-- SECTION:DESCRIPTION:END -->
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
<!-- AC:BEGIN -->
|
||||||
|
- [x] #1 Fresh default config has texthooker startup disabled by default.
|
||||||
|
- [x] #2 Fresh default config disables associated subtitle websocket servers by default, or exposes/uses an existing config option that does so.
|
||||||
|
- [x] #3 Fresh default config keeps subtitleStyle.autoPauseVideoOnYomitanPopup enabled by default.
|
||||||
|
- [x] #4 Fresh default config uses fontFamily `Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP` for primary subtitles.
|
||||||
|
- [x] #5 Fresh default config keeps secondary subtitle fontFamily as `Inter, Noto Sans, Helvetica Neue, sans-serif`.
|
||||||
|
- [x] #6 Fresh default config uses textShadow `0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)` for primary and secondary subtitles.
|
||||||
|
- [x] #7 Fresh default config uses transparent subtitle backgrounds for primary and secondary subtitles.
|
||||||
|
- [x] #8 Tests and generated/docs config examples are updated for the new defaults.
|
||||||
|
- [x] #9 Fresh default config uses `#8bd5ca` for the fourth frequency band and JLPT N4 subtitle color.
|
||||||
|
<!-- AC:END -->
|
||||||
|
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
<!-- SECTION:PLAN:BEGIN -->
|
||||||
|
1. Update focused config tests first for the requested fresh-install defaults.
|
||||||
|
2. Change default config values in `src/config/definitions/defaults-core.ts` and `src/config/definitions/defaults-subtitle.ts`.
|
||||||
|
3. Regenerate generated config examples with the repo generator.
|
||||||
|
4. Update docs-site configuration prose/snippets for the new defaults.
|
||||||
|
5. Run focused config/example tests and mark acceptance criteria when verified.
|
||||||
|
|
||||||
|
6. Include the requested JLPT N4 default color adjustment and verify the existing fourth frequency band default remains `#8bd5ca`.
|
||||||
|
|
||||||
|
7. Restore the secondary subtitle font default to its previous `Inter, Noto Sans, Helvetica Neue, sans-serif` stack while keeping the new primary subtitle font default.
|
||||||
|
<!-- SECTION:PLAN:END -->
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
|
||||||
|
<!-- SECTION:NOTES:BEGIN -->
|
||||||
|
Context: existing config already has websocket.enabled (`true | false | "auto"`) and annotationWebsocket.enabled (`boolean`), so disabling associated websockets can be handled by default changes instead of adding a new config surface.
|
||||||
|
|
||||||
|
Scope update from user: also set JLPT N4 default color to `#8bd5ca`; fourth frequency band is already `#8bd5ca` in current defaults and has existing regression coverage.
|
||||||
|
|
||||||
|
Verification: `bun run test:config`, `bun run docs:test`, `bun run docs:build`, `bun run changelog:lint`, `bun run format:check:src`, `bun run typecheck`, `bun run build`, `bun run test:smoke:dist`, and `git diff --check` passed. Earlier full fast/env suites also passed during this task (`bun run test:fast`, `bun run test:env`) before the final N4-only default tweak; focused config/docs/build/smoke checks were rerun after that tweak.
|
||||||
|
|
||||||
|
Scope correction from user: secondary subtitles should keep the previous font stack. Interpreting the typo `snas-serif` as the previous literal default `sans-serif`.
|
||||||
|
|
||||||
|
Correction verification: restored secondary subtitle default font to `Inter, Noto Sans, Helvetica Neue, sans-serif`. Passed `bun run test:config`, `bun run docs:test`, `bun run changelog:lint`, `bun run format:check:src`, `bun run typecheck`, and `git diff --check`. Verified generated examples and docs contain the restored secondary font.
|
||||||
|
<!-- SECTION:NOTES:END -->
|
||||||
|
|
||||||
|
## Final Summary
|
||||||
|
|
||||||
|
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||||
|
Updated fresh-install defaults so texthooker startup, the regular subtitle websocket, and the annotation websocket are disabled by default while preserving Yomitan popup auto-pause. Updated primary subtitle defaults to the requested Japanese font stack, kept secondary subtitle font at the prior `Inter, Noto Sans, Helvetica Neue, sans-serif` stack, and applied shared stronger text shadow, transparent backgrounds, and teal N4/fourth-band color. Regenerated config examples, updated docs-site configuration docs, and added a changelog fragment.
|
||||||
|
|
||||||
|
Verification passed: `bun run test:config`, `bun run docs:test`, `bun run docs:build`, `bun run changelog:lint`, `bun run format:check:src`, `bun run typecheck`, `bun run build`, `bun run test:smoke:dist`, and `git diff --check`. After the secondary-font correction, reran `bun run test:config`, `bun run docs:test`, `bun run changelog:lint`, `bun run format:check:src`, `bun run typecheck`, and `git diff --check`. `bun run test:fast` and `bun run test:env` also passed during the task before the final small default corrections; affected focused checks were rerun afterward.
|
||||||
|
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
type: changed
|
||||||
|
area: config
|
||||||
|
|
||||||
|
- Config: Disabled texthooker startup plus subtitle and annotation websocket servers by default, while keeping Yomitan popup auto-pause enabled and updating fresh primary subtitle style defaults to a Japanese font stack, transparent subtitle backgrounds, stronger text shadows, and teal N4/fourth-band coloring.
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
// Configure texthooker startup launch and browser opening behavior.
|
// Configure texthooker startup launch and browser opening behavior.
|
||||||
// ==========================================
|
// ==========================================
|
||||||
"texthooker": {
|
"texthooker": {
|
||||||
"launchAtStartup": true, // Launch texthooker server automatically when SubMiner starts. Values: true | false
|
"launchAtStartup": false, // Launch texthooker server automatically when SubMiner starts. Values: true | false
|
||||||
"openBrowser": false // Open browser setting. Values: true | false
|
"openBrowser": false // Open browser setting. Values: true | false
|
||||||
}, // Configure texthooker startup launch and browser opening behavior.
|
}, // Configure texthooker startup launch and browser opening behavior.
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
// Auto mode disables built-in server if mpv_websocket is detected.
|
// Auto mode disables built-in server if mpv_websocket is detected.
|
||||||
// ==========================================
|
// ==========================================
|
||||||
"websocket": {
|
"websocket": {
|
||||||
"enabled": "auto", // Built-in subtitle websocket server mode. Values: auto | true | false
|
"enabled": false, // Built-in subtitle websocket server mode. Values: auto | true | false
|
||||||
"port": 6677 // Built-in subtitle websocket server port.
|
"port": 6677 // Built-in subtitle websocket server port.
|
||||||
}, // Built-in WebSocket server broadcasts subtitle text to connected clients.
|
}, // Built-in WebSocket server broadcasts subtitle text to connected clients.
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
// Independent from websocket.auto and defaults to port 6678.
|
// Independent from websocket.auto and defaults to port 6678.
|
||||||
// ==========================================
|
// ==========================================
|
||||||
"annotationWebsocket": {
|
"annotationWebsocket": {
|
||||||
"enabled": true, // Annotated subtitle websocket server enabled state. Values: true | false
|
"enabled": false, // Annotated subtitle websocket server enabled state. Values: true | false
|
||||||
"port": 6678 // Annotated subtitle websocket server port.
|
"port": 6678 // Annotated subtitle websocket server port.
|
||||||
}, // Dedicated annotated subtitle websocket for bundled texthooker and token-aware clients.
|
}, // Dedicated annotated subtitle websocket for bundled texthooker and token-aware clients.
|
||||||
|
|
||||||
@@ -355,7 +355,7 @@
|
|||||||
"hoverTokenBackgroundColor": "rgba(54, 58, 79, 0.84)", // CSS color used for hovered subtitle token background highlight in mpv.
|
"hoverTokenBackgroundColor": "rgba(54, 58, 79, 0.84)", // CSS color used for hovered subtitle token background highlight in mpv.
|
||||||
"nameMatchEnabled": true, // Enable subtitle token coloring for matches from the SubMiner character dictionary. Values: true | false
|
"nameMatchEnabled": true, // Enable subtitle token coloring for matches from the SubMiner character dictionary. Values: true | false
|
||||||
"nameMatchColor": "#f5bde6", // Hex color used when a subtitle token matches an entry from the SubMiner character dictionary.
|
"nameMatchColor": "#f5bde6", // Hex color used when a subtitle token matches an entry from the SubMiner character dictionary.
|
||||||
"fontFamily": "M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP", // Font family setting.
|
"fontFamily": "Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP", // Font family setting.
|
||||||
"fontSize": 35, // Font size setting.
|
"fontSize": 35, // Font size setting.
|
||||||
"fontColor": "#cad3f5", // Font color setting.
|
"fontColor": "#cad3f5", // Font color setting.
|
||||||
"fontWeight": "600", // Font weight setting.
|
"fontWeight": "600", // Font weight setting.
|
||||||
@@ -364,9 +364,9 @@
|
|||||||
"wordSpacing": 0, // Word spacing setting.
|
"wordSpacing": 0, // Word spacing setting.
|
||||||
"fontKerning": "normal", // Font kerning setting.
|
"fontKerning": "normal", // Font kerning setting.
|
||||||
"textRendering": "geometricPrecision", // Text rendering setting.
|
"textRendering": "geometricPrecision", // Text rendering setting.
|
||||||
"textShadow": "0 3px 10px rgba(0,0,0,0.69)", // Text shadow setting.
|
"textShadow": "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)", // Text shadow setting.
|
||||||
"fontStyle": "normal", // Font style setting.
|
"fontStyle": "normal", // Font style setting.
|
||||||
"backgroundColor": "rgb(30, 32, 48, 0.88)", // Background color setting.
|
"backgroundColor": "transparent", // Background color setting.
|
||||||
"backdropFilter": "blur(6px)", // Backdrop filter setting.
|
"backdropFilter": "blur(6px)", // Backdrop filter setting.
|
||||||
"nPlusOneColor": "#c6a0f6", // N plus one color setting.
|
"nPlusOneColor": "#c6a0f6", // N plus one color setting.
|
||||||
"knownWordColor": "#a6da95", // Known word color setting.
|
"knownWordColor": "#a6da95", // Known word color setting.
|
||||||
@@ -374,7 +374,7 @@
|
|||||||
"N1": "#ed8796", // N1 setting.
|
"N1": "#ed8796", // N1 setting.
|
||||||
"N2": "#f5a97f", // N2 setting.
|
"N2": "#f5a97f", // N2 setting.
|
||||||
"N3": "#f9e2af", // N3 setting.
|
"N3": "#f9e2af", // N3 setting.
|
||||||
"N4": "#a6e3a1", // N4 setting.
|
"N4": "#8bd5ca", // N4 setting.
|
||||||
"N5": "#8aadf4" // N5 setting.
|
"N5": "#8aadf4" // N5 setting.
|
||||||
}, // Jlpt colors setting.
|
}, // Jlpt colors setting.
|
||||||
"frequencyDictionary": {
|
"frequencyDictionary": {
|
||||||
@@ -401,8 +401,8 @@
|
|||||||
"wordSpacing": 0, // Word spacing setting.
|
"wordSpacing": 0, // Word spacing setting.
|
||||||
"fontKerning": "normal", // Font kerning setting.
|
"fontKerning": "normal", // Font kerning setting.
|
||||||
"textRendering": "geometricPrecision", // Text rendering setting.
|
"textRendering": "geometricPrecision", // Text rendering setting.
|
||||||
"textShadow": "0 2px 4px rgba(0,0,0,0.95), 0 0 8px rgba(0,0,0,0.8), 0 0 16px rgba(0,0,0,0.55)", // Text shadow setting.
|
"textShadow": "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)", // Text shadow setting.
|
||||||
"backgroundColor": "rgba(20, 22, 34, 0.78)", // Background color setting.
|
"backgroundColor": "transparent", // Background color setting.
|
||||||
"backdropFilter": "blur(6px)", // Backdrop filter setting.
|
"backdropFilter": "blur(6px)", // Backdrop filter setting.
|
||||||
"fontWeight": "600", // Font weight setting.
|
"fontWeight": "600", // Font weight setting.
|
||||||
"fontStyle": "normal" // Font style setting.
|
"fontStyle": "normal" // Font style setting.
|
||||||
|
|||||||
+17
-16
@@ -205,23 +205,23 @@ The overlay includes a built-in WebSocket server that broadcasts subtitle text t
|
|||||||
|
|
||||||
For endpoint details, payload examples, and client patterns, see [WebSocket / Texthooker API & Integration](/websocket-texthooker-api).
|
For endpoint details, payload examples, and client patterns, see [WebSocket / Texthooker API & Integration](/websocket-texthooker-api).
|
||||||
|
|
||||||
By default, the server uses "auto" mode: it starts automatically unless [mpv_websocket](https://github.com/kuroahna/mpv_websocket) is detected at `~/.config/mpv/mpv_websocket`. If you have mpv_websocket installed, the built-in server is skipped to avoid conflicts.
|
By default, the server is disabled. Set `enabled` to `true` to force it on, or `"auto"` to start it unless [mpv_websocket](https://github.com/kuroahna/mpv_websocket) is detected at `~/.config/mpv/mpv_websocket`.
|
||||||
|
|
||||||
See `config.example.jsonc` for detailed configuration options.
|
See `config.example.jsonc` for detailed configuration options.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"websocket": {
|
"websocket": {
|
||||||
"enabled": "auto",
|
"enabled": false,
|
||||||
"port": 6677
|
"port": 6677
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Option | Values | Description |
|
| Option | Values | Description |
|
||||||
| --------- | ------------------------- | -------------------------------------------------------- |
|
| --------- | ------------------------- | --------------------------------------------- |
|
||||||
| `enabled` | `true`, `false`, `"auto"` | `"auto"` (default) disables if mpv_websocket is detected |
|
| `enabled` | `true`, `false`, `"auto"` | Built-in subtitle websocket mode (default: `false`) |
|
||||||
| `port` | number | WebSocket server port (default: 6677) |
|
| `port` | number | WebSocket server port (default: 6677) |
|
||||||
|
|
||||||
### Annotation WebSocket
|
### Annotation WebSocket
|
||||||
|
|
||||||
@@ -232,7 +232,7 @@ This stream includes subtitle text plus token metadata (N+1, known-word, frequen
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"annotationWebsocket": {
|
"annotationWebsocket": {
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"port": 6678
|
"port": 6678
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,14 +245,14 @@ This stream includes subtitle text plus token metadata (N+1, known-word, frequen
|
|||||||
|
|
||||||
### Texthooker
|
### Texthooker
|
||||||
|
|
||||||
Control whether the browser opens automatically when texthooker starts:
|
Control whether texthooker starts automatically and whether it opens a browser:
|
||||||
|
|
||||||
See `config.example.jsonc` for detailed configuration options.
|
See `config.example.jsonc` for detailed configuration options.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"texthooker": {
|
"texthooker": {
|
||||||
"launchAtStartup": true,
|
"launchAtStartup": false,
|
||||||
"openBrowser": false
|
"openBrowser": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ See `config.example.jsonc` for detailed configuration options.
|
|||||||
|
|
||||||
| Option | Values | Description |
|
| Option | Values | Description |
|
||||||
| ----------------- | --------------- | ---------------------------------------------------------------------- |
|
| ----------------- | --------------- | ---------------------------------------------------------------------- |
|
||||||
| `launchAtStartup` | `true`, `false` | Start texthooker automatically with SubMiner startup (default: `true`) |
|
| `launchAtStartup` | `true`, `false` | Start texthooker automatically with SubMiner startup (default: `false`) |
|
||||||
| `openBrowser` | `true`, `false` | Open browser tab when texthooker starts (default: `false`) |
|
| `openBrowser` | `true`, `false` | Open browser tab when texthooker starts (default: `false`) |
|
||||||
|
|
||||||
## Subtitle Display
|
## Subtitle Display
|
||||||
@@ -274,7 +274,7 @@ See `config.example.jsonc` for detailed configuration options.
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"subtitleStyle": {
|
"subtitleStyle": {
|
||||||
"fontFamily": "M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP",
|
"fontFamily": "Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP",
|
||||||
"fontSize": 35,
|
"fontSize": 35,
|
||||||
"fontColor": "#cad3f5",
|
"fontColor": "#cad3f5",
|
||||||
"fontWeight": "600",
|
"fontWeight": "600",
|
||||||
@@ -283,14 +283,15 @@ See `config.example.jsonc` for detailed configuration options.
|
|||||||
"wordSpacing": 0,
|
"wordSpacing": 0,
|
||||||
"fontKerning": "normal",
|
"fontKerning": "normal",
|
||||||
"textRendering": "geometricPrecision",
|
"textRendering": "geometricPrecision",
|
||||||
"textShadow": "0 3px 10px rgba(0,0,0,0.69)",
|
"textShadow": "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)",
|
||||||
"fontStyle": "normal",
|
"fontStyle": "normal",
|
||||||
"backgroundColor": "rgb(30, 32, 48, 0.88)",
|
"backgroundColor": "transparent",
|
||||||
"backdropFilter": "blur(6px)",
|
"backdropFilter": "blur(6px)",
|
||||||
"secondary": {
|
"secondary": {
|
||||||
"fontFamily": "Inter, Noto Sans, Helvetica Neue, sans-serif",
|
"fontFamily": "Inter, Noto Sans, Helvetica Neue, sans-serif",
|
||||||
"fontSize": 24,
|
"fontSize": 24,
|
||||||
"fontColor": "#cad3f5",
|
"fontColor": "#cad3f5",
|
||||||
|
"textShadow": "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)",
|
||||||
"backgroundColor": "transparent"
|
"backgroundColor": "transparent"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,12 +300,12 @@ See `config.example.jsonc` for detailed configuration options.
|
|||||||
|
|
||||||
| Option | Values | Description |
|
| Option | Values | Description |
|
||||||
| ---------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `fontFamily` | string | CSS font-family value (default: `"M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP"`) |
|
| `fontFamily` | string | CSS font-family value (default: `"Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP"`) |
|
||||||
| `fontSize` | number (px) | Font size in pixels (default: `35`) |
|
| `fontSize` | number (px) | Font size in pixels (default: `35`) |
|
||||||
| `fontColor` | string | Any CSS color value (default: `"#cad3f5"`) |
|
| `fontColor` | string | Any CSS color value (default: `"#cad3f5"`) |
|
||||||
| `fontWeight` | string | CSS font-weight, e.g. `"bold"`, `"normal"`, `"600"` (default: `"600"`) |
|
| `fontWeight` | string | CSS font-weight, e.g. `"bold"`, `"normal"`, `"600"` (default: `"600"`) |
|
||||||
| `fontStyle` | string | `"normal"` or `"italic"` (default: `"normal"`) |
|
| `fontStyle` | string | `"normal"` or `"italic"` (default: `"normal"`) |
|
||||||
| `backgroundColor` | string | Any CSS color, including `"transparent"` (default: `"rgb(30, 32, 48, 0.88)"`) |
|
| `backgroundColor` | string | Any CSS color, including `"transparent"` (default: `"transparent"`) |
|
||||||
| `enableJlpt` | boolean | Enable JLPT level underline styling (`false` by default) |
|
| `enableJlpt` | boolean | Enable JLPT level underline styling (`false` by default) |
|
||||||
| `preserveLineBreaks` | boolean | Preserve line breaks in visible overlay subtitle rendering (`false` by default). Enable to mirror mpv line layout. |
|
| `preserveLineBreaks` | boolean | Preserve line breaks in visible overlay subtitle rendering (`false` by default). Enable to mirror mpv line layout. |
|
||||||
| `autoPauseVideoOnHover` | boolean | Pause playback while mouse hovers subtitle text, then resume on leave (`true` by default). |
|
| `autoPauseVideoOnHover` | boolean | Pause playback while mouse hovers subtitle text, then resume on leave (`true` by default). |
|
||||||
@@ -343,7 +344,7 @@ Character-name highlighting is separate from N+1 and frequency highlighting:
|
|||||||
- `nameMatchColor` sets the highlight color for those matched character names.
|
- `nameMatchColor` sets the highlight color for those matched character names.
|
||||||
- Matches come from the bundled SubMiner character dictionary, including AniList-synced merged dictionaries when enabled.
|
- Matches come from the bundled SubMiner character dictionary, including AniList-synced merged dictionaries when enabled.
|
||||||
|
|
||||||
Secondary subtitle defaults: `fontFamily: "Inter, Noto Sans, Helvetica Neue, sans-serif"`, `fontSize: 24`, `fontColor: "#cad3f5"`, `textShadow: "0 2px 4px rgba(0,0,0,0.95), 0 0 8px rgba(0,0,0,0.8), 0 0 16px rgba(0,0,0,0.55)"`, `backgroundColor: "rgba(20, 22, 34, 0.78)"`, `fontWeight: "600"`. Any property not set in `secondary` falls back to the CSS defaults.
|
Secondary subtitle defaults: `fontFamily: "Inter, Noto Sans, Helvetica Neue, sans-serif"`, `fontSize: 24`, `fontColor: "#cad3f5"`, `textShadow: "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)"`, `backgroundColor: "transparent"`, `fontWeight: "600"`. Any property not set in `secondary` falls back to the CSS defaults.
|
||||||
|
|
||||||
**See `config.example.jsonc`** for the complete list of subtitle style configuration options.
|
**See `config.example.jsonc`** for the complete list of subtitle style configuration options.
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// Configure texthooker startup launch and browser opening behavior.
|
// Configure texthooker startup launch and browser opening behavior.
|
||||||
// ==========================================
|
// ==========================================
|
||||||
"texthooker": {
|
"texthooker": {
|
||||||
"launchAtStartup": true, // Launch texthooker server automatically when SubMiner starts. Values: true | false
|
"launchAtStartup": false, // Launch texthooker server automatically when SubMiner starts. Values: true | false
|
||||||
"openBrowser": false // Open browser setting. Values: true | false
|
"openBrowser": false // Open browser setting. Values: true | false
|
||||||
}, // Configure texthooker startup launch and browser opening behavior.
|
}, // Configure texthooker startup launch and browser opening behavior.
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
// Auto mode disables built-in server if mpv_websocket is detected.
|
// Auto mode disables built-in server if mpv_websocket is detected.
|
||||||
// ==========================================
|
// ==========================================
|
||||||
"websocket": {
|
"websocket": {
|
||||||
"enabled": "auto", // Built-in subtitle websocket server mode. Values: auto | true | false
|
"enabled": false, // Built-in subtitle websocket server mode. Values: auto | true | false
|
||||||
"port": 6677 // Built-in subtitle websocket server port.
|
"port": 6677 // Built-in subtitle websocket server port.
|
||||||
}, // Built-in WebSocket server broadcasts subtitle text to connected clients.
|
}, // Built-in WebSocket server broadcasts subtitle text to connected clients.
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
// Independent from websocket.auto and defaults to port 6678.
|
// Independent from websocket.auto and defaults to port 6678.
|
||||||
// ==========================================
|
// ==========================================
|
||||||
"annotationWebsocket": {
|
"annotationWebsocket": {
|
||||||
"enabled": true, // Annotated subtitle websocket server enabled state. Values: true | false
|
"enabled": false, // Annotated subtitle websocket server enabled state. Values: true | false
|
||||||
"port": 6678 // Annotated subtitle websocket server port.
|
"port": 6678 // Annotated subtitle websocket server port.
|
||||||
}, // Dedicated annotated subtitle websocket for bundled texthooker and token-aware clients.
|
}, // Dedicated annotated subtitle websocket for bundled texthooker and token-aware clients.
|
||||||
|
|
||||||
@@ -355,7 +355,7 @@
|
|||||||
"hoverTokenBackgroundColor": "rgba(54, 58, 79, 0.84)", // CSS color used for hovered subtitle token background highlight in mpv.
|
"hoverTokenBackgroundColor": "rgba(54, 58, 79, 0.84)", // CSS color used for hovered subtitle token background highlight in mpv.
|
||||||
"nameMatchEnabled": true, // Enable subtitle token coloring for matches from the SubMiner character dictionary. Values: true | false
|
"nameMatchEnabled": true, // Enable subtitle token coloring for matches from the SubMiner character dictionary. Values: true | false
|
||||||
"nameMatchColor": "#f5bde6", // Hex color used when a subtitle token matches an entry from the SubMiner character dictionary.
|
"nameMatchColor": "#f5bde6", // Hex color used when a subtitle token matches an entry from the SubMiner character dictionary.
|
||||||
"fontFamily": "M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP", // Font family setting.
|
"fontFamily": "Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP", // Font family setting.
|
||||||
"fontSize": 35, // Font size setting.
|
"fontSize": 35, // Font size setting.
|
||||||
"fontColor": "#cad3f5", // Font color setting.
|
"fontColor": "#cad3f5", // Font color setting.
|
||||||
"fontWeight": "600", // Font weight setting.
|
"fontWeight": "600", // Font weight setting.
|
||||||
@@ -364,9 +364,9 @@
|
|||||||
"wordSpacing": 0, // Word spacing setting.
|
"wordSpacing": 0, // Word spacing setting.
|
||||||
"fontKerning": "normal", // Font kerning setting.
|
"fontKerning": "normal", // Font kerning setting.
|
||||||
"textRendering": "geometricPrecision", // Text rendering setting.
|
"textRendering": "geometricPrecision", // Text rendering setting.
|
||||||
"textShadow": "0 3px 10px rgba(0,0,0,0.69)", // Text shadow setting.
|
"textShadow": "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)", // Text shadow setting.
|
||||||
"fontStyle": "normal", // Font style setting.
|
"fontStyle": "normal", // Font style setting.
|
||||||
"backgroundColor": "rgb(30, 32, 48, 0.88)", // Background color setting.
|
"backgroundColor": "transparent", // Background color setting.
|
||||||
"backdropFilter": "blur(6px)", // Backdrop filter setting.
|
"backdropFilter": "blur(6px)", // Backdrop filter setting.
|
||||||
"nPlusOneColor": "#c6a0f6", // N plus one color setting.
|
"nPlusOneColor": "#c6a0f6", // N plus one color setting.
|
||||||
"knownWordColor": "#a6da95", // Known word color setting.
|
"knownWordColor": "#a6da95", // Known word color setting.
|
||||||
@@ -374,7 +374,7 @@
|
|||||||
"N1": "#ed8796", // N1 setting.
|
"N1": "#ed8796", // N1 setting.
|
||||||
"N2": "#f5a97f", // N2 setting.
|
"N2": "#f5a97f", // N2 setting.
|
||||||
"N3": "#f9e2af", // N3 setting.
|
"N3": "#f9e2af", // N3 setting.
|
||||||
"N4": "#a6e3a1", // N4 setting.
|
"N4": "#8bd5ca", // N4 setting.
|
||||||
"N5": "#8aadf4" // N5 setting.
|
"N5": "#8aadf4" // N5 setting.
|
||||||
}, // Jlpt colors setting.
|
}, // Jlpt colors setting.
|
||||||
"frequencyDictionary": {
|
"frequencyDictionary": {
|
||||||
@@ -401,8 +401,8 @@
|
|||||||
"wordSpacing": 0, // Word spacing setting.
|
"wordSpacing": 0, // Word spacing setting.
|
||||||
"fontKerning": "normal", // Font kerning setting.
|
"fontKerning": "normal", // Font kerning setting.
|
||||||
"textRendering": "geometricPrecision", // Text rendering setting.
|
"textRendering": "geometricPrecision", // Text rendering setting.
|
||||||
"textShadow": "0 2px 4px rgba(0,0,0,0.95), 0 0 8px rgba(0,0,0,0.8), 0 0 16px rgba(0,0,0,0.55)", // Text shadow setting.
|
"textShadow": "0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)", // Text shadow setting.
|
||||||
"backgroundColor": "rgba(20, 22, 34, 0.78)", // Background color setting.
|
"backgroundColor": "transparent", // Background color setting.
|
||||||
"backdropFilter": "blur(6px)", // Backdrop filter setting.
|
"backdropFilter": "blur(6px)", // Backdrop filter setting.
|
||||||
"fontWeight": "600", // Font weight setting.
|
"fontWeight": "600", // Font weight setting.
|
||||||
"fontStyle": "normal" // Font style setting.
|
"fontStyle": "normal" // Font style setting.
|
||||||
|
|||||||
+18
-20
@@ -13,6 +13,11 @@ import {
|
|||||||
import { parseConfigContent } from './parse';
|
import { parseConfigContent } from './parse';
|
||||||
import { generateConfigTemplate } from './template';
|
import { generateConfigTemplate } from './template';
|
||||||
|
|
||||||
|
const DEFAULT_SUBTITLE_FONT_FAMILY =
|
||||||
|
'Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP';
|
||||||
|
const DEFAULT_SECONDARY_SUBTITLE_FONT_FAMILY = 'Inter, Noto Sans, Helvetica Neue, sans-serif';
|
||||||
|
const DEFAULT_SUBTITLE_TEXT_SHADOW = '0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)';
|
||||||
|
|
||||||
function makeTempDir(): string {
|
function makeTempDir(): string {
|
||||||
return fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-config-test-'));
|
return fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-config-test-'));
|
||||||
}
|
}
|
||||||
@@ -21,10 +26,11 @@ test('loads defaults when config is missing', () => {
|
|||||||
const dir = makeTempDir();
|
const dir = makeTempDir();
|
||||||
const service = new ConfigService(dir);
|
const service = new ConfigService(dir);
|
||||||
const config = service.getConfig();
|
const config = service.getConfig();
|
||||||
|
assert.equal(config.websocket.enabled, false);
|
||||||
assert.equal(config.websocket.port, DEFAULT_CONFIG.websocket.port);
|
assert.equal(config.websocket.port, DEFAULT_CONFIG.websocket.port);
|
||||||
assert.equal(config.annotationWebsocket.enabled, DEFAULT_CONFIG.annotationWebsocket.enabled);
|
assert.equal(config.annotationWebsocket.enabled, false);
|
||||||
assert.equal(config.annotationWebsocket.port, DEFAULT_CONFIG.annotationWebsocket.port);
|
assert.equal(config.annotationWebsocket.port, DEFAULT_CONFIG.annotationWebsocket.port);
|
||||||
assert.equal(config.texthooker.launchAtStartup, true);
|
assert.equal(config.texthooker.launchAtStartup, false);
|
||||||
assert.equal(config.ankiConnect.behavior.autoUpdateNewCards, true);
|
assert.equal(config.ankiConnect.behavior.autoUpdateNewCards, true);
|
||||||
assert.deepEqual(config.ankiConnect.tags, ['SubMiner']);
|
assert.deepEqual(config.ankiConnect.tags, ['SubMiner']);
|
||||||
assert.equal(config.anilist.enabled, false);
|
assert.equal(config.anilist.enabled, false);
|
||||||
@@ -61,7 +67,7 @@ test('loads defaults when config is missing', () => {
|
|||||||
assert.equal(config.shortcuts.toggleSubtitleSidebar, 'Backslash');
|
assert.equal(config.shortcuts.toggleSubtitleSidebar, 'Backslash');
|
||||||
assert.equal(config.discordPresence.enabled, true);
|
assert.equal(config.discordPresence.enabled, true);
|
||||||
assert.equal(config.discordPresence.updateIntervalMs, 3_000);
|
assert.equal(config.discordPresence.updateIntervalMs, 3_000);
|
||||||
assert.equal(config.subtitleStyle.backgroundColor, 'rgb(30, 32, 48, 0.88)');
|
assert.equal(config.subtitleStyle.backgroundColor, 'transparent');
|
||||||
assert.equal(config.subtitleStyle.primaryDefaultMode, 'visible');
|
assert.equal(config.subtitleStyle.primaryDefaultMode, 'visible');
|
||||||
assert.equal(config.subtitleStyle.preserveLineBreaks, false);
|
assert.equal(config.subtitleStyle.preserveLineBreaks, false);
|
||||||
assert.equal(config.subtitleStyle.autoPauseVideoOnHover, true);
|
assert.equal(config.subtitleStyle.autoPauseVideoOnHover, true);
|
||||||
@@ -69,29 +75,21 @@ test('loads defaults when config is missing', () => {
|
|||||||
assert.equal(config.subtitleSidebar.enabled, true);
|
assert.equal(config.subtitleSidebar.enabled, true);
|
||||||
assert.equal(config.subtitleStyle.hoverTokenColor, '#f4dbd6');
|
assert.equal(config.subtitleStyle.hoverTokenColor, '#f4dbd6');
|
||||||
assert.equal(config.subtitleStyle.hoverTokenBackgroundColor, 'rgba(54, 58, 79, 0.84)');
|
assert.equal(config.subtitleStyle.hoverTokenBackgroundColor, 'rgba(54, 58, 79, 0.84)');
|
||||||
assert.equal(
|
assert.equal(config.subtitleStyle.fontFamily, DEFAULT_SUBTITLE_FONT_FAMILY);
|
||||||
config.subtitleStyle.fontFamily,
|
|
||||||
'M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP',
|
|
||||||
);
|
|
||||||
assert.equal(config.subtitleStyle.fontWeight, '600');
|
assert.equal(config.subtitleStyle.fontWeight, '600');
|
||||||
assert.equal(config.subtitleStyle.lineHeight, 1.35);
|
assert.equal(config.subtitleStyle.lineHeight, 1.35);
|
||||||
assert.equal(config.subtitleStyle.letterSpacing, '-0.01em');
|
assert.equal(config.subtitleStyle.letterSpacing, '-0.01em');
|
||||||
assert.equal(config.subtitleStyle.wordSpacing, 0);
|
assert.equal(config.subtitleStyle.wordSpacing, 0);
|
||||||
assert.equal(config.subtitleStyle.fontKerning, 'normal');
|
assert.equal(config.subtitleStyle.fontKerning, 'normal');
|
||||||
assert.equal(config.subtitleStyle.textRendering, 'geometricPrecision');
|
assert.equal(config.subtitleStyle.textRendering, 'geometricPrecision');
|
||||||
assert.equal(config.subtitleStyle.textShadow, '0 3px 10px rgba(0,0,0,0.69)');
|
assert.equal(config.subtitleStyle.textShadow, DEFAULT_SUBTITLE_TEXT_SHADOW);
|
||||||
assert.equal(config.subtitleStyle.backdropFilter, 'blur(6px)');
|
assert.equal(config.subtitleStyle.backdropFilter, 'blur(6px)');
|
||||||
assert.equal(
|
assert.equal(config.subtitleStyle.jlptColors.N4, '#8bd5ca');
|
||||||
config.subtitleStyle.secondary.fontFamily,
|
assert.equal(config.subtitleStyle.secondary.fontFamily, DEFAULT_SECONDARY_SUBTITLE_FONT_FAMILY);
|
||||||
'Inter, Noto Sans, Helvetica Neue, sans-serif',
|
|
||||||
);
|
|
||||||
assert.equal(config.subtitleStyle.secondary.fontColor, '#cad3f5');
|
assert.equal(config.subtitleStyle.secondary.fontColor, '#cad3f5');
|
||||||
assert.equal(config.subtitleStyle.secondary.fontWeight, '600');
|
assert.equal(config.subtitleStyle.secondary.fontWeight, '600');
|
||||||
assert.equal(
|
assert.equal(config.subtitleStyle.secondary.textShadow, DEFAULT_SUBTITLE_TEXT_SHADOW);
|
||||||
config.subtitleStyle.secondary.textShadow,
|
assert.equal(config.subtitleStyle.secondary.backgroundColor, 'transparent');
|
||||||
'0 2px 4px rgba(0,0,0,0.95), 0 0 8px rgba(0,0,0,0.8), 0 0 16px rgba(0,0,0,0.55)',
|
|
||||||
);
|
|
||||||
assert.equal(config.subtitleStyle.secondary.backgroundColor, 'rgba(20, 22, 34, 0.78)');
|
|
||||||
assert.equal(config.immersionTracking.enabled, true);
|
assert.equal(config.immersionTracking.enabled, true);
|
||||||
assert.equal(config.immersionTracking.dbPath, '');
|
assert.equal(config.immersionTracking.dbPath, '');
|
||||||
assert.equal(config.immersionTracking.batchSize, 25);
|
assert.equal(config.immersionTracking.batchSize, 25);
|
||||||
@@ -2142,11 +2140,11 @@ test('template generator includes known keys', () => {
|
|||||||
);
|
);
|
||||||
assert.match(
|
assert.match(
|
||||||
output,
|
output,
|
||||||
/"enabled": "auto",? \/\/ Built-in subtitle websocket server mode\. Values: auto \| true \| false/,
|
/"enabled": false,? \/\/ Built-in subtitle websocket server mode\. Values: auto \| true \| false/,
|
||||||
);
|
);
|
||||||
assert.match(
|
assert.match(
|
||||||
output,
|
output,
|
||||||
/"enabled": true,? \/\/ Annotated subtitle websocket server enabled state\. Values: true \| false/,
|
/"enabled": false,? \/\/ Annotated subtitle websocket server enabled state\. Values: true \| false/,
|
||||||
);
|
);
|
||||||
assert.match(
|
assert.match(
|
||||||
output,
|
output,
|
||||||
@@ -2221,7 +2219,7 @@ test('template generator includes known keys', () => {
|
|||||||
assert.doesNotMatch(output, /"whisperThreads": 4/);
|
assert.doesNotMatch(output, /"whisperThreads": 4/);
|
||||||
assert.match(
|
assert.match(
|
||||||
output,
|
output,
|
||||||
/"launchAtStartup": true,? \/\/ Launch texthooker server automatically when SubMiner starts\. Values: true \| false/,
|
/"launchAtStartup": false,? \/\/ Launch texthooker server automatically when SubMiner starts\. Values: true \| false/,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,18 +19,18 @@ export const CORE_DEFAULT_CONFIG: Pick<
|
|||||||
subtitlePosition: { yPercent: 10 },
|
subtitlePosition: { yPercent: 10 },
|
||||||
keybindings: [],
|
keybindings: [],
|
||||||
websocket: {
|
websocket: {
|
||||||
enabled: 'auto',
|
enabled: false,
|
||||||
port: 6677,
|
port: 6677,
|
||||||
},
|
},
|
||||||
annotationWebsocket: {
|
annotationWebsocket: {
|
||||||
enabled: true,
|
enabled: false,
|
||||||
port: 6678,
|
port: 6678,
|
||||||
},
|
},
|
||||||
logging: {
|
logging: {
|
||||||
level: 'info',
|
level: 'info',
|
||||||
},
|
},
|
||||||
texthooker: {
|
texthooker: {
|
||||||
launchAtStartup: true,
|
launchAtStartup: false,
|
||||||
openBrowser: false,
|
openBrowser: false,
|
||||||
},
|
},
|
||||||
controller: {
|
controller: {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const SUBTITLE_DEFAULT_CONFIG: Pick<ResolvedConfig, 'subtitleStyle' | 'su
|
|||||||
hoverTokenBackgroundColor: 'rgba(54, 58, 79, 0.84)',
|
hoverTokenBackgroundColor: 'rgba(54, 58, 79, 0.84)',
|
||||||
nameMatchEnabled: true,
|
nameMatchEnabled: true,
|
||||||
nameMatchColor: '#f5bde6',
|
nameMatchColor: '#f5bde6',
|
||||||
fontFamily: 'M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP',
|
fontFamily: 'Hiragino Sans, M PLUS 1, Source Han Sans JP, Noto Sans CJK JP',
|
||||||
fontSize: 35,
|
fontSize: 35,
|
||||||
fontColor: '#cad3f5',
|
fontColor: '#cad3f5',
|
||||||
fontWeight: '600',
|
fontWeight: '600',
|
||||||
@@ -20,9 +20,9 @@ export const SUBTITLE_DEFAULT_CONFIG: Pick<ResolvedConfig, 'subtitleStyle' | 'su
|
|||||||
wordSpacing: 0,
|
wordSpacing: 0,
|
||||||
fontKerning: 'normal',
|
fontKerning: 'normal',
|
||||||
textRendering: 'geometricPrecision',
|
textRendering: 'geometricPrecision',
|
||||||
textShadow: '0 3px 10px rgba(0,0,0,0.69)',
|
textShadow: '0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)',
|
||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
backgroundColor: 'rgb(30, 32, 48, 0.88)',
|
backgroundColor: 'transparent',
|
||||||
backdropFilter: 'blur(6px)',
|
backdropFilter: 'blur(6px)',
|
||||||
nPlusOneColor: '#c6a0f6',
|
nPlusOneColor: '#c6a0f6',
|
||||||
knownWordColor: '#a6da95',
|
knownWordColor: '#a6da95',
|
||||||
@@ -30,7 +30,7 @@ export const SUBTITLE_DEFAULT_CONFIG: Pick<ResolvedConfig, 'subtitleStyle' | 'su
|
|||||||
N1: '#ed8796',
|
N1: '#ed8796',
|
||||||
N2: '#f5a97f',
|
N2: '#f5a97f',
|
||||||
N3: '#f9e2af',
|
N3: '#f9e2af',
|
||||||
N4: '#a6e3a1',
|
N4: '#8bd5ca',
|
||||||
N5: '#8aadf4',
|
N5: '#8aadf4',
|
||||||
},
|
},
|
||||||
frequencyDictionary: {
|
frequencyDictionary: {
|
||||||
@@ -51,8 +51,8 @@ export const SUBTITLE_DEFAULT_CONFIG: Pick<ResolvedConfig, 'subtitleStyle' | 'su
|
|||||||
wordSpacing: 0,
|
wordSpacing: 0,
|
||||||
fontKerning: 'normal',
|
fontKerning: 'normal',
|
||||||
textRendering: 'geometricPrecision',
|
textRendering: 'geometricPrecision',
|
||||||
textShadow: '0 2px 4px rgba(0,0,0,0.95), 0 0 8px rgba(0,0,0,0.8), 0 0 16px rgba(0,0,0,0.55)',
|
textShadow: '0 2px 6px rgba(0,0,0,0.9), 0 0 12px rgba(0,0,0,0.55)',
|
||||||
backgroundColor: 'rgba(20, 22, 34, 0.78)',
|
backgroundColor: 'transparent',
|
||||||
backdropFilter: 'blur(6px)',
|
backdropFilter: 'blur(6px)',
|
||||||
fontWeight: '600',
|
fontWeight: '600',
|
||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
|
|||||||
Reference in New Issue
Block a user