Skip to content

One channel for every notification: the notch, or a banner - #326

Open
rafaelbarea wants to merge 1 commit into
vinzdg:mainfrom
rafaelbarea:pr/notification-channel
Open

rafaelbarea wants to merge 1 commit into
vinzdg:mainfrom
rafaelbarea:pr/notification-channel

Conversation

@rafaelbarea

Copy link
Copy Markdown
Contributor

What

Notifications came from two places with no choice about either: a session ending opened the notch, a limit event showed the notch's card with a banner as fallback, and a threshold crossing was always a banner. Someone on a second display, or with the notch hidden, missed the first two; someone who chose the notch to keep Notification Center empty still got the third.

Settings › Notifications now opens with Where to notify: In the notch or Mac notifications. One choice for all of them; which events notify stays a switch per event, exactly as today.

  • Mac channel: a session ending becomes a banner ("Claude finished", "Claude is waiting on you"); reset and limit events go straight to UsageAlertNotifications; threshold crossings stay banners.
  • Notch channel: a threshold crossing becomes a card beside the notch (UsageAlertEvent gains optional noticeTitle/Subtitle/Status so UsageResetCard can show words that are not a reset's). The banner remains the fallback for a notch that cannot show the card.
  • Default is the notch, so nothing changes for anyone who does not touch the setting.
  • Send a test shows one on the chosen channel. When banners are switched off for Codenotch in System Settings it opens that pane instead of doing nothing.
  • A UNUserNotificationCenterDelegate presents banners while Codenotch is frontmost (macOS otherwise delivers an app's own notifications quietly to the list, which is why a test from the Settings window never showed).
  • Permission is requested when the Mac channel is chosen, not on the first event, and never of someone who keeps to the notch.

Files

  • Sources/Model/NotificationChannel.swift (new): the enum and the Mac side (presenter, permission, test, session banners).
  • Preferences.notificationChannel, stored as notificationChannel.
  • AppDelegate: routing in announceCompletions, announceUsageReset, announceUsageLimit; new announceThreshold and sendTestNotification.
  • ThresholdAlert carries the provider glyph so the card can draw it.
  • 16 new strings, with pt-BR.

Tests

  • NotificationChannelPreferenceTests: the notch is the default, the choice survives a relaunch, every channel has a title and explanation.
  • make test: 1737 tests, 0 failures.

🤖 Generated with Claude Code

Notifications came from two places with no choice about either: a session
ending opened the notch, a limit event showed the notch's card with a banner
as fallback, and a threshold crossing was always a banner. Someone on a
second display, or with the notch hidden, missed the first two; someone who
chose the notch to keep Notification Center empty still got the third.

Settings › Notifications now opens with the channel: In the notch, or Mac
notifications. Which events notify stays a switch per event. On the Mac
channel a session ending becomes a banner ("… finished", "… is waiting on
you"), and limit events go straight to a banner. On the notch channel a
threshold crossing becomes a card beside the notch, with the banner kept
only for a notch that cannot show it. The notch is the default, because it
is what every earlier version did.

A Send a test button shows one on whichever channel is chosen; when banners
are switched off for Codenotch in System Settings it opens that pane, since
a test that shows nothing and says nothing reads as broken. A notification
center delegate presents banners while Codenotch is frontmost, which is
exactly when the test button is clicked. Permission is asked when the Mac
channel is chosen, not on the first event, and never of someone who keeps
to the notch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@rafaelbarea
rafaelbarea requested a review from vinzdg as a code owner September 22, 2026 18:47
@vinzdg

vinzdg commented Sep 23, 2026

Copy link
Copy Markdown
Owner

Thanks @rafaelbarea — one preference that decides where a notification goes is a sensible idea, and the "Send a test" button is the right affordance for it.

One thing to change:

ChannelNotifications.installPresenter() (AppDelegate.swift:88) installs a process-wide UNUserNotificationCenterDelegate that forces [.banner, .list, .sound] for every notification the app posts — including the ones the notch channel raises as fallbacks (NotificationChannel.swift:40-48). So choosing "notch" can still produce a banner, and notifications unrelated to this feature change presentation too. Scope the delegate to the channel's own notifications, or gate the forced presentation on the preference actually being set to the banner channel.

Smaller: testEveryChannelExplainsItself only asserts the strings are non-empty, which passes for any non-empty string.

You'll want a rebase — #327 is merged, and it changes displayName on every published snapshot, which is the name these notifications would use. #324 and #325 are in too.

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.

2 participants