mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-26 00:55:16 -07:00
refactor: deduplicate mpv plugin config, fix CSS font fallbacks
- Extract shared getMpvPluginRuntimeConfig() helper to eliminate duplicate inline objects - Call ensureImmersionTrackerStarted() before markActiveVideoWatched action - Quote multi-word font names and add sans-serif generic fallback in subtitle sidebar CSS - Add main-wiring tests asserting deduplication and tracker start ordering
This commit is contained in:
+18
-22
@@ -1222,17 +1222,7 @@ const youtubePlaybackRuntime = createYoutubePlaybackRuntime({
|
|||||||
resolveInstalledPluginBeforeLaunch: (detection, mpvPath) =>
|
resolveInstalledPluginBeforeLaunch: (detection, mpvPath) =>
|
||||||
promptForLegacyMpvPluginRemovalBeforeWindowsLaunch(mpvPath, detection),
|
promptForLegacyMpvPluginRemovalBeforeWindowsLaunch(mpvPath, detection),
|
||||||
},
|
},
|
||||||
{
|
getMpvPluginRuntimeConfig(),
|
||||||
socketPath: appState.mpvSocketPath,
|
|
||||||
binaryPath: getResolvedConfig().mpv.subminerBinaryPath,
|
|
||||||
backend: getResolvedConfig().mpv.backend,
|
|
||||||
autoStart: getResolvedConfig().mpv.autoStartSubMiner,
|
|
||||||
autoStartVisibleOverlay: getResolvedConfig().auto_start_overlay,
|
|
||||||
autoStartPauseUntilReady: getResolvedConfig().mpv.pauseUntilOverlayReady,
|
|
||||||
texthookerEnabled: getResolvedConfig().texthooker.launchAtStartup,
|
|
||||||
aniskipEnabled: getResolvedConfig().mpv.aniskipEnabled,
|
|
||||||
aniskipButtonKey: getResolvedConfig().mpv.aniskipButtonKey,
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
waitForYoutubeMpvConnected: (timeoutMs) => waitForYoutubeMpvConnected(timeoutMs),
|
waitForYoutubeMpvConnected: (timeoutMs) => waitForYoutubeMpvConnected(timeoutMs),
|
||||||
prepareYoutubePlaybackInMpv: (request) => prepareYoutubePlaybackInMpv(request),
|
prepareYoutubePlaybackInMpv: (request) => prepareYoutubePlaybackInMpv(request),
|
||||||
@@ -1243,6 +1233,21 @@ const youtubePlaybackRuntime = createYoutubePlaybackRuntime({
|
|||||||
clearScheduled: (timer) => clearTimeout(timer),
|
clearScheduled: (timer) => clearTimeout(timer),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getMpvPluginRuntimeConfig() {
|
||||||
|
const config = getResolvedConfig();
|
||||||
|
return {
|
||||||
|
socketPath: appState.mpvSocketPath,
|
||||||
|
binaryPath: config.mpv.subminerBinaryPath,
|
||||||
|
backend: config.mpv.backend,
|
||||||
|
autoStart: config.mpv.autoStartSubMiner,
|
||||||
|
autoStartVisibleOverlay: config.auto_start_overlay,
|
||||||
|
autoStartPauseUntilReady: config.mpv.pauseUntilOverlayReady,
|
||||||
|
texthookerEnabled: config.texthooker.launchAtStartup,
|
||||||
|
aniskipEnabled: config.mpv.aniskipEnabled,
|
||||||
|
aniskipButtonKey: config.mpv.aniskipButtonKey,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let firstRunSetupMessage: string | null = null;
|
let firstRunSetupMessage: string | null = null;
|
||||||
const resolveWindowsMpvShortcutRuntimePaths = () =>
|
const resolveWindowsMpvShortcutRuntimePaths = () =>
|
||||||
resolveWindowsMpvShortcutPaths({
|
resolveWindowsMpvShortcutPaths({
|
||||||
@@ -2650,17 +2655,7 @@ const {
|
|||||||
getLaunchMode: () => getResolvedConfig().mpv.launchMode,
|
getLaunchMode: () => getResolvedConfig().mpv.launchMode,
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
execPath: process.execPath,
|
execPath: process.execPath,
|
||||||
getPluginRuntimeConfig: () => ({
|
getPluginRuntimeConfig: () => getMpvPluginRuntimeConfig(),
|
||||||
socketPath: appState.mpvSocketPath,
|
|
||||||
binaryPath: getResolvedConfig().mpv.subminerBinaryPath,
|
|
||||||
backend: getResolvedConfig().mpv.backend,
|
|
||||||
autoStart: getResolvedConfig().mpv.autoStartSubMiner,
|
|
||||||
autoStartVisibleOverlay: getResolvedConfig().auto_start_overlay,
|
|
||||||
autoStartPauseUntilReady: getResolvedConfig().mpv.pauseUntilOverlayReady,
|
|
||||||
texthookerEnabled: getResolvedConfig().texthooker.launchAtStartup,
|
|
||||||
aniskipEnabled: getResolvedConfig().mpv.aniskipEnabled,
|
|
||||||
aniskipButtonKey: getResolvedConfig().mpv.aniskipButtonKey,
|
|
||||||
}),
|
|
||||||
defaultMpvLogPath: DEFAULT_MPV_LOG_PATH,
|
defaultMpvLogPath: DEFAULT_MPV_LOG_PATH,
|
||||||
defaultMpvArgs: MPV_JELLYFIN_DEFAULT_ARGS,
|
defaultMpvArgs: MPV_JELLYFIN_DEFAULT_ARGS,
|
||||||
removeSocketPath: (socketPath) => {
|
removeSocketPath: (socketPath) => {
|
||||||
@@ -5143,6 +5138,7 @@ async function dispatchSessionAction(request: SessionActionDispatchRequest): Pro
|
|||||||
toggleSubtitleSidebar: () => toggleSubtitleSidebar(),
|
toggleSubtitleSidebar: () => toggleSubtitleSidebar(),
|
||||||
markLastCardAsAudioCard: () => markLastCardAsAudioCard(),
|
markLastCardAsAudioCard: () => markLastCardAsAudioCard(),
|
||||||
markActiveVideoWatched: async () => {
|
markActiveVideoWatched: async () => {
|
||||||
|
ensureImmersionTrackerStarted();
|
||||||
const marked = (await appState.immersionTracker?.markActiveVideoWatched()) ?? false;
|
const marked = (await appState.immersionTracker?.markActiveVideoWatched()) ?? false;
|
||||||
if (marked) {
|
if (marked) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
function readMainSource(): string {
|
||||||
|
return fs.readFileSync(path.join(process.cwd(), 'src/main.ts'), 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
test('manual watched session action starts immersion tracker before marking watched', () => {
|
||||||
|
const source = readMainSource();
|
||||||
|
const actionBlock = source.match(
|
||||||
|
/markActiveVideoWatched: async \(\) => \{(?<body>[\s\S]*?)\n \},/,
|
||||||
|
)?.groups?.body;
|
||||||
|
|
||||||
|
assert.ok(actionBlock);
|
||||||
|
assert.match(actionBlock, /ensureImmersionTrackerStarted\(\);/);
|
||||||
|
assert.ok(
|
||||||
|
actionBlock.indexOf('ensureImmersionTrackerStarted();') <
|
||||||
|
actionBlock.indexOf('markActiveVideoWatched()'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('main process uses one shared mpv plugin runtime config helper', () => {
|
||||||
|
const source = readMainSource();
|
||||||
|
assert.match(source, /function getMpvPluginRuntimeConfig\(\)/);
|
||||||
|
assert.equal((source.match(/socketPath: appState\.mpvSocketPath/g) ?? []).length, 1);
|
||||||
|
assert.equal(
|
||||||
|
(source.match(/binaryPath: getResolvedConfig\(\)\.mpv\.subminerBinaryPath/g) ?? []).length,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -40,6 +40,20 @@ test('renderer stylesheet only hides visible focus chrome on top-level overlay f
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('subtitle sidebar stylesheet keeps quoted font fallbacks and generic family', () => {
|
||||||
|
const cssSource = readWorkspaceFile('src/renderer/style.css');
|
||||||
|
const sidebarContentBlock = cssSource.match(
|
||||||
|
/\.subtitle-sidebar-content\s*\{(?<body>[\s\S]*?)\n\}/,
|
||||||
|
)?.groups?.body;
|
||||||
|
|
||||||
|
assert.ok(sidebarContentBlock);
|
||||||
|
assert.match(sidebarContentBlock, /'Hiragino Sans'/);
|
||||||
|
assert.match(sidebarContentBlock, /'M PLUS 1'/);
|
||||||
|
assert.match(sidebarContentBlock, /'Source Han Sans JP'/);
|
||||||
|
assert.match(sidebarContentBlock, /'Noto Sans CJK JP'/);
|
||||||
|
assert.match(sidebarContentBlock, /sans-serif/);
|
||||||
|
});
|
||||||
|
|
||||||
test('top-level readme avoids stale overlay-layers wording', () => {
|
test('top-level readme avoids stale overlay-layers wording', () => {
|
||||||
const readmeSource = readWorkspaceFile('README.md');
|
const readmeSource = readWorkspaceFile('README.md');
|
||||||
assert.doesNotMatch(readmeSource, /overlay layers/i);
|
assert.doesNotMatch(readmeSource, /overlay layers/i);
|
||||||
|
|||||||
@@ -1912,10 +1912,11 @@ body.subtitle-sidebar-embedded-open .subtitle-sidebar-modal {
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
font-family: var(
|
font-family: var(
|
||||||
--subtitle-sidebar-font-family,
|
--subtitle-sidebar-font-family,
|
||||||
Hiragino Sans,
|
'Hiragino Sans',
|
||||||
M PLUS 1,
|
'M PLUS 1',
|
||||||
Source Han Sans JP,
|
'Source Han Sans JP',
|
||||||
Noto Sans CJK JP
|
'Noto Sans CJK JP',
|
||||||
|
sans-serif
|
||||||
);
|
);
|
||||||
font-size: var(--subtitle-sidebar-font-size, 16px);
|
font-size: var(--subtitle-sidebar-font-size, 16px);
|
||||||
background: var(--subtitle-sidebar-background-color, rgba(73, 77, 100, 0.9));
|
background: var(--subtitle-sidebar-background-color, rgba(73, 77, 100, 0.9));
|
||||||
|
|||||||
Reference in New Issue
Block a user