feat(ui): Trail phase 4 — Save/Load to flash + GPX export over USB

Single-slot persistence as agreed. Action popup grows three entries
(conditional on what makes sense for the current state):

- "Save trail"  — writes the current RAM ring to /trail in LittleFS.
- "Load trail"  — only shown when /trail exists; replaces the live ring
                  with the snapshot (any active session ends first).
- "Export GPX"  — dumps the trail as a minimal GPX 1.1 document over
                  Serial so the user can capture it from a USB host.

Plumbing:
- TrailStore gains writeTo / readFrom (template on the file handle, so
  the platform-specific File flavour stays out of Trail.h) plus
  exportGpx(Stream&) for the GPX serializer. Header carries magic
  "TRAL", a version byte, point count, and the accumulated active time
  so elapsed survives the round trip.
- DataStore::openWrite is exposed publicly so callers outside DataStore
  don't have to duplicate the platform open-mode dance.
- MyMesh gains a public getDataStore() accessor.

After Load, _pending_seg_break is set so any subsequent Start opens a
new segment instead of joining the loaded last point.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-26 07:49:17 +02:00
parent bb33a23543
commit 2671e3f764
5 changed files with 154 additions and 1 deletions

View File

@@ -155,6 +155,10 @@ File DataStore::openRead(FILESYSTEM* fs, const char* filename) {
#endif
}
File DataStore::openWrite(const char* filename) {
return ::openWrite(_fs, filename);
}
bool DataStore::removeFile(const char* filename) {
return _fs->remove(filename);
}