Phase 1: foundation modules
Central Config with all tunables (retention, GPS timeout, colors, event type keys, menu item metadata). Event / EventStore handle persistence via Application.Storage with 7-day pruning. Logger mirrors the same retention. LayoutMetrics and Haversine provide resolution-independent geometry helpers. German UI strings and placeholder menu icons landed alongside so the build stays green. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6f56c337f7
commit
43f970d764
19 changed files with 409 additions and 2 deletions
73
source/EventStore.mc
Normal file
73
source/EventStore.mc
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import Toybox.Application;
|
||||
import Toybox.Lang;
|
||||
import Toybox.Time;
|
||||
|
||||
// Persists events in Application.Storage as an array of dictionaries,
|
||||
// ordered oldest → newest. Prunes entries older than Config.RETENTION_SEC
|
||||
// whenever loaded.
|
||||
module EventStore {
|
||||
|
||||
const KEY = "events";
|
||||
|
||||
function getAll() as Array<Event> {
|
||||
var raw = Application.Storage.getValue(KEY);
|
||||
if (raw == null || !(raw instanceof Array)) {
|
||||
return [];
|
||||
}
|
||||
var out = [];
|
||||
for (var i = 0; i < raw.size(); i++) {
|
||||
out.add(Event.fromDict(raw[i] as Dictionary));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function add(event as Event) as Void {
|
||||
var raw = Application.Storage.getValue(KEY);
|
||||
var arr = (raw instanceof Array) ? raw : [];
|
||||
arr.add(event.toDict());
|
||||
Application.Storage.setValue(KEY, arr);
|
||||
}
|
||||
|
||||
function deleteLast() as Boolean {
|
||||
var raw = Application.Storage.getValue(KEY);
|
||||
if (!(raw instanceof Array) || raw.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
raw = raw.slice(0, raw.size() - 1);
|
||||
Application.Storage.setValue(KEY, raw);
|
||||
return true;
|
||||
}
|
||||
|
||||
function count() as Number {
|
||||
var raw = Application.Storage.getValue(KEY);
|
||||
return (raw instanceof Array) ? raw.size() : 0;
|
||||
}
|
||||
|
||||
function latest() as Event or Null {
|
||||
var raw = Application.Storage.getValue(KEY);
|
||||
if (!(raw instanceof Array) || raw.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
return Event.fromDict(raw[raw.size() - 1] as Dictionary);
|
||||
}
|
||||
|
||||
// Drops events with timestamp < (now - retention).
|
||||
function pruneOld() as Void {
|
||||
var raw = Application.Storage.getValue(KEY);
|
||||
if (!(raw instanceof Array) || raw.size() == 0) {
|
||||
return;
|
||||
}
|
||||
var cutoff = Time.now().value() - Config.RETENTION_SEC;
|
||||
var kept = [];
|
||||
for (var i = 0; i < raw.size(); i++) {
|
||||
var d = raw[i] as Dictionary;
|
||||
var ts = d["ts"];
|
||||
if (ts != null && (ts as Number) >= cutoff) {
|
||||
kept.add(d);
|
||||
}
|
||||
}
|
||||
if (kept.size() != raw.size()) {
|
||||
Application.Storage.setValue(KEY, kept);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue