mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-06-13 15:13:32 -07:00
feat(config): add configuration window (#70)
This commit is contained in:
@@ -6,11 +6,18 @@ import {
|
||||
DEFAULT_KEYBINDINGS,
|
||||
deepCloneConfig,
|
||||
} from './definitions';
|
||||
import {
|
||||
buildSubtitleCssDeclarationObject,
|
||||
getSubtitleCssManagedConfigPaths,
|
||||
getSubtitleCssPath,
|
||||
type SubtitleCssScope,
|
||||
} from '../settings/subtitle-style-css';
|
||||
|
||||
const OPTION_REGISTRY_BY_PATH = new Map(CONFIG_OPTION_REGISTRY.map((entry) => [entry.path, entry]));
|
||||
const TOP_LEVEL_SECTION_DESCRIPTION_BY_KEY = new Map(
|
||||
CONFIG_TEMPLATE_SECTIONS.map((section) => [String(section.key), section.description[0] ?? '']),
|
||||
);
|
||||
const SUBTITLE_CSS_SCOPES: SubtitleCssScope[] = ['primary', 'secondary', 'sidebar'];
|
||||
|
||||
function normalizeCommentText(value: string): string {
|
||||
return value.replace(/\s+/g, ' ').replace(/\*\//g, '*\\/').trim();
|
||||
@@ -18,7 +25,9 @@ function normalizeCommentText(value: string): string {
|
||||
|
||||
function humanizeKey(key: string): string {
|
||||
const spaced = key
|
||||
.replace(/^--/, '')
|
||||
.replace(/_/g, ' ')
|
||||
.replace(/-/g, ' ')
|
||||
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
||||
.toLowerCase();
|
||||
return spaced.charAt(0).toUpperCase() + spaced.slice(1);
|
||||
@@ -42,6 +51,62 @@ function buildInlineOptionComment(path: string, value: unknown): string {
|
||||
return description;
|
||||
}
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
||||
}
|
||||
|
||||
function getValueAtPath(root: unknown, path: string): unknown {
|
||||
let current = root;
|
||||
for (const segment of path.split('.')) {
|
||||
if (!isRecord(current)) return undefined;
|
||||
current = current[segment];
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
function setValueAtPath(root: unknown, path: string, value: unknown): void {
|
||||
const segments = path.split('.').filter(Boolean);
|
||||
let current = root;
|
||||
for (const [index, segment] of segments.entries()) {
|
||||
if (!isRecord(current)) return;
|
||||
if (index === segments.length - 1) {
|
||||
current[segment] = value;
|
||||
return;
|
||||
}
|
||||
current = current[segment];
|
||||
}
|
||||
}
|
||||
|
||||
function deleteValueAtPath(root: unknown, path: string): void {
|
||||
const segments = path.split('.').filter(Boolean);
|
||||
let current = root;
|
||||
for (const [index, segment] of segments.entries()) {
|
||||
if (!isRecord(current)) return;
|
||||
if (index === segments.length - 1) {
|
||||
delete current[segment];
|
||||
return;
|
||||
}
|
||||
current = current[segment];
|
||||
}
|
||||
}
|
||||
|
||||
function foldSubtitleCssManagedDefaults(templateConfig: ResolvedConfig): void {
|
||||
for (const scope of SUBTITLE_CSS_SCOPES) {
|
||||
const cssPath = getSubtitleCssPath(scope);
|
||||
const values: Record<string, unknown> = {
|
||||
[cssPath]: getValueAtPath(templateConfig, cssPath),
|
||||
};
|
||||
const managedPaths = getSubtitleCssManagedConfigPaths(scope);
|
||||
for (const managedPath of managedPaths) {
|
||||
values[managedPath] = getValueAtPath(templateConfig, managedPath);
|
||||
}
|
||||
setValueAtPath(templateConfig, cssPath, buildSubtitleCssDeclarationObject(scope, values));
|
||||
for (const managedPath of managedPaths) {
|
||||
deleteValueAtPath(templateConfig, managedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderValue(value: unknown, indent = 0, path = ''): string {
|
||||
const pad = ' '.repeat(indent);
|
||||
const nextPad = ' '.repeat(indent + 2);
|
||||
@@ -106,6 +171,7 @@ function renderSection(
|
||||
|
||||
function createTemplateConfig(config: ResolvedConfig): ResolvedConfig {
|
||||
const templateConfig = deepCloneConfig(config);
|
||||
foldSubtitleCssManagedDefaults(templateConfig);
|
||||
if (templateConfig.keybindings.length === 0) {
|
||||
templateConfig.keybindings = DEFAULT_KEYBINDINGS.map((binding) => ({
|
||||
key: binding.key,
|
||||
|
||||
Reference in New Issue
Block a user