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>
31 lines
1.7 KiB
JavaScript
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; } }
|