Post the drawer's row behind the app's own banner

A notification arriving while the app was open was shown as a banner and
nowhere else, so a moment that happened while the phone was face-up on a desk
left nothing behind at all -- the banner is seconds long and reaches only
somebody already looking.

The two are not two versions of one thing: a banner interrupts and a row
records. Both go up now, and the banner having done the interrupting is what
makes the row a silent one (`setSilent`), so one moment is worth a noise once.
What keeps the drawer from filling up is the other end rather than suppression,
and already was: opening a session clears whatever is posted about it, whichever
way the reader got there.

Checked with ktfmtFormat, compileDebugKotlin, testDebugUnitTest and lintDebug,
and on the emulator against the sandbox, reading the posted record out of
dumpsys: app on the session list gives a banner and flags=AUTO_CANCEL|SILENT;
app backgrounded gives flags=AUTO_CANCEL; opening the session leaves nothing
posted about it in either case.
This commit is contained in:
iris-ai committed 2026-09-15 02:06:12 -04:00
1 parent 1e52b2910c
commit 0be15adbee
3 files changed
+45 -26

No files matched your search

+24 -14
View File
@@ -1184,26 +1184,36 @@ load-bearing** — every path that reads it has a network path beside it giving
the same answer. What the app does not keep is anything *derived*: the folded
rows are rebuilt from events every time.
### Notifications: two places, never both (2026-08-30)
### Notifications: the record and the interruption (2026-08-30, revised
2026-09-15)
`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`):
app decides how each one is said, 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.
- **A row in Android's drawer** otherwise, which is what the foreground
service exists for.
- **A row in Android's drawer** for everything else, which is what the
foreground service exists for.
- **A banner over the app as well** 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. The drawer's row is posted **silently** in that case
(`setSilent`), because the banner has already done the interrupting.
Never two of them for one moment. 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 two are not two versions of one thing, which is why both go up. A banner
is six seconds long and reaches only somebody whose eyes were on the screen,
so it is what interrupts; a row waits however long it has to, so it is what
records. Until 2026-09-15 the banner suppressed the row outright, and a
notification that arrived while the phone was face-up on a desk left nothing
behind at all.
What keeps the drawer from filling up is the other end rather than
suppression: **opening a session clears whatever is posted about it**
(`NotificationService.showing`), whichever way the reader got there, because
opening it is reading the notification. Which case 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.
**What counts as finished** is decided in `notification_for`, and since
2026-08-31 it takes the number of messages the session has been given and not