Skip to content

feat: support browser notifications for remotes - #996

Merged
paulinevos merged 3 commits into
dev-null-sh:productionfrom
paulinevos:remotes-notifications
Oct 23, 2026
Merged

paulinevos merged 3 commits into
dev-null-sh:productionfrom
paulinevos:remotes-notifications

Conversation

@paulinevos

@paulinevos paulinevos commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Turning off notification sounds in account settings:

image

Muting a specific remote:
image

Copilot AI balanced review requested due to automatic review settings October 22, 2026 20:14
Comment thread app/Actions/CreateExport.php Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Alert coordination can produce unwanted cross-tab notifications and miss unread org messages when membership events follow them.

3 open issues
What changed in this PR

Adds browser notifications and sound to Remotes, with per-browser preferences and account-wide conversation mutes integrated into the existing chat system.

Changes:

  • Adds background alert polling, permission controls, cooldown handling, and notification navigation.
  • Adds timed and permanent mutes through web/API endpoints, chat menus, and account exports.
  • Expands tests and documentation, and clears stale attachment errors in the composer.
File Description
tests/​Unit/​RemoteNotifications.test.tsx Tests alert filtering, cooldowns, permissions, and polling.
tests/​Unit/​ImageAttachments.test.tsx Tests clearing attachment errors without removing images.
tests/​Unit/​Actions/​DeleteUserTest.php Verifies mute cleanup on account deletion.
tests/​tsconfig.json Includes notification tests in type checking.
tests/​Feature/​Controllers/​ExportControllerTest.php Tests account-scoped mute exports.
tests/​Feature/​Controllers/​ConversationMuteControllerTest.php Tests web mute behavior and authorization.
tests/​Feature/​Controllers/​Api/​ConversationMuteControllerTest.php Tests API mute behavior and authorization.
tests/​draft-images.config.ts Registers notification tests.
routes/​web.php Adds web mute routes.
routes/​api.php Adds API mute routes.
resources/​js/​types/​conversation.ts Adds mute timestamps to chat types.
resources/​js/​lib/​remote-notifications.ts Implements notification preferences, filtering, sound, and cooldowns.
resources/​js/​lib/​chat.ts Integrates alerts, focus-aware reads, and mute updates.
resources/​js/​layouts/​app-layout.tsx Starts alerts for eligible signed-in users.
resources/​js/​hooks/​use-image-attachments.ts Exposes attachment-error clearing.
resources/​js/​hooks/​use-chat.ts Adds alert preference and lifecycle hooks.
resources/​js/​components/​remotes-setting.tsx Adds notification preference and permission controls.
resources/​js/​components/​chat/​conversation-thread.tsx Handles focus-aware reads and clears composer errors.
resources/​js/​components/​chat/​conversation-actions.tsx Adds mute and unmute controls.
public/​sw.js Handles service-worker notification clicks.
PRODUCT.md Updates the notification feature summary.
KNOWLEDGE_BASE.md Documents alert behavior and conversation mutes.
database/​migrations/​2026_10_22_120000_add_muted_until_at_to_conversation_participants_table.php Stores participant-specific mute expiry.
app/​Queries/​ConversationThreadQuery.php Returns active mute timestamps in threads.
app/​Queries/​ConversationsQuery.php Includes active mute timestamps in inbox summaries.
app/​Models/​ConversationParticipant.php Casts and documents participant mute timestamps.
app/​Models/​Conversation.php Casts and documents selected mute timestamps.
app/​Http/​Resources/​OrgThreadResource.php Updates the documented org-thread shape.
app/​Http/​Resources/​ConversationThreadResource.php Updates the documented direct-thread shape.
app/​Http/​Resources/​ConversationResource.php Documents mute data in inbox summaries.
app/​Http/​Requests/​UpdateOrgMuteRequest.php Authorizes and validates web org mutes.
app/​Http/​Requests/​UpdateConversationMuteRequest.php Authorizes and validates web direct mutes.
app/​Http/​Requests/​UpdateApiOrgMuteRequest.php Authorizes and validates API org mutes.
app/​Http/​Requests/​UpdateApiConversationMuteRequest.php Authorizes and validates API direct mutes.
app/​Http/​Controllers/​OrgMuteController.php Handles web org mute updates.
app/​Http/​Controllers/​ConversationMuteController.php Handles web direct mute updates.
app/​Http/​Controllers/​Api/​OrgMuteController.php Handles API org mute updates.
app/​Http/​Controllers/​Api/​ConversationMuteController.php Handles API direct mute updates.
app/​Enums/​ConversationMuteDuration.php Defines mute durations and expiry calculation.
app/​Actions/​UpdateConversationMute.php Persists the current participant’s mute.
app/​Actions/​CreateExport.php Exports mute preferences and shares recipient formatting.

