Polish pass: sysops wording, QR size, NWC toolbar, logo, diagnostics placement

Eight fixes from live testing:

Systems Operational modal:
- Drop the "test from your phone on mobile data" (hairpin NAT) sentence
  from the router note — too technical for the intended audience.
- Node-only role: when BTCPay Server and Lightning Wallet Connections
  (LNURL) are both off, the router card becomes a simple "No router
  setup needed yet" note explaining that ports 80/443 only matter if
  one of those services is turned on. When one is enabled, the card
  shows the same port steps and live domain/port diagnostics as the
  Desktop + Server role (diagnostics now poll only enabled services).

Service modals:
- The Domain Diagnostic Checklist now shows only the domain-active
  step (Domain Configured). DNS and port diagnostics live in Systems
  Operational, which shows the full checklist.
- Node-only role: BTCPay Server and Lightning Wallet Connections
  modals gain a "Ports to Forward in Your Router" section with the
  standard 80/443 wording and this computer's LAN address.
- Domain setup and reconfigure dialogs no longer contain router
  port-forwarding instructions (already handled during Desktop +
  Server onboarding and shown in Systems Operational).

Lightning Wallet Connections:
- Refresh and New Wallet toolbar buttons now share one height and
  baseline (a leftover 12px top margin on Refresh was offsetting it).
- The header status chip has a proper gap between the status dot and
  its label.

Zeus Connect / QR codes:
- QR codes render at the original 240px with the white frame and
  pixelated upscaling, restoring scannability.

Brand:
- The sidebar logo loads via /static/sovran-hub-icon.svg (same as the
  login page) instead of an inline <use> symbol — the gradient-heavy
  symbol did not render reliably. The icon sprite is hidden with the
  browser-safe zero-size pattern instead of display:none.
This commit is contained in:
2026-09-08 17:19:26 -05:00
parent d164d423ad
commit ea9d4f21d7
5 changed files with 79 additions and 50 deletions
+38 -15
View File
@@ -221,9 +221,19 @@
'</div></div>';
}
function isNodeRole() {
return (typeof _currentRole !== "undefined" && _currentRole === "node");
}
function hasEnabledDomainService(services) {
return DOMAIN_UNITS.some(function (u) {
return services.some(function (s) { return s.unit === u && s.enabled; });
});
}
function whoUsesPorts() {
if (typeof _currentRole !== "undefined" && _currentRole === "node") {
return 'On this <strong>Bitcoin Node</strong> install, BTCPay Server and Lightning Wallet Connections (LNURL) are the domain services that use these ports.';
if (isNodeRole()) {
return 'On this <strong>Bitcoin Node</strong> install, <strong>BTCPay Server</strong> and <strong>Lightning Wallet Connections (LNURL)</strong> are the domain services that use these ports.';
}
return 'All your domain services share ports 80 and 443 — Matrix, BTCPay Server, VaultWarden, Nextcloud, WordPress, Haven Relay, Lightning Wallet Connections, and Element Calling.';
}
@@ -253,14 +263,24 @@
step(3, "Turned off", "", off ? escHtml(offNames.join(", ")) : "None") +
'</div>';
/* Router ports — repo wording (domain-prereqs.js / server.py) */
html += '<div class="sysmodal-card">' +
'<div class="sysmodal-card-title">' + icon("g-wifi") + 'Router — Ports to Forward</div>' +
step(1, "Port 80", "TCP — HTTP (redirect to HTTPS)", fwd) +
step(2, "Port 443", "TCP — HTTPS", fwd) +
'<div class="sysnote"><div class="sysnote-title">' + icon("g-alert") + 'One router task</div>' +
'<div class="sysnote-desc">Set the internal and external port to the <strong>same number</strong>. You only need to do this once — all your services share these two ports. Test from your phone on mobile data (your home network may not support hairpin NAT / loopback).</div></div>' +
'</div>';
/* Router ports — repo wording (domain-prereqs.js / server.py).
Node-only role: ports matter only once BTCPay Server or Lightning
Wallet Connections (LNURL) is turned on — until then, no router task. */
if (isNodeRole() && !hasEnabledDomainService(services)) {
html += '<div class="sysmodal-card">' +
'<div class="sysmodal-card-title">' + icon("g-wifi") + 'Router</div>' +
'<div class="sysnote"><div class="sysnote-title">' + icon("g-check") + 'No router setup needed yet</div>' +
'<div class="sysnote-desc">Ports 80 and 443 only need to be forwarded on your router if you turn on <strong>BTCPay Server</strong> or <strong>Lightning Wallet Connections (LNURL)</strong>. If you enable one of them, come back here — this card will show exactly what to do.</div></div>' +
'</div>';
} else {
html += '<div class="sysmodal-card">' +
'<div class="sysmodal-card-title">' + icon("g-wifi") + 'Router — Ports to Forward</div>' +
step(1, "Port 80", "TCP — HTTP (redirect to HTTPS)", fwd) +
step(2, "Port 443", "TCP — HTTPS", fwd) +
'<div class="sysnote"><div class="sysnote-title">' + icon("g-alert") + 'One router task</div>' +
'<div class="sysnote-desc">Set the internal and external port to the <strong>same number</strong>. You only need to do this once — all your services share these two ports.</div></div>' +
'</div>';
}
/* Live domain diagnostics (sequential checklist from the backend —
same data the domain-service modals show) */
@@ -269,10 +289,13 @@
'<div id="sys-check-steps"><div class="sysfineprint">Checking…</div></div>' +
'</div>';
/* Who uses these ports */
html += '<div class="sysnote" style="margin-top:14px">' +
'<div class="sysnote-title">' + icon("g-antenna") + 'Who uses these ports</div>' +
'<div class="sysnote-desc">' + whoUsesPorts() + '</div></div>';
/* Who uses these ports (redundant on a Node install with no domain
services on — the router note above already covers it) */
if (!isNodeRole() || hasEnabledDomainService(services)) {
html += '<div class="sysnote" style="margin-top:14px">' +
'<div class="sysnote-title">' + icon("g-antenna") + 'Who uses these ports</div>' +
'<div class="sysnote-desc">' + whoUsesPorts() + '</div></div>';
}
$sysBody.innerHTML = html;
$sysModal.classList.add("open");
@@ -281,7 +304,7 @@
var checkCard = document.getElementById("sys-check-card");
var stepsEl = document.getElementById("sys-check-steps");
var units = DOMAIN_UNITS.filter(function (u) {
return services.some(function (s) { return s.unit === u; });
return services.some(function (s) { return s.unit === u && s.enabled; });
});
if (!units.length || !checkCard || !stepsEl) return;
checkCard.style.display = "";