fix(android): confetti in its own window, over any open sheet #285

Merged
nalum merged 1 commit from fix/android-confetti-window into main 2026-09-12 20:52:10 +00:00
Owner

Fixes #283. Stacked on #284 — merge that first.

Three celebration defects on the phone:

  • A sub-job ticked inside the job sheet handed the moment to its board. The board drew the confetti on its own canvas, under the sheet, which Material hosts in a separate window.
  • The calendar page opened the job sheet with no celebrate hook, so a points tick from a calendar row's sheet never burst.
  • The wide calendar (week, month, the day sheet) set its confetti origin, but only the phone branch composed the overlay. Those bursts never drew.

ConfettiOverlay now composes into a transparent, touch-through window of its own: a Compose Dialog with the dim, focus and touch flags cleared. It sits above whichever sheet or dialog fired it, the way the web's fixed-position canvas stacks over an open sheet. Origins move to screen coordinates so a burst fired from a sheet's window lands where the tap was. The calendar page wires onCelebrate like the Jobs and Today boards and hosts one overlay for every view.

Verified on the emulator against the e2e server. A points sub-job ticked inside the job sheet raises a third app window on top with NOT_FOCUSABLE NOT_TOUCHABLE and no dim, above the sheet's window, and it retires when the burst ends. Not checked: TalkBack behaviour with the extra window, and the wide-calendar path on a tablet geometry.

🤖 Generated with Claude Code

Fixes #283. Stacked on #284 — merge that first. Three celebration defects on the phone: - A sub-job ticked inside the job sheet handed the moment to its board. The board drew the confetti on its own canvas, under the sheet, which Material hosts in a separate window. - The calendar page opened the job sheet with no celebrate hook, so a points tick from a calendar row's sheet never burst. - The wide calendar (week, month, the day sheet) set its confetti origin, but only the phone branch composed the overlay. Those bursts never drew. `ConfettiOverlay` now composes into a transparent, touch-through window of its own: a Compose Dialog with the dim, focus and touch flags cleared. It sits above whichever sheet or dialog fired it, the way the web's fixed-position canvas stacks over an open sheet. Origins move to screen coordinates so a burst fired from a sheet's window lands where the tap was. The calendar page wires `onCelebrate` like the Jobs and Today boards and hosts one overlay for every view. Verified on the emulator against the e2e server. A points sub-job ticked inside the job sheet raises a third app window on top with `NOT_FOCUSABLE NOT_TOUCHABLE` and no dim, above the sheet's window, and it retires when the burst ends. Not checked: TalkBack behaviour with the extra window, and the wide-calendar path on a tablet geometry. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(android): confetti in its own window, over any open sheet
Some checks failed
check / commits (pull_request) Successful in 32s
android / report (pull_request) Has been cancelled
check / report (pull_request) Has been cancelled
check / web (pull_request) Has been cancelled
android / build (pull_request) Has been cancelled
check / go (pull_request) Has been cancelled
fc5275dc2b
Three celebration defects on the phone (issue #283). A sub-job ticked
inside the job sheet handed the moment to its board, and the board drew
the confetti on its own canvas — under the sheet, which Material hosts
in a separate window. The calendar page opened the job sheet with no
celebrate hook at all, so a points tick from a calendar row's sheet
never burst. And the wide calendar (week, month, the day sheet) set
its confetti origin but only the phone branch composed the overlay, so
those bursts never drew either.

ConfettiOverlay now composes into a transparent, touch-through window
of its own (a Compose Dialog with the dim, focus and touch flags
cleared), so it sits above whichever sheet or dialog fired it — the
web's fixed-position canvas, which the DOM stacks over the sheet for
free. Origins move to screen coordinates so a burst fired from a
sheet's window lands where the tap was. The calendar page wires
onCelebrate like the Jobs and Today boards, and hosts one overlay for
every view.

Verified on the emulator against the e2e server: ticking a points
sub-job inside the job sheet raises a third app window on top with
NOT_FOCUSABLE NOT_TOUCHABLE and no dim, above the sheet's window, and
it retires when the burst ends. Two emulator gotchas met on the way:
the seed's admin has reduce_motion on, and an AVD with
animator_duration_scale 0 reads as system reduce-motion — both skip
the confetti by design.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CywUhYM9usURAtwCY9338d
nalum force-pushed fix/android-confetti-window from fc5275dc2b
Some checks failed
check / commits (pull_request) Successful in 32s
android / report (pull_request) Has been cancelled
check / report (pull_request) Has been cancelled
check / web (pull_request) Has been cancelled
android / build (pull_request) Has been cancelled
check / go (pull_request) Has been cancelled
to d709727a95
All checks were successful
check / commits (pull_request) Successful in 20s
check / go (pull_request) Successful in 2m54s
check / report (pull_request) Successful in 4s
android / build (pull_request) Successful in 7m59s
android / report (pull_request) Successful in 5s
check / web (pull_request) Successful in 4m30s
check / commits (push) Successful in 32s
check / go (push) Successful in 3m0s
check / report (push) Has been skipped
check / web (push) Successful in 6m54s
android / build (push) Successful in 7m29s
android / report (push) Has been skipped
tag / tag (push) Successful in 5m8s
release / docs (push) Successful in 1m19s
release / binaries (push) Successful in 1m59s
release / android (push) Successful in 4m59s
release / image (push) Successful in 3m57s
release / module (push) Successful in 28s
release / manifests (push) Successful in 29s
release / release (push) Successful in 15s
2026-09-12 16:31:34 +00:00
Compare

Test report

Suite Tests Result Skipped
Unit 1443 ✅ pass 1
Integration 133 ✅ pass —

Coverage: 27.0%

Updated by the check workflow · commit d709727a95

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

Android test report

Suite Tests Result Skipped
Unit (debug) 275 ✅ pass 1

Coverage: 12.5% of lines

Updated by the android workflow · commit d709727a95

<!-- android-test-report --> ## Android test report | Suite | Tests | Result | Skipped | | --- | --: | --- | --: | | Unit (debug) | 275 | ✅ pass | 1 | **Coverage:** 12.5% of lines <sub>Updated by the android workflow · commit d709727a95fb7126524ba25b6d4f71b1268ba295</sub>
nalum changed target branch from fix/list-quiet-notifications to main 2026-09-12 20:51:41 +00:00
nalum merged commit d709727a95 into main 2026-09-12 20:52:10 +00:00
nalum deleted branch fix/android-confetti-window 2026-09-12 20:52:14 +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!285
No description provided.