Post-registration and every host entry point now routes through a config overlay where the user picks encoder settings before hosting. Daemon auto-host bypasses config (non-interactive).
- commit
- 6a5c76ec2fd10168544529d393326f8c3816e2d1
- parent
- 735879286de45fdf8689fb8404fab764a258d324
- author
- dami etoile <dami.etoile@gmail.com>
| M | src/ | 140 | +++++++++++++++++++++++++++++- |
@@ -420,6 +420,30 @@
420420 outline: none;421421 border-color: var(--foreground);422422 }423+424+ /* ─── Config overlay (pre-host) ───────────────────────────────────── */425+ .config-rows { text-align: left; margin-bottom: 8px; }426+ .config-row {427+ display: flex;428+ justify-content: space-between;429+ align-items: center;430+ padding: 6px 0;431+ border-bottom: 1px solid var(--border);432+ }433+ .config-row:last-child { border-bottom: none; }434+ .config-row-label {435+ font-family: var(--mono);436+ font-size: 12px;437+ color: var(--muted-fg);438+ }439+ .config-row-value {440+ font-family: var(--mono);441+ font-size: 11px;442+ color: var(--foreground);443+ max-width: 170px;444+ text-align: right;445+ word-break: break-all;446+ }423447 </style>424448 </head>425449 <body>@@ -466,6 +490,57 @@
466490 </div>467491 </div>468492 493+ <!-- Config screen (post-registration, pre-host) -->494+ <div class="overlay-screen hidden" id="config-overlay">495+ <div class="overlay-content" style="width: 360px;">496+ <h1>configure host</h1>497+ <p>encoder settings before hosting.</p>498+ <div class="config-rows">499+ <div class="config-row">500+ <span class="config-row-label">codec</span>501+ <select id="cfg-codec" class="config-select">502+ <option value="h264">h.264</option>503+ <option value="h265">h.265</option>504+ <option value="av1">av1</option>505+ </select>506+ </div>507+ <div class="config-row">508+ <span class="config-row-label">backend</span>509+ <select id="cfg-backend" class="config-select">510+ <option value="auto">auto</option>511+ <option value="nvenc">nvenc</option>512+ <option value="vaapi">vaapi</option>513+ <option value="qsv">qsv</option>514+ <option value="amf">amf</option>515+ <option value="videotoolbox">videotoolbox</option>516+ <option value="software">software</option>517+ </select>518+ </div>519+ <div class="config-row">520+ <span class="config-row-label">bitrate</span>521+ <input id="cfg-bitrate" class="config-input" type="text" value="8M" />522+ </div>523+ <div class="config-row">524+ <span class="config-row-label">framerate</span>525+ <input id="cfg-framerate" class="config-input" type="number" value="30" min="1" max="60" />526+ </div>527+ <div class="config-row">528+ <span class="config-row-label">gop</span>529+ <input id="cfg-gop" class="config-input" type="number" value="30" min="1" max="120" />530+ </div>531+ <div class="config-row">532+ <span class="config-row-label">available</span>533+ <span class="config-row-value" id="cfg-available">—</span>534+ </div>535+ </div>536+ <div style="display: flex; gap: 16px; justify-content: center; margin-top: 20px;">537+ <button class="overlay-btn" onclick="configBack()">back</button>538+ <button class="overlay-btn" onclick="configHost()">host</button>539+ </div>540+ <div class="overlay-status" id="config-status"></div>541+ </div>542+ </div>543+469544 <!-- Top bar -->470545 <div class="topbar">471546 <span class="brand">keyhome</span>@@ -703,8 +778,14 @@
703778 result.node_id.substring(0, 16) + '...';704779 document.getElementById('action-main').textContent = 'host';705780 document.getElementById('action-unreg').style.display = '';706- // Show intro again with registered state707- await checkRegistration();781+ // Set up registered intro state (so "back" from config works)782+ document.getElementById('intro-unregistered').style.display = 'none';783+ document.getElementById('intro-registered').style.display = 'block';784+ document.getElementById('reg-status').textContent = 'registered';785+ document.getElementById('reg-node-id').textContent =786+ result.node_id.substring(0, 24) + '...';787+ // Show config screen before hosting788+ showConfigScreen();708789 } else {709790 hideTap();710791 showIntro();@@ -761,7 +842,58 @@
761842 762843 async function introHost() {763844 hideIntro();764- await startHost();845+ showConfigScreen();846+ }847+848+ // ─── Config screen (pre-host) ──────────────────────────────────────849+ async function showConfigScreen() {850+ // Load current encoder config into the config overlay851+ try {852+ const config = await invoke('get_encoder_config');853+ document.getElementById('cfg-codec').value = config.codec;854+ document.getElementById('cfg-backend').value = config.backend;855+ document.getElementById('cfg-bitrate').value = config.bitrate;856+ document.getElementById('cfg-framerate').value = config.framerate;857+ document.getElementById('cfg-gop').value = config.gop;858+ } catch (e) { console.error('config load failed:', e); }859+ try {860+ const available = await invoke('detect_available_encoders');861+ document.getElementById('cfg-available').textContent = available.join(', ') || 'none';862+ } catch (e) {863+ document.getElementById('cfg-available').textContent = 'ffmpeg not found';864+ }865+ document.getElementById('config-status').textContent = '';866+ document.getElementById('config-overlay').classList.remove('hidden');867+ }868+869+ function hideConfigScreen() {870+ document.getElementById('config-overlay').classList.add('hidden');871+ }872+873+ function configBack() {874+ hideConfigScreen();875+ showIntro();876+ }877+878+ async function configHost() {879+ const status = document.getElementById('config-status');880+ status.className = 'overlay-status pending';881+ status.textContent = 'saving...';882+ try {883+ const config = {884+ codec: document.getElementById('cfg-codec').value,885+ backend: document.getElementById('cfg-backend').value,886+ bitrate: document.getElementById('cfg-bitrate').value,887+ framerate: parseInt(document.getElementById('cfg-framerate').value) || 30,888+ gop: parseInt(document.getElementById('cfg-gop').value) || 30,889+ };890+ await invoke('set_encoder_config', { config });891+ hideConfigScreen();892+ await startHost();893+ } catch (e) {894+ status.className = 'overlay-status err';895+ status.textContent = 'error: ' + e;896+ }765897 }766898 767899 // ─── Host ───────────────────────────────────────────────────────────@@ -823,7 +955,7 @@
823955 // Hosting state uses disconnect button, not main action824956 return;825957 } else if (registered) {826- await startHost();958+ showConfigScreen();827959 } else {828960 // Not registered — show intro for registration829961 showIntro();