fix(ui): don't nuke the registered panel's children on status update

Regression from 20375ec: the `signal-event reconnecting` and
`signal-event registered` handlers were assigning to
`directRegistered.textContent`, which is the PARENT element that
holds the entire registered UI — the "Registered — waiting"
header, incoming-call panel, recent-contacts section, call
history, the fingerprint-input bar, and the Call button. Setting
textContent on that parent wiped every child with a single text
node, so after registration the user saw " Registered" with
NOTHING below it — no call input, no history, no call button.
App unusable post-registration.

Fix:
- Add a dedicated `#registered-status` <p> inside the header of
  `#direct-registered` (this element already existed as a plain
  paragraph without an id; just giving it an id).
- Rewrite both handlers to target that element by id instead of
  the parent, so `textContent =` only touches the status line
  and leaves the rest of the panel intact.
- The `registered` handler now also explicitly
  `registerBtn.classList.add("hidden")` and
  `directRegistered.classList.remove("hidden")` so the first
  register event correctly reveals the UI. Belt-and-braces for
  the transparent-reconnect case too — if the supervisor
  re-registers after a drop, the UI stays in the registered
  state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-11 19:28:16 +04:00
parent b7a48bf13b
commit 05ec926317
2 changed files with 24 additions and 9 deletions

View File

@@ -52,7 +52,7 @@
<button id="register-btn" class="primary" style="background:#2196F3">Register on Relay</button>
<div id="direct-registered" class="hidden" style="margin-top:12px">
<div class="direct-registered-header">
<p style="color:var(--green);font-size:13px;margin:0">&#x2705; Registered — waiting for calls</p>
<p id="registered-status" style="color:var(--green);font-size:13px;margin:0">&#x2705; Registered — waiting for calls</p>
<button id="deregister-btn" class="secondary-btn small">Deregister</button>
</div>
<div id="incoming-call-panel" class="hidden" style="background:#1B5E20;padding:12px;border-radius:8px;margin:8px 0">

View File

@@ -1423,23 +1423,38 @@ listen("signal-event", (event: any) => {
break;
case "reconnecting":
// Signal supervisor is retrying the relay connection. Show
// a non-blocking indicator; the user can keep using
// everything that doesn't need a live signal.
// a non-blocking indicator on the small status line INSIDE
// the registered panel — do NOT touch directRegistered
// itself, that's the parent that holds the entire
// registered UI (address bar, call button, history, ...)
// and overwriting its textContent wipes all children.
{
const relay = typeof data.relay === "string" ? data.relay : "relay";
directRegistered.textContent = `🔄 reconnecting to ${relay}`;
directRegistered.style.color = "var(--yellow)";
directRegistered.classList.remove("hidden");
const status = document.getElementById("registered-status");
if (status) {
status.textContent = `🔄 reconnecting to ${relay}`;
(status as HTMLElement).style.color = "var(--yellow)";
}
}
break;
case "registered":
// Supervisor (re-)succeeded, or the first register landed.
// Clear the banner and show the registered state.
// Clear the reconnecting badge and keep the registered UI.
{
const fp = typeof data.fingerprint === "string" ? data.fingerprint : "";
directRegistered.textContent = `✓ registered${fp ? ` (${fp.slice(0, 16)}…)` : ""}`;
directRegistered.style.color = "var(--green)";
const status = document.getElementById("registered-status");
if (status) {
status.textContent = fp
? `✅ Registered (${fp.slice(0, 16)}…)`
: "✅ Registered — waiting for calls";
(status as HTMLElement).style.color = "var(--green)";
}
// Make sure the registered panel is visible and the
// Register button is hidden. This is the critical path
// both for the first register and for a transparent
// supervisor-driven reconnect.
directRegistered.classList.remove("hidden");
registerBtn.classList.add("hidden");
}
break;
}