const QUEUE_SYNC_FAST_MS = 900; const QUEUE_SYNC_DEFAULT_MS = 1800; const QUEUE_SYNC_IDLE_MS = 4500; const QUEUE_SYNC_HIDDEN_MS = 9000; const QUEUE_SYNC_RECENT_ACTIVITY_WINDOW_MS = 15000; async function init(): Promise { const [loadedConfig, initialQueue, isDown, version] = await Promise.all([ window.api.getConfig(), window.api.getQueue(), window.api.isDownloading(), window.api.getVersion() ]); config = loadedConfig; const language = setLanguage((config.language as string) || 'en'); config.language = language; queue = Array.isArray(initialQueue) ? initialQueue : []; downloading = isDown; markQueueActivity(); byId('versionText').textContent = `v${version}`; byId('versionInfo').textContent = `Version: v${version}`; document.title = `${UI_TEXT.appName} v${version}`; byId('clientId').value = config.client_id ?? ''; byId('clientSecret').value = config.client_secret ?? ''; byId('downloadPath').value = config.download_path ?? ''; byId('themeSelect').value = config.theme ?? 'twitch'; byId('languageSelect').value = config.language ?? 'en'; updateLanguagePicker(config.language ?? 'en'); byId('downloadMode').value = config.download_mode ?? 'full'; byId('partMinutes').value = String(config.part_minutes ?? 120); byId('performanceMode').value = (config.performance_mode as string) || 'balanced'; byId('smartSchedulerToggle').checked = (config.smart_queue_scheduler as boolean) !== false; byId('duplicatePreventionToggle').checked = (config.prevent_duplicate_downloads as boolean) !== false; byId('metadataCacheMinutes').value = String((config.metadata_cache_minutes as number) || 10); byId('vodFilenameTemplate').value = (config.filename_template_vod as string) || DEFAULT_VOD_TEMPLATE; byId('partsFilenameTemplate').value = (config.filename_template_parts as string) || DEFAULT_PARTS_TEMPLATE; byId('defaultClipFilenameTemplate').value = (config.filename_template_clip as string) || DEFAULT_CLIP_TEMPLATE; initSettingsAutoSave(); changeTheme(config.theme ?? 'twitch'); renderStreamers(); renderQueue(); // Kick off live-status subscription so the sidebar dots populate. const liveStatusInit = (window as unknown as { initLiveStatusSubscription?: () => Promise }).initLiveStatusSubscription; if (typeof liveStatusInit === 'function') void liveStatusInit(); initQueueDragDrop(); updateDownloadButtonState(); updateStatusBarQueueSummary(); // Restore persisted VOD filter into the input — the filter itself only // takes effect once VODs load (renderVODs reads vodFilterQuery). vodFilterQuery = loadPersistedVodFilter(); const vodFilterInput = document.getElementById('vodFilterInput') as HTMLInputElement | null; if (vodFilterInput) vodFilterInput.value = vodFilterQuery; syncVodFilterClearButton(); // Restore persisted VOD sort key. Apply localized labels to