Эх сурвалжийг харах

Web: add meshcoretel.ru profile link button next to public key

Adds a hidden `ℹ` button (meshcoretelProfileBtn) in the Public Key
field of the Info panel.  After initApp() finishes loading the
"Loading info..." section, the public key value is read from the
DOM and validated against /^[0-9A-F]{64}$/.  If it passes, an onclick
handler is attached that opens https://meshcoretel.ru/<PUBLIC_KEY>
in a new tab, and the button is made visible.  The button remains
hidden if the key fails to load or does not match the expected 64-char
uppercase hex pattern, so the UI degrades gracefully on any firmware
that does not return a valid public key.

The container div is changed from fieldline (2-column grid: 1fr auto)
to inline-actions (3-column grid: minmax(0,1fr) auto auto) to accommodate
the second action button without wrapping.
Valentin V. Bartenev 2 сар өмнө
parent
commit
8a0d04fa86

+ 8 - 1
src/helpers/web/WebPanelServer.cpp

@@ -656,9 +656,10 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
         </div>
         <div class="field-card">
           <label class="label" for="publicKey">Public Key</label>
-          <div class="fieldline">
+          <div class="inline-actions">
             <input id="publicKey" readonly disabled>
             <button id="copyPublicKeyBtn" class="iconbtn" title="Copy public key">&#x2398;</button>
+            <button id="meshcoretelProfileBtn" class="iconbtn" title="View on meshcoretel.ru" style="display:none">&#x2139;</button>
           </div>
         </div>
       </div>
@@ -2723,6 +2724,12 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
           () => loadField("clock", "clockUtc", null, quiet),
           () => loadField("get public.key", "publicKey", "uppercase", quiet)
         ]);
+        const pubKeyValue = document.getElementById("publicKey").value.trim();
+        const profileBtn = document.getElementById("meshcoretelProfileBtn");
+        if (profileBtn && /^[0-9A-F]{64}$/.test(pubKeyValue)) {
+          profileBtn.onclick = () => window.open("https://meshcoretel.ru/" + encodeURIComponent(pubKeyValue), "_blank", "noopener,noreferrer");
+          profileBtn.style.display = "";
+        }
         await loadSection("Loading repeater settings...", [
           () => loadField("get name", "nodeName", null, quiet),
           () => loadField("get lat", "nodeLat", null, quiet),