refactor: Android shared entity components — port the web's shapes #146

Merged
nalum merged 4 commits from refactor/android-shared-components into main 2026-08-18 16:43:36 +00:00
Owner

Closes #130 and the Android half of #122. PR 8 of the #137 stack, based on #145 — ports the reference surface's consolidation decisions. Four commits:

  1. Shared JobCard on Today — Android reproduced the web's job-card fork field for field: Today's inline copy lost the mark edge, repeat glyph, description and the entire due label, and carried the worth sentence under a second message id. JobCard is internal now and Today consumes it; the worth sentence lives under the web's one message id ({n, plural, one {Worth # point} …}).
  2. Shared AgendaRow — Today's event row was a hand copy of the calendar's private AgendaRow; it's internal now and Today consumes it (birthday and all-day rows keep an empty time slot).
  3. One clamped balance, one wording (#122) — RewardsRepository.balanceOf clamps at zero (the web's ruling: a balance is what you can spend); the header chip's private clamp is gone, so all five renderings agree. The Everyone row's lowercase "costs {n}"-without-the-word-points becomes the one "Costs {points}" sentence, the two "N of M done" message ids collapse onto the web's, and Today's reward strip hides a zero balance the way the web does.
  4. One Pill, one SectionHeading — Board.kt gains a Pill (border colour, optional dress; the type badge, value pill, overdue badge and switch-sheet profile chip all wear it) and SectionHeading gains a leading slot, collapsing the three hand-rolled group headings (Jobs Everyone, Rewards Everyone, calendar day headings).

Emulator-verified against the live deploy: Today's card now shows the repeat glyph, description, "Due tomorrow 18:00" and "Worth 9 points"; the Everyone view's "My jobs" heading wears my mark through the shared heading; the reward strip stayed quiet on a zero balance while still announcing ready-to-claim rewards. make check and Android unit tests green; seeded data cleaned up.

🤖 Generated with Claude Code

Closes #130 and the Android half of #122. PR 8 of the #137 stack, based on #145 — ports the reference surface's consolidation decisions. Four commits: 1. **Shared JobCard on Today** — Android reproduced the web's job-card fork field for field: Today's inline copy lost the mark edge, repeat glyph, description and the entire due label, and carried the worth sentence under a second message id. `JobCard` is internal now and Today consumes it; the worth sentence lives under the web's one message id (`{n, plural, one {Worth # point} …}`). 2. **Shared AgendaRow** — Today's event row was a hand copy of the calendar's private `AgendaRow`; it's internal now and Today consumes it (birthday and all-day rows keep an empty time slot). 3. **One clamped balance, one wording** (#122) — `RewardsRepository.balanceOf` clamps at zero (the web's ruling: a balance is what you can spend); the header chip's private clamp is gone, so all five renderings agree. The Everyone row's lowercase "costs {n}"-without-the-word-points becomes the one "Costs {points}" sentence, the two "N of M done" message ids collapse onto the web's, and Today's reward strip hides a zero balance the way the web does. 4. **One Pill, one SectionHeading** — `Board.kt` gains a `Pill` (border colour, optional dress; the type badge, value pill, overdue badge and switch-sheet profile chip all wear it) and `SectionHeading` gains a `leading` slot, collapsing the three hand-rolled group headings (Jobs Everyone, Rewards Everyone, calendar day headings). Emulator-verified against the live deploy: Today's card now shows the repeat glyph, description, "Due tomorrow 18:00" and "Worth 9 points"; the Everyone view's "My jobs" heading wears my mark through the shared heading; the reward strip stayed quiet on a zero balance while still announcing ready-to-claim rewards. `make check` and Android unit tests green; seeded data cleaned up. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Android reproduced the web's job-card fork field for field: Today's
inline copy lost the mark edge, the repeat glyph, the description and
the entire due label, and carried its own copy of the worth sentence
under a second message id (#130, porting the PR-7 web decision). The
Jobs board's JobCard is now internal and Today renders through it —
and the worth sentence lives under the web's one message id, so the
catalogs stop asking translators for the same sentence twice.
Today's event row was a hand copy of the calendar's private AgendaRow
(#130): only Today suppressed the time on birthdays, and any change to
one row shape missed the other. AgendaRow is internal now, owns the
birthday time suppression itself, and Today consumes it.
Five balance renderings computed the ledger independently and only the
header chip clamped negatives (#122): a member whose spends outran
their claims read "-5 points" on one board and "0" in the header.
RewardsRepository.balanceOf is now the one ledger, clamped like the
web's (a balance is what you can spend). The wording consolidates with
it: one "Costs …" sentence (the Everyone row's lowercase costs-
without-points goes), one "N of M done" message id, and Today's
reward strip hides a zero balance the way the web does.
refactor(android): one Pill, one SectionHeading
Some checks failed
check / commits (pull_request) Successful in 6s
check / web (pull_request) Successful in 1m36s
check / go (pull_request) Successful in 2m44s
check / report (pull_request) Successful in 4s
android / build (pull_request) Successful in 5m43s
android / report (pull_request) Successful in 4s
check / commits (push) Has been cancelled
check / go (push) Has been cancelled
check / report (push) Has been cancelled
check / web (push) Has been cancelled
tag / tag (push) Has been cancelled
android / report (push) Has been cancelled
android / build (push) Has been cancelled
a95e95efbc
Four hand-rolled 999dp pills (TypeBadge, ValuePill, ProfileChip,
OverdueBadge) and three re-implementations of SectionHeading existed
for want of a leading slot (#130 target 7). Board.kt now owns a Pill —
border colour, optional icon, one shape — that the four wear, and
SectionHeading takes a leading composable so the copies collapse.

Test report

Suite Tests Result Skipped
Unit 1370 ✅ pass 1
Integration 86 ✅ pass —

Coverage: 28.0%

Updated by the check workflow · commit a95e95efbc

<!-- ci-test-report --> ## Test report | Suite | Tests | Result | Skipped | | --- | --: | --- | --: | | Unit | 1370 | ✅ pass | 1 | | Integration | 86 | ✅ pass | — | **Coverage:** 28.0% <sub>Updated by the check workflow · commit a95e95efbcdac3336c91c84017fae569baed78a0</sub>

Android test report

Suite Tests Result Skipped
Unit (debug) 31 ✅ pass 0

Coverage: 2.4% of lines

Updated by the android workflow · commit a95e95efbc

<!-- android-test-report --> ## Android test report | Suite | Tests | Result | Skipped | | --- | --: | --- | --: | | Unit (debug) | 31 | ✅ pass | 0 | **Coverage:** 2.4% of lines <sub>Updated by the android workflow · commit a95e95efbcdac3336c91c84017fae569baed78a0</sub>
nalum changed target branch from refactor/web-shared-components to main 2026-08-18 16:43:29 +00:00
nalum merged commit a95e95efbc into main 2026-08-18 16:43:36 +00:00
nalum deleted branch refactor/android-shared-components 2026-08-18 16:43:36 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
eagraiclainne/app!146
No description provided.