Files
floret-kit/docs/ROADMAP.md
T
makiolaj 394ac12236 feat(core-android): receiver, permission, alarm and Flow helpers
New Android module (no Compose, no DI) with broadcastTicks, a coroutine
BroadcastReceiver.goAsync, Context.hasPermission, AlarmManager.setWakeup and
Flow.stateWhileSubscribed.
2026-10-15 16:52:14 +02:00

3.8 KiB

floret-kit — roadmap

What's extracted, what's deferred, and what's deliberately not shared. The defer/skip calls come from a cross-app survey of both Calendula and Agendula — the guiding rule is to share only what is genuinely common, and to keep divergent or app-specific code where it lives.


Extracted (done)

Module Type Consumers
core-time JVM Agendula (and Calendula's pending branch)
core-reminders JVM Agendula (and Calendula's pending branch)
core-locale Android Agendula, Calendula
core-crash Android Agendula
core-prefs Android Clockula
core-di JVM Clockula
core-android Android — (Calendula pending)
identity Android Agendula
components Android Agendula
glance Android Agendula (Calendula pending — its own M3 Expressive widget pass)

See ../CHANGELOG.md for the contents of each.

Follow-ups on what's extracted

  • Migrate Calendula and Agendula onto core-prefs + core-di — Clockula triggered the extraction (the third app that made the duplication hurt) and is its only consumer today. Both siblings still carry their own ThemeMode, toEnum() and @IoDispatcher. The stored key names are identical (theme_mode, dynamic_color), so each migration is a code change with no data migration — deliberately out of scope for the extraction, and done by each sibling when it next re-pins the kit.

Deferred / not yet worth it

  • ReminderFormatting (ReminderUnit + reminderLeadTimeLabel + decomposeReminder) — the labels are @Composable over app-specific R.plurals, and the presets differ per app. Extract later behind a label/preset callback API, not before.

Deferred — needs migration first

  • core-provider (the ContentProvider seam: ColumnReader, failures, observer→Flow) — the two apps' ColumnReaders diverged (Calendula index-based, Agendula name-based + null-safe). True sharing means migrating Calendula to the better name-based design first (~a few hundred LOC), so it waits until Calendula is actively on the kit.

Not shared (by design)

  • A generic Settings scaffold — the two apps' settings domains are too divergent for a config-driven SettingsScaffold to stay readable. The win is captured instead at the component level (shared GroupedRow/section primitives + CollapsingScaffold + OptionPicker); each app composes its own settings from those.
  • The reminder scheduler — the shared core-reminders module is the app-agnostic override model only (ReminderOverride + codec + unit model, now multi-value). The delivery stays app-local: Agendula self-schedules alarms (pull), Calendula is provider-event-driven (push) — opposite architectures over incompatible data models, so forcing a shared scheduler abstraction would be leaky. A tiny core-notification (idempotent channel setup, POST_NOTIFICATIONS checks) might land later; schedulers stay app-local.
  • Domain-specific UI (date/time fields tied to a domain, calendar/timeline widgets, recurrence text, domain pickers) and all string wording — these encode each app's model and resist parameterization.

Consumers & cadence

  • Agendula consumes the kit on main (active development).
  • Clockula consumes the kit on main (active development); the first consumer of core-prefs and core-di.
  • Calendula (ships via official F-Droid reproducible builds) has a pending adoption branch. Bringing it onto the kit is where the canonical-GroupedSurface convergence becomes visible, and where the F-Droid reproducibility checklist (submodules: true in the recipe; the repro guard scanning the submodule) applies — see ARCHITECTURE.md §2 and §5.