New Android module (no Compose, no DI) with broadcastTicks, a coroutine
BroadcastReceiver.goAsync, Context.hasPermission, AlarmManager.setWakeup and
Flow.stateWhileSubscribed.
IconInfoCard for the detail/edit cards, OnboardingScaffold headline/supporting
plus OnboardingPrimaryButton, and header/predictiveBack on LanguagePickerRow.
GroupedRow gains checked, OptionPicker gains dismissOnSelect and exposes its
rows as OptionRows. New GroupedSwitchRow, CustomExpandRow, GroupedHint and
ExpandIcon. Every existing call keeps its behaviour.
ColorScheme.toPureBlack() sets background, surface, surfaceDim and
surfaceContainerLowest to #000 and dims the other containers by scaling
their sRGB channels, so their hue tint carries over and grid tiles drawn
as containers over surface keep visible gaps. FloretExpressiveTheme takes
pureBlack to apply it to the dark scheme, dynamic or app-supplied.
core-prefs gains ThemeMode.BLACK (dark, pure black) and
ThemeMode.isPureBlack, stored under the same theme_mode key.
Brings the branches the sibling apps actually ship from back onto main, so floret-kit stops forking per project.
Merged in:
- `vouch/settings` (what vouch pins), which already contains `feat/clockula` (what clockula pins) and `chore/deps-2026-10`: core-prefs, core-di, CollapsingScaffold FAB/no-back slots, the glance module, LocaleManager on API 33+, and the dependency bump
- `feat/glance-module`: the three glance commits clockula's branch didn't have yet (progress ring/tile/check button, expressive shapes + header pill, WidgetDoneState)
Both merged without conflicts. Version ends up at 0.7.0 (untagged).
Heads-up for consumers: the deps bump moves the toolchain to Gradle 9.8.0 / AGP 9.4.1 / Kotlin 2.4.20. Since floret-kit is a composite build, a consumer must be on Gradle >= 9.6 to pin anything from here on. Calendula builds, tests and lints against this branch with just that toolchain bump, no source changes.
Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/floret-kit/pulls/11
The issue the crash flow prefills took its title and body from string
resources, so both followed the device language: a crash on a French
phone opened the tracker with a French issue, which is unreadable to
whoever has to triage it. The report itself was always English — only
the wrapper around it wasn't.
That text is posted rather than shown, so it is no longer a resource at
all: title and body are fixed English in CrashReportSubmit, and
CrashConfig drops issueTitle (apps pass one fewer argument and can
delete their own crash_report_issue_title / crash_report_body_* strings).
What the reporter sees in the app — the dialog, the toasts, the
clipboard label — stays translated, which is the line the kdoc and the
resource header now draw.
A connected list for a procedure the user has to carry out somewhere
else. Collapsible, so it can be shown again as a reference once it has
already had a screen of its own.
The header was invented here rather than converged from the app that
already had one. Calendula's SectionHeader is labelLarge at top 16 /
bottom 4, and separates one group from the next with the caller's own 8dp
spacer — a hub's first header follows the About card, not another group,
so the gap cannot live on the header. Matched exactly, so the two apps'
settings hubs are the same page.
A settings page with a dozen categories in one flat run has no way to say
which of them are about how the app behaves and which are about the app
itself. GroupedSectionHeader is that label: it starts on GroupedListInset,
the edge the cards it names start on, and owns the gap to the group above,
so a page writes header-then-rows and nothing else.
primary rather than onSurfaceVariant — after the Android-15 settings
pattern Position already follows, and because a header that matches the
summaries underneath it stops separating anything.
ScaledViewPreview measures real screen composables at a phone viewport and
scales the finished layout down; ViewPreviewFrame is the tonal plate it sits
on, cross-fading between options at the grouped rows' width and radius so
preview and options read as one stack.
Converged from Calendula's view and month-style choosers, where the pattern
was invented, and now Agendula's quick-add step. The viewport height is a
parameter here rather than a calendar-shaped constant.
GroupedRow's container had no `on*` pair, so a row given a tint kept its
text on onSurface — readable by luck rather than by the theme. Wanted by a
status row that colours itself by outcome.
KeyboardType.Password only tells the IME to drop suggestions; without a
visual transformation a borderless password field renders the secret in
the clear.
The per-app-language store re-parses the applied locale through ICU and
fills in the implied script, so a zh-CN choice reads back as zh-Hans-CN and
no longer matches the tag the picker offers — the selected row lost its
mark after a restart. currentTag(supported) maps it back.
Two new components since 0.2.1 — the onboarding shell (OnboardingScaffold,
OnboardingProgress, BenefitRow) that Calendula's first-run wizard is built
on, and SnackChip, the compact confirmation converged from Agendula's and
Calendula's undo chips — plus grouped-list and picker richness (long-press
rows, styled row text, exported GroupedListInset, per-option summaries,
public SelectedCheck, AboutCard in a group) and two fixes: all-day values
rendering a day early west of UTC, and full-screen picker bar icons
following the XML theme rather than the running one.
The changelog had gone unwritten since 0.2.1; this backfills every entry.
A step whose content is taller than the screen loses room to a pinned bar,
and the bar hides that there is more below it. scrollingActions moves the
call-to-action stack to the end of the scrolling column instead.
A step that can be stepped back from passes navigationIcon. The slot's
width is reserved whether or not it is filled, and mirrored on the other
side, so the progress stays centred as steps come and go.
contentPadding lets a step built from grouped rows drop the column's own
inset, since those rows carry their own.
A multi-step flow passes a progress slot, pinned above the scrolling
content, and OnboardingProgress draws it as one capsule per step with the
caller's own localised label. topSpacing lets a step whose hero is a large
picture rather than a mark keep the content on one screen.
GroupedRow took plain Strings, so a caller that needs emphasis inside the
title or summary — a search hit marking what it matched — had no way in short
of rebuilding the row. Adds an AnnotatedString overload and delegates the
String one to it.
GroupedSurface/GroupedRow gain onLongClick (with the platform long-press
haptic), for lists that enter a selection mode from a row — Calendula's
search results (#80).