feat(firmware): drive event firmware branding from bundled metadata#5929
Conversation
Replaces the hardcoded EventEdition.kt enum mapping with the offline-first event_firmware.json contract from #5920, and surfaces the richer metadata it carries (location, dates, links, accent color) through to the UI. Adding a new event is now a data edit rather than a code change + Crowdin string + recompile. - core/model: EventFirmware{Response,Edition,Link} @serializable models matching the bundled asset and schema. - core/repository + core/data: EventFirmwareRepository, backed by a decode-once in-memory cache (no DB/network — 4 static records; a /resource/eventFirmware refresh is a later follow-up). - core/ui: data-driven LocalEventBranding; EventInfoSheet opens on app-bar tap (welcome, location, date range, links); ambient accent tint on the top app bar when connected to event firmware. Every event edition is now tappable. - feature/node: firmware-edition display name resolved from the repo. - Removes the hardcoded EventEdition.kt and the now-unused event_welcome_* strings (drops their Crowdin localization — sanctioned by #5920). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
📄 Docs staleness check — advisoryThis PR modifies user-facing UI source files but does not update any page under
Changed source files: What to check:
New page checklist (if adding a new doc page):
If this PR does not require a doc update (e.g., internal refactor, bug fix, test change), add the
|
🖼️ Preview staleness check — advisoryThis PR modifies UI composables but does not update any
Changed UI files: What to check:
Adding previews checklist:
If this PR does not require preview updates (e.g., logic-only change, non-visual refactor), add the |
Surfaces the offline-first event firmware metadata contract from #5920 in the app: event branding is now driven by the bundled
event_firmware.jsoninstead of the hardcodedEventEdition.ktmapping, and the richer fields it carries (location, dates, links, accent color) are shown to the user. Adding a new event becomes a data edit rather than a code change + Crowdin string + recompile. Builds on theBundledAssetReaderseam from #5921.🌟 New Features
EventInfoSheet.kt): tapping the event branding in the app bar opens a Material 3 bottom sheet with the welcome message, location, date range, and tappable links (LocalUriHandler). The header band uses the edition's accent color with a luminance-picked on-color for contrast.accentColor(12% oversurface), app-wide.🛠️ Refactoring & Architecture
core/model: new@SerializableEventFirmwareResponse/EventFirmwareEdition/EventFirmwareLinkmodels matching the bundled asset andschemas/event_firmware.schema.json(all fields defaulted,@JsonIgnoreUnknownKeys).core/repository+core/data: newEventFirmwareRepository(Koin@Single), backed by a decode-once in-memory cache — no DB or network, since this is a handful of static records. A/resource/eventFirmwarerefresh is a deliberate later follow-up (mirrorsDeviceLinkRepository's seed → reconcile when it lands).core/ui:UIViewModel.eventEditionandLocalEventBrandingnow carry the data model; the bundled Hamvention drawable stays code-mapped viaeventIconFor()(the data'siconUrlis null until icons are hosted).feature/node: the firmware-edition display name in the admin section is resolved from the repository.🧹 Chores
EventEdition.ktand the now-unusedevent_welcome_*string resources. This drops their Crowdin per-language localization in favor of the data's plain-EnglishwelcomeMessage— a trade-off documented and sanctioned in feat: offline-first event firmware metadata (JSON schema + bundled asset) #5920. Translationstrings.xmlfiles are left for Crowdin to reconcile.2026-05-15 – 2026-05-17);core/uihas nokotlinx-datetime, so localized formatting is left as future polish.🧪 Testing Performed
EventFirmwareRepositoryImplTest(new): lookup by enum name, null for unknown editions, absent-asset tolerance, and decode-once caching.EventBrandingTest(new):accentColorOrNull()#RRGGBBparsing, case-insensitivity, and null on malformed/missing input.spotlessCheck detekt assembleDebug test allTests kmpSmokeCompile(1733 tasks, 0 failures).