juice_theme 0.2.0
juice_theme: ^0.2.0 copied to clipboard
App theme selection (mode + flavor) as a Juice bloc, with optional persistence behind a swappable seam.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.2.0 - 2026-09-15 #
Changed — behaviour, not cleanup (ISSUES #22) #
- Requires
juice: ^1.6.0. EveryUseCaseBuildernow declares anEventConcurrencymode:InitializeThemeEvent→droppable;SetThemeModeEvent,ToggleThemeEvent,SetFlavorEvent→sequential.commitalready emitted state synchronously before awaitingsave, so state was race-free; whatsequentialadds is that SAVES complete in the order the selections were made, so persistence can never end up holding an older selection than state (and load the wrong theme next launch). The property that comes with it, stated plainly:sequentialqueues the WHOLE use case, so a second change's emit waits behind the previous change'ssave(milliseconds withStorageThemePersistence; visible only behind a slow custom persistence). The test pins exactly that. - Known, documented: modes are keyed by exact event type —
ToggleThemeEventandSetThemeModeEventboth writemodeand are not serialized against each other. Stakes are a stale theme on next launch; a bloc-owned persist tail would close it, deferred.
Tests #
- Gated-persistence coverage: overlapping initializations coalesce to one
load; a second mode change'ssavedoes not start until the first completes.
0.1.0 - 2026-05-28 #
Added #
- Initial release.
ThemeBloc— owns the theme selection:ThemeMode+ optional named flavor.ThemePersistence— vendor seam; the bloc depends on this, not on storage, so it is testable without real storage.StorageThemePersistence— default persistence backed byStorageBloc(SharedPreferences). Passnullfor in-memory-only.- Convenience —
setMode,toggle(light⇄dark),setFlavor; gettersisDarkMode/isLightMode/isSystemMode. - Rebuild groups —
theme:mode,theme:flavor.