From 88dc52dd69b15b3bb389ba7ac3c6e7c7afdd9ba0 Mon Sep 17 00:00:00 2001 From: "every.channel" Date: Fri, 20 Feb 2026 22:43:32 -0800 Subject: [PATCH] web: lazy-load hang element so query params still initialize --- apps/web/app.js | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/apps/web/app.js b/apps/web/app.js index 1a2e388..42bbcc3 100644 --- a/apps/web/app.js +++ b/apps/web/app.js @@ -3,10 +3,9 @@ // This uses the upstream hang web component (WebTransport + WebCodecs). // It is intentionally dependency-light: no framework, no bundler. -// Use an ESM CDN that rewrites bare module specifiers. -import "https://esm.sh/@kixelated/hang@0.7.4/watch/element.js"; - const DEFAULT_RELAY_URL = "https://interop-relay.cloudflare.mediaoverquic.com/"; +const HANG_WATCH_MODULE_URL = "https://esm.sh/@kixelated/hang@0.7.4/watch/element.js"; +let hangWatchModulePromise = null; function $(id) { const el = document.getElementById(id); @@ -65,6 +64,17 @@ function mountPlayer(relayUrl, name) { mount.appendChild(watch); } +async function ensureHangWatchElement() { + if (window.customElements && window.customElements.get("hang-watch")) return; + if (!hangWatchModulePromise) { + hangWatchModulePromise = import(HANG_WATCH_MODULE_URL); + } + await hangWatchModulePromise; + if (!(window.customElements && window.customElements.get("hang-watch"))) { + throw new Error("hang-watch custom element is unavailable"); + } +} + async function copyToClipboard(text) { if (!text) return; if (navigator.clipboard && navigator.clipboard.writeText) { @@ -122,7 +132,7 @@ function main() { setShareLink(currentShareLink(relayUrl, name)); } - function start() { + async function start() { const relayUrl = normalizeRelayUrl(relayInput.value); const name = normalizeName(nameInput.value); @@ -141,6 +151,16 @@ function main() { return; } + try { + await ensureHangWatchElement(); + } catch (e) { + setHint( + `Failed to load web player dependency: ${String(e)}. Disable script blockers for esm.sh and retry.`, + "warn", + ); + return; + } + writeParams(relayUrl, name); setHint(`Connecting to relay and subscribing: ${name}`, "ok"); mountPlayer(relayUrl, name); @@ -149,9 +169,11 @@ function main() { relayInput.addEventListener("input", updateSharePreview); nameInput.addEventListener("input", updateSharePreview); - watchBtn.addEventListener("click", start); + watchBtn.addEventListener("click", () => { + void start(); + }); nameInput.addEventListener("keydown", (e) => { - if (e.key === "Enter") start(); + if (e.key === "Enter") void start(); }); copyBtn.addEventListener("click", async () => { @@ -175,7 +197,7 @@ function main() { updateSharePreview(); // Auto-start if a name was provided. - if (initial.name) start(); + if (initial.name) void start(); } main();