fix(meshcore): fix layout height, connection polling, and modal visibility

- Add base flex properties to #meshcoreVisuals so it fills full panel
  height when meshtastic.css hasn't been lazily loaded yet
- Poll /meshcore/status every 2s after Connect click so the UI
  transitions out of "Connecting..." when the backend is ready
- Fix Add Contact and Traceroute modals to use .show class pattern
  (signal-details-modal uses opacity/visibility transitions, not display)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
James Smith
2026-05-13 16:59:59 +01:00
parent 7c535d7ba8
commit 2cdf156cd0
2 changed files with 35 additions and 10 deletions
+5 -1
View File
@@ -20,9 +20,13 @@
max-width: 100% !important; max-width: 100% !important;
} }
/* ── Container overrides ── */ /* ── Visuals container (base rules duplicated from meshtastic.css — lazy-load safety) ── */
#meshcoreVisuals { #meshcoreVisuals {
display: flex;
flex-direction: column; flex-direction: column;
flex: 1;
min-height: 0;
overflow: hidden;
padding: 0; padding: 0;
gap: 0; gap: 0;
} }
+30 -9
View File
@@ -86,9 +86,21 @@ const MeshCore = (function () {
body.address = document.getElementById('meshcoreBleSelect').value || null; body.address = document.getElementById('meshcoreBleSelect').value || null;
} }
try { try {
await fetch('/meshcore/connect', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
_updateStatusUI('connecting'); _updateStatusUI('connecting');
} catch (e) { console.error('Connect failed:', e); } await fetch('/meshcore/connect', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
_pollUntilConnected(0);
} catch (e) {
_updateStatusUI('error', 'Connection failed');
console.error('Connect failed:', e);
}
}
function _pollUntilConnected(attempts) {
if (_connected || attempts > 15) return;
setTimeout(async () => {
await _checkStatus();
if (!_connected) _pollUntilConnected(attempts + 1);
}, 2000);
} }
async function disconnect() { async function disconnect() {
@@ -383,23 +395,32 @@ const MeshCore = (function () {
container.appendChild(arrow); container.appendChild(arrow);
} }
}); });
modal.style.display = 'flex'; _openModal(modal);
} }
function closeTraceroute() { function closeTraceroute() {
const modal = document.getElementById('meshcoreTracerouteModal'); _closeModal(document.getElementById('meshcoreTracerouteModal'));
if (modal) modal.style.display = 'none';
} }
// ── Contacts ─────────────────────────────────────────────────────────── // ── Contacts ───────────────────────────────────────────────────────────
function showAddContact() { function showAddContact() {
const modal = document.getElementById('meshcoreAddContactModal'); _openModal(document.getElementById('meshcoreAddContactModal'));
if (modal) modal.style.display = 'flex';
} }
function closeAddContact() { function closeAddContact() {
const modal = document.getElementById('meshcoreAddContactModal'); _closeModal(document.getElementById('meshcoreAddContactModal'));
if (modal) modal.style.display = 'none'; }
function _openModal(modal) {
if (!modal) return;
modal.style.display = '';
requestAnimationFrame(() => modal.classList.add('show'));
}
function _closeModal(modal) {
if (!modal) return;
modal.classList.remove('show');
setTimeout(() => { modal.style.display = 'none'; }, 200);
} }
async function saveContact() { async function saveContact() {