Say it over the app when the app is what somebody is looking at
The notification stream now has three places to land instead of two, decided in one function. Nothing at all for the session on screen, as before. A banner over the app while the app is up. Android's drawer otherwise. Never two of them for one moment: a drawer filling up behind an app that showed you each one is a drawer nobody reads. The banners queue, one per session replacing that session's own -- the rule the drawer already followed, and for the same reason. Each can be tapped, which opens the session by the same path a tapped notification takes; pushed off either side; or left alone, in which case the bar across its foot retires it. The bar and the retiring are one value rather than a bar beside a timer, so a banner cannot outlive the countdown drawn under it. They clear when the app goes away, since a claim that a session wants somebody *now* does not survive an absence -- and the drawer has the job back by then. Which of the three applies needs no flag anybody keeps level. The session on screen is registered by the one composable that draws one, and "the app is up" is the queue being collected, which happens exactly while it is. Also: tapping a model or permission button while its own menu is open now closes it. A non-focusable popup does not swallow the press that dismisses it, so the same finger was reopening what it had just closed -- measured at 3ms between the two, which is what the guard is sized against. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e0eaa4b3f8
commit
be47beb0ff
6 files changed
+296
-11
No files matched your search
@@ -640,6 +640,37 @@ connectivity/lifecycle. The app keeps no persistent transcript store — the
|
||||
backend's transcript is the source of truth; the app caches only for the
|
||||
screen it's showing.
|
||||
|
||||
### Notifications: two places, never both (decided 2026-08-30)
|
||||
|
||||
The backend's `GET /notifications` is one SSE stream of attention-wanting
|
||||
moments, and the app decides where each one is said. Three outcomes, in one
|
||||
place (`NotificationService.show`):
|
||||
|
||||
- **Nothing at all** if the session is the one on screen. The transcript in
|
||||
front of the reader is already saying it.
|
||||
- **A banner over the app** if the app is up — `SessionAlerts`, queued, one
|
||||
per session replacing that session's own, dismissable by a push in either
|
||||
direction, and otherwise retiring itself when the bar across its foot runs
|
||||
out. Tapping one opens the session, through the same path a tapped
|
||||
notification uses.
|
||||
- **A row in Android's drawer** otherwise, which is what the foreground
|
||||
service exists for.
|
||||
|
||||
Never two of them for one moment. A notification that has already been shown
|
||||
in the app is not something to also find in the shade afterwards, and a
|
||||
drawer that fills up behind an app that showed you each one is a drawer
|
||||
nobody reads.
|
||||
|
||||
Which of the three applies is answered without a flag anybody has to keep
|
||||
level: the session on screen is registered by the one composable that draws
|
||||
one, and "the app is up" *is* the banner queue being collected, since it
|
||||
collects only while it is on screen.
|
||||
|
||||
The alternative considered and rejected was giving the app its own
|
||||
connection to `/notifications` while it is in front. That is a second stream
|
||||
per device saying the same thing, and it puts the "which of these two shows
|
||||
it" decision in two processes' worth of code instead of one function.
|
||||
|
||||
### Deferred polish
|
||||
|
||||
Noticed and deliberately not fixed yet, so they are not re-found from
|
||||
|
||||
Reference in new issue
Block a user