feat(ui): mesh header "Flash LoRa" button opens the in-app flash flow
Demo images / Build & push demo images (push) Failing after 2m9s
Demo images / Build & push demo images (push) Failing after 2m9s
Replaces the external flasher.meshcore.co.uk link with a button that opens the global device-setup modal directly at its flash step, via a new manual entry point in the mesh store (flashFlowPath). Manual opens target the connected radio (else the first detected stick), skip the read-only probe — the port is held by the live session and a second tty opener corrupts it; the backend flash job stops the listener itself — and close the modal instead of stepping back to the detection screen. Button is disabled with a hint when no radio is present. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
c99f1c7b77
commit
6ba39041d0
@@ -21,6 +21,18 @@ const mesh = useMeshStore()
|
||||
const transport = useTransportStore()
|
||||
const route = useRoute()
|
||||
|
||||
// "Flash LoRa" header button target: the connected radio wins, else any
|
||||
// detected-but-unconnected stick. Opens the global setup modal at its
|
||||
// flash step (backend stops the listener and frees the port itself).
|
||||
const flashLoraPath = computed(() =>
|
||||
(mesh.status?.device_connected && mesh.status.device_path) ||
|
||||
mesh.status?.detected_devices?.[0] ||
|
||||
''
|
||||
)
|
||||
function openFlashLora() {
|
||||
if (flashLoraPath.value) mesh.openFlashFlow(flashLoraPath.value)
|
||||
}
|
||||
|
||||
// Responsive layout breakpoints
|
||||
const isWideDesktop = ref(window.innerWidth >= 1536)
|
||||
const isVeryWideDesktop = ref(window.innerWidth >= 2560 && window.innerHeight >= 1200)
|
||||
@@ -1860,14 +1872,14 @@ async function downloadAttachment(payload: MeshAttachmentPayload) {
|
||||
<span v-else-if="mesh.status?.device_present" class="mesh-subtitle-badge">Mesh device detected</span>
|
||||
</p>
|
||||
</div>
|
||||
<a
|
||||
href="https://flasher.meshcore.co.uk/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
<button
|
||||
class="glass-button mesh-flasher-btn"
|
||||
:disabled="!flashLoraPath"
|
||||
:title="flashLoraPath ? '' : 'Plug in a LoRa radio first'"
|
||||
@click="openFlashLora"
|
||||
>
|
||||
Flash Meshcore <span class="mesh-flasher-sep">|</span> Choose Companion USB
|
||||
</a>
|
||||
Flash LoRa
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Error banner -->
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
.mesh-subtitle { color: rgba(255, 255, 255, 0.5); font-size: 0.85rem; margin: 2px 0 0; display: flex; align-items: center; gap: 8px; }
|
||||
.mesh-subtitle-badge { font-size: 0.65rem; font-weight: 600; color: #4ade80; background: rgba(74, 222, 128, 0.12); padding: 1px 6px; border-radius: 4px; text-transform: uppercase; letter-spacing: 0.5px; }
|
||||
.mesh-flasher-btn { display: inline-flex; align-items: center; gap: 0; padding: 8px 16px; font-size: 0.9rem; text-decoration: none; white-space: nowrap; flex-shrink: 0; }
|
||||
.mesh-flasher-btn:disabled { opacity: 0.45; cursor: not-allowed; }
|
||||
.mesh-flasher-sep { margin: 0 8px; color: rgba(255, 255, 255, 0.2); }
|
||||
.mesh-error { color: #ef4444; font-size: 0.85rem; padding: 8px 12px; background: rgba(239, 68, 68, 0.1); border-radius: 8px; border: 1px solid rgba(239, 68, 68, 0.2); flex-shrink: 0; }
|
||||
.mesh-columns { display: flex; gap: 16px; flex: 1; min-height: 0; overflow: hidden; }
|
||||
|
||||
Reference in New Issue
Block a user