feat(analyzer): seed Letsmesh as a normal DB row and flip switch UX

Letsmesh Analyzer is now a regular analyzers row, seeded once via an
app_settings flag on first startup. It can be renamed, disabled, or
deleted like any user entry. The frontend drops the special built-in
pseudo-row and the built-in slot in the chooser.

Click resolution updated: 0 enabled → toast "No analyzer configured";
1 enabled → open directly; multiple with a default → open default;
multiple without default → chooser.

The row switch and the edit modal now show "Enabled" (checked = active),
which matches intuition. The DB column remains is_disabled so no data
migration is needed — the UI simply inverts the value on read/write.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-07-01 21:56:55 +02:00
parent ca4c77da36
commit debb711b71
6 changed files with 48 additions and 47 deletions
+19
View File
@@ -558,6 +558,25 @@ class Database:
# Analyzers (user-configured MeshCore Analyzer services)
# ================================================================
LETSMESH_ANALYZER_URL_TEMPLATE = 'https://analyzer.letsmesh.net/packets?packet_hash={packetHash}'
LETSMESH_ANALYZER_NAME = 'Letsmesh Analyzer'
_LETSMESH_SEED_FLAG = 'analyzer_letsmesh_seeded'
def seed_default_analyzers(self) -> None:
"""Seed the Letsmesh Analyzer row on first startup after this feature was added.
Uses an app_settings flag so the seed happens exactly once per installation.
If the user later renames, disables or deletes the row, we won't re-create it.
"""
if self.get_setting(self._LETSMESH_SEED_FLAG) is not None:
return
with self._connect() as conn:
conn.execute(
"INSERT OR IGNORE INTO analyzers (name, url_template) VALUES (?, ?)",
(self.LETSMESH_ANALYZER_NAME, self.LETSMESH_ANALYZER_URL_TEMPLATE)
)
self.set_setting(self._LETSMESH_SEED_FLAG, '1')
def create_analyzer(self, name: str, url_template: str) -> int:
"""Insert a new analyzer. Raises sqlite3.IntegrityError on duplicate name."""
with self._connect() as conn: