diff --git a/src/App.svelte b/src/App.svelte index 744a4b9..643b67b 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -213,6 +213,7 @@ let pendingOverlayDraft: { overlayName: string; overlaySlug: string; overlayHtml: string; overlayCss: string; overlayJavascript: string; overlayEnabled: boolean; overlayDisabledDesign: string; overlayAlertGroupWindowMs: number; overlayAlertGroupSize: number; overlayAlertDisplayMs: number } | null = null; let overlayDiagnosticsOpen = false; let overlayEditorTab: 'HTML' | 'CSS' | 'JAVASCRIPT' = 'HTML'; + let overlayCompletion = ''; let overlayAutosaveTimer: number | undefined; let oauthScopes: Record<'streamer' | 'bot', { connected: boolean; missing_scopes: string[]; reauthorization_required: boolean }> = { streamer: { connected: false, missing_scopes: [], reauthorization_required: false }, @@ -1286,6 +1287,20 @@ return Array.from({ length: Math.max(1, source.split('\n').length) }, (_, index) => index + 1); } + function overlayCompletionOptions() { + if (overlayEditorTab === 'HTML') return ['
${text}
', '${text}']; + if (overlayEditorTab === 'CSS') return ['.alert { color: var(--ed-cyan); }', 'display: flex; align-items: center;']; + return ["document.querySelector('.alert')", "window.addEventListener('trixie-alert', (event) => {})"]; + } + + function insertOverlayCompletion() { + if (!overlayCompletion) return; + if (overlayEditorTab === 'HTML') overlayHtml += overlayCompletion; + if (overlayEditorTab === 'CSS') overlayCss += overlayCompletion; + if (overlayEditorTab === 'JAVASCRIPT') overlayJavascript += overlayCompletion; + overlayCompletion = ''; + } + function overlayDraftCacheKey(id: string) { return `trixie.overlay.draft.${id}`; } @@ -1584,6 +1599,7 @@ {:else if activeView === 'Overlays'}
OVERLAYS
{#if selectedOverlayId || overlayName}
{#each ['HTML', 'CSS', 'JAVASCRIPT'] as tab}{/each}
{#if overlayEditorTab === 'HTML'}
{:else if overlayEditorTab === 'CSS'}
{:else}
{/if}
LIVE PREVIEW
{#if overlayError}
{overlayError}
{/if}{:else}
Select or create an overlayDrafts autosave when explicitly saved; publishing controls the browser source.
{/if}
ALERT PLAYBACK

Configure grouping and playback for the selected browser-source overlay. Changes are saved with the next draft save.

+
EDITOR COMPLETION{overlayEditorTab}

Choose a literal starter snippet for the active source tab. Snippets are inserted as text and never executed by the editor.

{:else if activeView === 'Settings'}
SERVER SETTINGS
DATABASE BACKUPS

Daily backups use the server's local schedule. Restore replaces the current database and is permanently destructive.

{#if backupError}
{backupError}
{/if}{#if backups.length}
{#each backups as backup}
{backup.filename}{Math.round(backup.size_bytes / 1024)} KiB{backup.modified_at ? new Date(backup.modified_at).toLocaleString() : 'UNKNOWN TIME'}
{/each}
{:else}
No backup archives are available.
{/if}
{:else}