Skip to content

Pushes follow the notification settings: every message at All, @everyone unless suppressed (GRYT-1696) - #285

Merged
sivert-io merged 1 commit into
mainfrom
claude/GRYT-1696-push-follows-settings
Oct 7, 2026
Merged

sivert-io merged 1 commit into
mainfrom
claude/GRYT-1696-push-follows-settings

Conversation

@sivert-io

@sivert-io sivert-io commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Until now a push went out only for a DM or a mention of you or one of your roles. A channel set to "All messages" was silent with the app closed, and @everyone never pushed, though the desktop notifies for both. Now:

  • A channel the phone has at All pushes "New message" for every message.
  • @everyone and @here push to phones that don't suppress them.
  • Direct and role mentions, DMs and mutes work as before.

The phone sends its settings with push:register: all, the conversations at All, and everyone, whether @everyone gets through. They go in two new push_devices columns, loud and everyone. A phone that sends neither gets what it got before, so older apps are unchanged.

The phone half is Gryt-chat/mobile#314 and the docs are Gryt-chat/docs#159.

What to look at:

  • src/db/sqlite: the two columns, their migration, and loudPushAccounts, which finds accounts with a loud phone for a conversation through json_each. It's one query per channel message, on every server, whether or not anyone has a phone. It's cheap with few devices, but it is new work on the send path.
  • chat.ts: the "every message" push runs after the mention push, so a mention takes the conversation's 15-second quiet window and arrives as one notification. Each candidate is checked with mayViewChannel, so a phone that lost access stops getting them, even though its list still names the channel.
  • Muted wins: if a phone sends a conversation in both muted and all, it's dropped from all before it's stored.
  • The id limit went from 1,000 to 2,000, because all can name every channel on a server.

Tests: pushAudience.test.ts runs the real handlers against a fake relay. A phone at All gets one "message" push for a burst, and a phone left at mentions gets none. A mention in a loud channel arrives once, as a mention. The sender, someone at a screen, someone who blocked the sender and someone who lost access to the channel get nothing. Muted beats All. @everyone wakes only a phone with everyone, and bad settings are refused. Dropping either new push fails them. The helper that waited for the fake relay to go quiet for 60ms lost the first push under full-suite load. It now waits for every push in flight (pushesSettled), and the full suite passed twice in a row.

🤖 Generated with Claude Code

…@everyone unless suppressed (GRYT-1696)

Until now a push went out only for a DM or a mention of you or one of your roles. A channel set to "All messages" was silent with the app closed, and @everyone never pushed, though the desktop notifies for both. Now:

- A channel the phone has at All pushes "New message" for every message.
- @everyone and @here push to phones that don't suppress them.
- Direct and role mentions, DMs and mutes work as before.

The phone sends its settings with `push:register`: `all`, the conversations at All, and `everyone`, whether @everyone gets through. They go in two new `push_devices` columns, `loud` and `everyone`. A phone that sends neither gets what it got before, so older apps are unchanged.

The phone half is in Gryt-chat/mobile and the docs in Gryt-chat/docs (linked below).

What to look at:

- `src/db/sqlite`: the two columns, their migration, and `loudPushAccounts`, which finds accounts with a loud phone for a conversation through `json_each`. It's one query per channel message, on every server, whether or not anyone has a phone. It's cheap with few devices, but it is new work on the send path.
- `chat.ts`: the "every message" push runs after the mention push, so a mention takes the conversation's 15-second quiet window and arrives as one notification. Each candidate is checked with `mayViewChannel`, so a phone that lost access stops getting them, even though its list still names the channel.
- Muted wins: if a phone sends a conversation in both `muted` and `all`, it's dropped from `all` before it's stored.
- The id limit went from 1,000 to 2,000, because `all` can name every channel on a server.

Tests: `pushAudience.test.ts` runs the real handlers against a fake relay. A phone at All gets one "message" push for a burst, and a phone left at mentions gets none. A mention in a loud channel arrives once, as a mention. The sender, someone at a screen, someone who blocked the sender and someone who lost access to the channel get nothing. Muted beats All. @everyone wakes only a phone with `everyone`, and bad settings are refused. Dropping either new push fails them. The helper that waited for the fake relay to go quiet for 60ms lost the first push under full-suite load. It now waits for every push in flight (`pushesSettled`), and the full suite passed twice in a row.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@sivert-io
sivert-io merged commit b5bcc28 into main Oct 7, 2026
6 checks passed
@sivert-io
sivert-io deleted the claude/GRYT-1696-push-follows-settings branch October 7, 2026 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant