Files
namandClaude Opus 5.5 b0e3b805b1 guestlink v1: self-hosted guest line (Cleanfeed replacement)
Go + Pion + libopus. One guest, live audio both ways, anonymous chat.
README for this version was not preserved; see the next commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 16:14:00 -06:00

31 lines
1.7 KiB
JavaScript

'use strict';
const $ = s => document.querySelector(s);
function wsURL(path){ return (location.protocol === 'https:' ? 'wss://' : 'ws://') + location.host + path; }
function fmtTime(ts){ const d = new Date(ts); return d.toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'}); }
// Render a chat message. `mine` = which side this page is ('host' | 'guest'). Text only - never innerHTML.
function renderMsg(log, m, mine){
const el = document.createElement('div');
el.className = 'msg ' + (m.who === 'system' ? 'system' : (m.who === mine ? 'me' : 'them'));
if (m.who !== 'system') {
const w = document.createElement('span'); w.className = 'who';
w.textContent = (m.who === mine ? 'You' : m.from) + ' · ' + fmtTime(m.ts);
el.appendChild(w);
}
el.appendChild(document.createTextNode(m.text));
const atBottom = log.scrollHeight - log.scrollTop - log.clientHeight < 40;
log.appendChild(el);
if (atBottom || m.who === mine) log.scrollTop = log.scrollHeight;
}
function setMeter(el, peak){ // peak 0..1 linear -> bar on a -60..0 dBFS scale
const db = peak > 0 ? 20*Math.log10(peak) : -100;
const pct = Math.max(0, Math.min(100, (db + 60) / 60 * 100));
el.style.width = pct + '%';
el.className = db > -1 ? 'clip' : (db > -9 ? 'hot' : '');
return db;
}
function chatForm(form, ta, send){
form.addEventListener('submit', e => { e.preventDefault(); const t = ta.value.trim(); if (t) { send(t); ta.value=''; } ta.focus(); });
ta.addEventListener('keydown', e => { if (e.key === 'Enter' && !e.shiftKey && !e.isComposing) { e.preventDefault(); form.requestSubmit(); } });
}
function store(k, v){ try { if (v === undefined) return localStorage.getItem(k); localStorage.setItem(k, v); } catch(e) { return null; } }