mirror of
https://github.com/block/buzz.git
synced 2026-11-13 04:41:12 +00:00
Expanding a Buzz notification today shows the same stub as the banner: one line of at most 180 characters, with code replaced by `[code]` and links by `[link]`. A long message can only be read by opening the app. The notification body is now the message's own text. It keeps line breaks, the text of code and bare URLs, and drops the Markdown syntax around them (`[text](url)` shows `text`). It is capped at 256 UTF-16 units, which is the most iOS shows even when a notification is expanded. iOS cuts longer bodies mid-word with no ellipsis, so the cap stops at 255 units and adds "…" without splitting a character. A link label, image alt text or bold run may contain code, and a code fence with no closing fence runs to the end of the message. The body is built from at most the first 4096 UTF-16 units of the message, so very long or hostile Markdown stays fast (under 300 ms for a 256 KB message in an optimized build); when that cut drops text, the body also ends with "…". | Before (expanded) | After (expanded) | | --- | --- | | <img width="300" alt="Before" src="https://github.com/user-attachments/assets/7201791f-9556-446a-86d2-a50f024cf9dc"> | <img width="300" alt="After" src="https://github.com/user-attachments/assets/3fa52db8-ebcf-470f-9175-47fe5ef4ed12"> | [ADR 0002](docs/adr/0002-notification-message-text.md) records the rules so other mobile platforms follow them, and the cases in `test-fixtures/notification-body.json` are the contract. The iOS tests run every case, and Android's notification code can run the same file when it lands. **What gets better, what doesn't get worse:** only the body text of message notifications changes. The title, subtitle, grouping, avatars, navigation and dedupe are untouched, and the change lives in one pure function. A notification can now show code and URLs from the message, as the message itself does, and the user's lock-screen preview setting still applies. ### Validation - Added tests: `testPreviewBodyMatchesSharedNotificationBodyCases` runs the 30 shared cases (links, mentions, images, fenced and inline code, code inside link labels and bold runs, Markdown inside code, unclosed and cut fences, whitespace, the cap at 256 and 257 units, emoji and ZWJ sequences at the cap, the 4096-unit input cut). The full BuzzPushKit suite passes: 112 XCTest and 70 Swift Testing tests. - iOS limit measured on an iPhone 17 Pro simulator (iOS 27) with a local notification: the expanded body and its accessibility label both stopped at exactly 256 UTF-16 units (256 ASCII characters, 128 emoji), cut mid-word with no ellipsis. A 40-line body showed about 31 lines. - The screenshots show this function's before and after output for the same message, posted as a local notification. The simulator doesn't run the Notification Service Extension for `simctl push`, so the full push path (relay fetch through to display) was not exercised. An iPad was not measured. - Human testing is waived; the automated run above covered display of the changed body only, since nothing else in the app changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Tom Brow <tomb@squareup.com> Co-authored-by: Tom Brow <tomb@squareup.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
72 lines
3.4 KiB
Markdown
72 lines
3.4 KiB
Markdown
# Buzz domain language
|
|
|
|
Shared terminology for Buzz product behavior. This glossary currently covers mobile [push suppression](#push-suppression), the [notification body](#notification-body) and [mobile builds](#mobile-builds); it is not a complete model of Buzz.
|
|
|
|
## Notifications
|
|
|
|
### Mobile push notification
|
|
|
|
A notification directed to a user's mobile installation through the platform's push service.
|
|
|
|
### Notification body
|
|
|
|
The text a [mobile push notification](#mobile-push-notification) shows for a message: the message's text with its Markdown syntax removed, cut only where the platform would cut it. See [ADR 0002](docs/adr/0002-notification-message-text.md).
|
|
|
|
### Push suppression
|
|
|
|
Withholding an otherwise eligible [mobile push notification](#mobile-push-notification) based on [desktop activity](#desktop-activity) and a working connection to the relevant community. It does not depend on whether desktop alerts can be shown.
|
|
|
|
_Avoid_: Read receipt, mark as read, mute
|
|
|
|
### Desktop activity
|
|
|
|
User interaction with the computer running Buzz, including interaction with another application. It is the interaction itself, not a state that lasts afterward, and does not imply that a particular Buzz message was displayed or read.
|
|
|
|
_Avoid_: Message visibility, read activity
|
|
|
|
### In-app activity
|
|
|
|
User interaction inside Buzz. Recent in-app activity remains evidence of [desktop activity](#desktop-activity) after Buzz loses focus; current window focus is a separate condition.
|
|
|
|
### Desktop inactivity
|
|
|
|
The state reached when the duration specified in the spec has elapsed since the last observed [desktop activity](#desktop-activity).
|
|
|
|
### Additional notification delay
|
|
|
|
A waiting period after [desktop inactivity](#desktop-inactivity) begins before [mobile push notifications](#mobile-push-notification) resume. This is distinct from the inactivity threshold itself.
|
|
|
|
### Suppressed message
|
|
|
|
A message whose otherwise eligible [mobile push notification](#mobile-push-notification) was withheld. The term refers to its notification, not withholding the message itself, and says nothing about whether the message has been read.
|
|
|
|
### Suppression activity signal
|
|
|
|
Information communicated for deciding whether [desktop activity](#desktop-activity) warrants [push suppression](#push-suppression). It is distinct from [visible presence](#visible-presence) and is not a read receipt.
|
|
|
|
### Visible presence
|
|
|
|
The availability status shown to other members, such as online, away, or offline. A chosen visible presence status does not necessarily reflect actual [desktop activity](#desktop-activity).
|
|
|
|
### Suppression renewal
|
|
|
|
A [suppression activity signal](#suppression-activity-signal) that extends how long [push suppression](#push-suppression) applies based on activity on one desktop.
|
|
|
|
### Inactivity cutoff
|
|
|
|
The time of the last observed [desktop activity](#desktop-activity) plus the duration specified in the spec, when [desktop inactivity](#desktop-inactivity) begins. New desktop activity moves this cutoff forward.
|
|
|
|
## Mobile builds
|
|
|
|
### Internal build
|
|
|
|
A mobile app an organization distributes only to its own members, for example through device management. It uses only that organization's Builderlab and reaches only that organization's community.
|
|
|
|
_Avoid_: Dogfood build, enterprise build, org build
|
|
|
|
### Public build
|
|
|
|
The mobile app distributed through the App Store and TestFlight. It uses only the public Builderlab and cannot reach any organization's community.
|
|
|
|
_Avoid_: App Store build, external build
|