From 4b42e1ee11dcd5691be6a7a51a4d992b9ebd596d Mon Sep 17 00:00:00 2001 From: m4xx1m Date: Thu, 12 Nov 2026 23:32:20 +0300 Subject: [PATCH] feat(config): auto-persist Video & Quality settings to config.json across app restarts --- frontend/src/main.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 77a0f22..1076d61 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -420,6 +420,26 @@ function crfQualityHint(crf: number): string { return tr.crfHintSmall; } +let saveCfgTimer = 0; +function persistVideoSettings() { + const api = appApi(); + if (!api || !state.appInfo) return; + state.appInfo.config.defaultEncoder = state.encoder; + state.appInfo.config.defaultHwDecode = state.hwDecode; + state.appInfo.config.defaultPreset = state.preset; + state.appInfo.config.defaultCrf = state.crf; + state.appInfo.config.defaultFps = state.fps; + state.appInfo.config.defaultTune = state.tune; + state.appInfo.config.defaultMergeAudio = state.audioMode === 'merge'; + + window.clearTimeout(saveCfgTimer); + saveCfgTimer = window.setTimeout(() => { + if (state.appInfo) { + void api.SaveConfig(state.appInfo.config); + } + }, 350); +} + function syncControlsFromState() { el<'select'>('encoderSelect').value = state.encoder; el<'select'>('hwDecodeSelect').value = state.hwDecode; @@ -1168,26 +1188,32 @@ function bindEvents() { el<'select'>('encoderSelect').addEventListener('change', (e) => { state.encoder = (e.target as HTMLSelectElement).value; syncControlsFromState(); + persistVideoSettings(); }); el<'select'>('hwDecodeSelect').addEventListener('change', (e) => { state.hwDecode = (e.target as HTMLSelectElement).value; + persistVideoSettings(); void refreshCLI(); }); el<'input'>('crfRange').addEventListener('input', (e) => { state.crf = Number((e.target as HTMLInputElement).value); el<'span'>('crfLabel').textContent = `${state.crf} ยท ${crfQualityHint(state.crf)}`; + persistVideoSettings(); void refreshCLI(); }); el<'select'>('presetSelect').addEventListener('change', (e) => { state.preset = (e.target as HTMLSelectElement).value; + persistVideoSettings(); void refreshCLI(); }); el<'select'>('tuneSelect').addEventListener('change', (e) => { state.tune = (e.target as HTMLSelectElement).value; + persistVideoSettings(); void refreshCLI(); }); el<'select'>('fpsSelect').addEventListener('change', (e) => { state.fps = Number((e.target as HTMLSelectElement).value); + persistVideoSettings(); void refreshCLI(); }); @@ -1206,6 +1232,7 @@ function bindEvents() { b.addEventListener('click', () => { state.audioMode = b.dataset.amode as 'merge' | 'track' | 'mute'; syncControlsFromState(); + persistVideoSettings(); }); });