Files
amethyst/desktopApp
mandClaude e9475dd079 fix(desktop): make Enable OS notifications button actually enable them
Two independent gaps meant the desktop notifications flow silently
did nothing after the user clicked the settings button:

1. `LocalNotificationSettings` and `LocalNotificationReadState` were
   declared but never `.provides()`'d anywhere. Both
   `NotificationSettingsScreen` and `NotificationsScreen` fell back to
   a fresh `PreferencesNotificationSettings()` / `PreferencesNotification-
   ReadState()` instance each time — the java.util.prefs backing store
   kept the values consistent across cold restarts, but each Composable
   held its own `MutableStateFlow`, so a `setEnabled(true)` in Settings
   never fired the collectors in the inbox banner or in the auto-
   dispatcher. The user could toggle the master switch back and forth
   and nothing observable happened until the app was restarted. The
   auto-dispatcher in Main.kt was already using its own hoisted
   `notifSettings` instance too — just never handed down through the
   composition — so it never even saw the toggle.

2. The "Enable OS notifications" button (only shown on macOS when
   permission == NotRequested) called `dispatcher.requestPermission()`
   and updated `permissionState`, but it never touched `settings.enabled`.
   So the OS prompt appeared, user clicked Allow, the UI cheerfully
   said "Permission granted" — and toasts still didn't fire because the
   master switch was still off (defaults to false, first-launch UX
   choice). The button label promised the whole flow; the code did
   half of it.

Fix:
- Hoist `notifSettings` (already existed for the auto-dispatcher) into
  the app-level `CompositionLocalProvider` as
  `LocalNotificationSettings provides notifSettings`, so every consumer
  reads/writes the same instance. Same-instance sharing means StateFlow
  emissions actually propagate.
- Add a per-account `PreferencesNotificationReadState`, keyed on
  `loggedIn?.pubKeyHex` via `remember(pubKeyHex)`, provided through
  `LocalNotificationReadState`. This also fixes the "Mark all as read"
  button in the inbox, which was `enabled = false` because the
  composition-local was always null.
- In `NotificationSettingsScreen`, if `requestPermission()` returns
  Granted and the master switch is currently off, call
  `settings.setEnabled(true)` alongside setting the status message. The
  master switch UI observes `settings.enabled` and recomposes
  automatically, so clicking one button now does the whole handshake.

Behaviour on other platforms is unchanged: Windows / Linux start in
`PermissionState.NotApplicable`, so the "Enable OS notifications" branch
never renders there — they see the "Send a test toast" button directly.
The auto-enable is guarded by `!enabled`, so users who deliberately
disabled the master switch and then re-granted permission (e.g. after
denying in System Settings) don't get overridden if the switch was
still on.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-29 08:11:02 +10:00
..