Warning screen
- New reusable WarningPage (word-wrapped message, ENTER acknowledges and
continues to the screen you were about to enter).
- First use: pressing Play while the selected audio is still downloading.
Dynamic Audio requires every file; a fixed track requires its own file.
License re-validation
- No longer re-verifies on every Home render. Checks now run only when the
email/license key is entered or changed, on the manual option, at startup
when already due, and hourly while valid.
- Invalid + unchanged credentials are never re-checked (persisted pair).
- Valid re-checks at most once per hour, anchored on a DB timestamp so an
overdue check runs immediately after a power cycle.
- New system_kv keys track the checked pair, outcome, and last-check time.
- Added a System Settings row "Manually Validate License Key OK|Invalid"
(OK green, Invalid red, label white) that runs a check immediately.
Portal / local integration
- License validation request now sends the app version as `appVersion`.
- The entered license key is mirrored to ~/.local/radiantwave/license.txt.
Misc
- "Please connect to WiFi" only shows when no WiFi is joined AND the internet
is unreachable (fixes the NetworkManager-missing and Ethernet cases).
- Added unit tests for the audio-download warning, license scheduling policy,
license request shape, and the new settings-menu entry.
Adds api_client support for GET /licenses/{key}/schedule with If-None-Match
and target-payload parsing (version/type/daily/weekly + legacy blocks), an
atomic on-disk schedule cache, a pure schedule engine (half-open blocks,
midnight self-wrap for daily, Sunday->Monday spillover for weekly, invalid
blocks skipped with a warning), and a background ScheduleManager that loads
the cache offline and pulls on boot and every 5 minutes. Adds engine/cache
tests against the shared docs/fixtures, including 304, corrupt cache, and
offline cases.
Adds a System Name text-entry page (hint 'e.g. Living Room', 1-40 char
validation) and a data-driven System Settings row for it. Saving persists
locally and nudges the background sync; conflict/invalid results surface
the message and restore the previous name. Extends the settings-menu
tests.
Adds local System Name persistence (trimmed, 1-40) in system_kv, an
injectable sync module with conflict/invalid revert and a pending-sync
flag, a background SystemNameSync worker (retries on boot and on a timer),
and api_client support for PUT /licenses/{key}/system-name plus the
additive systemName field/systemNameStatus on license validation. The
license service sends the stored name and applies the status. Covers
validation, pending retry, and conflict revert with a faked HTTP layer.
Settings now shows Proclamations, Audio Options, System Settings, System
Logs, and Back. The new SystemSettingsPage groups Email Address, License
Key, WiFi Setup, Time Zone Setup, and Date Format, driven by the pure
settings::systemSettingEntries() list so future entries need one row, not
new menu plumbing. Adds unit tests for the entry list.
Fresh cmake configures pick up APP_VERSION/API_KEY from environment
variables (as nix develop and CI provide them); -D still wins on
reconfigure. Also normalizes indentation in the sd-bus blocks.
parseAccessPoint() is extracted from an anonymous namespace so the pure
property->AccessPointInfo mapping is testable. getAccessPoints() now reads
the Flags/WpaFlags/RsnFlags properties (they were never read, so every
network was reported Open and connections lacked a security section) and
fixes the double container-enter on the SSID 'ay' read that silently
emptied the scan list.