Review effort: Balanced

Comment thread resources/js/lib/chat.ts
Comment thread resources/js/lib/remote-notifications.ts Outdated
Comment thread resources/js/lib/remote-notifications.ts
Clear text and attachment errors when editing or sending, without discarding valid attachments.

Amp-Thread-ID: https://ampcode.com/threads/T-01a164f2-f78a-744d-9919-ba1ca2383eed
Co-authored-by: Pauline Vos <pvos88@gmail.com>
@paulinevos
paulinevos force-pushed the remotes-notifications branch from e0781b7 to 4caa831 Compare October 22, 2026 21:01
Comment thread app/Queries/ConversationsQuery.php
@xHeaven

xHeaven commented Oct 22, 2026

Copy link
Copy Markdown
Member
  • I'd prefer being able to separately control notification popups and sounds in Remotes. In the Settings we could probably drop the "sounds" part, since we are not actually asking for permission for sounds, only for the popups.
  • If I'm watching the Remotes page, I don't think I want to get notifications and sounds from Chat B if I'm currently watching Chat A, since both are technically right in front of me on the sidebar, the "x ahead" thingy is enough visual cue there already imo.
  • For muting, I'd prefer having an "Until tomorrow" switch.
  • For notifications, I'd prefer having separate notification controls, on a per-chat basis (groups only, doesn't make sense for 1on1): Everything, Mentions only, Nothing

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread app/Queries/ConversationsQuery.php
Comment thread resources/js/components/chat/conversation-actions.tsx Outdated
Comment thread resources/js/components/chat/conversation-actions.tsx
Comment thread resources/js/hooks/use-chat.ts
@paulinevos
paulinevos force-pushed the remotes-notifications branch 3 times, most recently from 8eac917 to 80d65a8 Compare October 23, 2026 08:34
@paulinevos
paulinevos requested a balanced review from Copilot October 23, 2026 08:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread resources/js/lib/chat.ts Outdated
Comment thread resources/js/lib/remote-notifications.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Cross-conversation cursor ordering can permanently suppress new-message alerts, and repeated history-wide baseline queries add avoidable database work.

2 open issues
4 resolved since last review

Review effort: Balanced

Comment thread resources/js/lib/remote-notifications.ts Outdated
Comment thread app/Http/Controllers/InboxController.php Outdated
ampagent and others added 2 commits October 23, 2026 11:47
Support one-hour, eight-hour, week-long, permanent, and cleared mutes for direct conversations and orgs through web and signed API endpoints. Expose only the current participant’s preference, preserve unread counts, and include mutes in export and account deletion coverage.

Amp-Thread-ID: https://ampcode.com/threads/T-01a164f2-f78a-744d-9919-ba1ca2383eed
Co-authored-by: Pauline Vos <pvos88@gmail.com>
Enable alerts by default in account profile settings, subject to browser permission. Play the supplied sound, keep notification text private, and share focused reading state and a ten-second cooldown across tabs without replaying suppressed arrivals. Track incoming messages independently of org events. Add timed mute and unmute controls, and avoid marking messages read in hidden or unfocused windows.

Co-authored-by: Pauline Vos <pvos88@gmail.com>
Amp-Thread-ID: https://ampcode.com/threads/T-01a164f2-f78a-744d-9919-ba1ca2383eed
@paulinevos
paulinevos force-pushed the remotes-notifications branch from 4bad0d0 to d2b3bcf Compare October 23, 2026 11:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

An unresolved cross-tab notification race needs correction, and browser lifecycle behavior warrants final human validation.

1 open issue
2 resolved since last review

Review effort: Balanced

(item) =>
(item.last_incoming_message_id ?? 0) >
(previous[item.id] ?? 0) &&
item.ahead > 0 &&

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fuck it we ball

@paulinevos
paulinevos merged commit 2111fff into dev-null-sh:production Oct 23, 2026
5 checks passed
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.

4 participants