mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-27 12:55:20 -07:00
feat(overlay): add primary subtitle bar visibility modes (#63)
- Cycle `v` through `hidden | visible | hover` instead of a boolean toggle - Add `subtitleStyle.primaryDefaultMode` config with default `visible` - Carry primary mode independently from secondary in hot-reload payload - Add hover CSS: transparent until hovered, then fully visible - Show primary-specific OSD text on each mode change
This commit is contained in:
@@ -56,6 +56,7 @@ test('loads defaults when config is missing', () => {
|
||||
assert.equal(config.discordPresence.enabled, true);
|
||||
assert.equal(config.discordPresence.updateIntervalMs, 3_000);
|
||||
assert.equal(config.subtitleStyle.backgroundColor, 'rgb(30, 32, 48, 0.88)');
|
||||
assert.equal(config.subtitleStyle.primaryDefaultMode, 'visible');
|
||||
assert.equal(config.subtitleStyle.preserveLineBreaks, false);
|
||||
assert.equal(config.subtitleStyle.autoPauseVideoOnHover, true);
|
||||
assert.equal(config.subtitleStyle.autoPauseVideoOnYomitanPopup, true);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ResolvedConfig } from '../../types/config';
|
||||
|
||||
export const SUBTITLE_DEFAULT_CONFIG: Pick<ResolvedConfig, 'subtitleStyle' | 'subtitleSidebar'> = {
|
||||
subtitleStyle: {
|
||||
primaryDefaultMode: 'visible',
|
||||
enableJlpt: false,
|
||||
preserveLineBreaks: false,
|
||||
autoPauseVideoOnHover: true,
|
||||
|
||||
@@ -5,6 +5,14 @@ export function buildSubtitleConfigOptionRegistry(
|
||||
defaultConfig: ResolvedConfig,
|
||||
): ConfigOptionRegistryEntry[] {
|
||||
return [
|
||||
{
|
||||
path: 'subtitleStyle.primaryDefaultMode',
|
||||
kind: 'enum',
|
||||
enumValues: ['hidden', 'visible', 'hover'],
|
||||
defaultValue: defaultConfig.subtitleStyle.primaryDefaultMode,
|
||||
description:
|
||||
'Default primary subtitle bar visibility mode. hidden hides it, visible shows it, hover reveals it on hover.',
|
||||
},
|
||||
{
|
||||
path: 'subtitleStyle.enableJlpt',
|
||||
kind: 'boolean',
|
||||
|
||||
@@ -147,6 +147,7 @@ export function applySubtitleDomainConfig(context: ResolveContext): void {
|
||||
|
||||
if (isObject(src.subtitleStyle)) {
|
||||
const fallbackSubtitleStyleEnableJlpt = resolved.subtitleStyle.enableJlpt;
|
||||
const fallbackSubtitleStylePrimaryDefaultMode = resolved.subtitleStyle.primaryDefaultMode;
|
||||
const fallbackSubtitleStylePreserveLineBreaks = resolved.subtitleStyle.preserveLineBreaks;
|
||||
const fallbackSubtitleStyleAutoPauseVideoOnHover = resolved.subtitleStyle.autoPauseVideoOnHover;
|
||||
const fallbackSubtitleStyleAutoPauseVideoOnYomitanPopup =
|
||||
@@ -190,6 +191,24 @@ export function applySubtitleDomainConfig(context: ResolveContext): void {
|
||||
);
|
||||
}
|
||||
|
||||
const primaryDefaultMode = (src.subtitleStyle as { primaryDefaultMode?: unknown })
|
||||
.primaryDefaultMode;
|
||||
if (
|
||||
primaryDefaultMode === 'hidden' ||
|
||||
primaryDefaultMode === 'visible' ||
|
||||
primaryDefaultMode === 'hover'
|
||||
) {
|
||||
resolved.subtitleStyle.primaryDefaultMode = primaryDefaultMode;
|
||||
} else if (primaryDefaultMode !== undefined) {
|
||||
resolved.subtitleStyle.primaryDefaultMode = fallbackSubtitleStylePrimaryDefaultMode;
|
||||
warn(
|
||||
'subtitleStyle.primaryDefaultMode',
|
||||
primaryDefaultMode,
|
||||
resolved.subtitleStyle.primaryDefaultMode,
|
||||
'Expected hidden, visible, or hover.',
|
||||
);
|
||||
}
|
||||
|
||||
const preserveLineBreaks = asBoolean(
|
||||
(src.subtitleStyle as { preserveLineBreaks?: unknown }).preserveLineBreaks,
|
||||
);
|
||||
|
||||
@@ -66,6 +66,31 @@ test('subtitleStyle autoPauseVideoOnYomitanPopup falls back on invalid value', (
|
||||
);
|
||||
});
|
||||
|
||||
test('subtitleStyle primaryDefaultMode accepts valid values and warns on invalid', () => {
|
||||
const valid = createResolveContext({
|
||||
subtitleStyle: {
|
||||
primaryDefaultMode: 'hover',
|
||||
},
|
||||
});
|
||||
applySubtitleDomainConfig(valid.context);
|
||||
assert.equal(valid.context.resolved.subtitleStyle.primaryDefaultMode, 'hover');
|
||||
|
||||
const invalid = createResolveContext({
|
||||
subtitleStyle: {
|
||||
primaryDefaultMode: 'auto' as never,
|
||||
},
|
||||
});
|
||||
applySubtitleDomainConfig(invalid.context);
|
||||
assert.equal(invalid.context.resolved.subtitleStyle.primaryDefaultMode, 'visible');
|
||||
assert.ok(
|
||||
invalid.warnings.some(
|
||||
(warning) =>
|
||||
warning.path === 'subtitleStyle.primaryDefaultMode' &&
|
||||
warning.message === 'Expected hidden, visible, or hover.',
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('subtitleStyle nameMatchEnabled falls back on invalid value', () => {
|
||||
const { context, warnings } = createResolveContext({
|
||||
subtitleStyle: {
|
||||
|
||||
Reference in New Issue
Block a user