Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions Meshtastic/Helpers/LocalNotificationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,57 @@ class LocalNotificationManager {
}
}
}

// Remove already-delivered notifications for an entire channel conversation.
//
// Called when the user opens or catches up on a channel so that notifications for messages they
// have now read stop piling up in Notification Center. Message notifications are tagged in
// `userInfo` when scheduled (see `scheduleNotifications`). Channel notifications are identified
// by their deep-link `path` (`?channelId=`) so direct messages that happen to share the same
// channel index are left untouched. Delivered notifications round-trip through the system, so the
// numeric `userInfo` values come back as `NSNumber`.
func removeDeliveredNotifications(forChannel channelIndex: Int32) {
UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
let identifiers = notifications.compactMap { notification -> String? in
let userInfo = notification.request.content.userInfo
guard let path = userInfo["path"] as? String, path.contains("?channelId="),
let channel = (userInfo["channel"] as? NSNumber)?.int32Value,
channel == channelIndex else {
return nil
}
return notification.request.identifier
}

if !identifiers.isEmpty {
Logger.services.debug("Removing \(identifiers.count, privacy: .public) delivered channel notifications")
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: identifiers)
}
}
}

// Remove already-delivered notifications for an entire direct-message conversation.
//
// Called when the user opens or catches up on a DM thread. Direct-message notifications are
// identified by their deep-link `path` (`?userNum=`) and matched on the remote node number so
// channel notifications that carry an unrelated `userNum` value are left untouched.
func removeDeliveredNotifications(forDirectMessageUserNum userNum: Int64) {
UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
let identifiers = notifications.compactMap { notification -> String? in
let userInfo = notification.request.content.userInfo
guard let path = userInfo["path"] as? String, path.contains("?userNum="),
let num = (userInfo["userNum"] as? NSNumber)?.int64Value,
num == userNum else {
return nil
}
return notification.request.identifier
}

if !identifiers.isEmpty {
Logger.services.debug("Removing \(identifiers.count, privacy: .public) delivered direct message notifications")
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: identifiers)
}
}
}
}

struct Notification {
Expand Down
3 changes: 3 additions & 0 deletions Meshtastic/Views/Messages/ChannelMessageList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ struct ChannelMessageList: View {
readMessageIDs.append(unreadTapback.messageId)
}
notificationManager.cancelNotificationsForMessageIds(readMessageIDs)
// Also clear any notifications for this channel that were already delivered to Notification
// Center, so catching up on the channel wipes its piled-up notifications.
notificationManager.removeDeliveredNotifications(forChannel: channelIndex)
Comment on lines +94 to +96

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.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Update docs/user/messages.md for this user-visible behavior change.

This change makes delivered notifications disappear from Notification Center when a channel is read — a user-visible behavior change in Meshtastic/Views/Messages/.

As per path instructions, Meshtastic/Views/Messages/**/*.swift: "Update docs/user/messages.md when code in Meshtastic/Views/Messages/ changes in a user-visible way."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Meshtastic/Views/Messages/ChannelMessageList.swift` around lines 94 - 96,
Update docs/user/messages.md to document that opening or catching up on a
channel removes its already-delivered notifications from Notification Center,
reflecting the behavior implemented by removeDeliveredNotifications(forChannel:)
in ChannelMessageList.

Source: Path instructions

if context.hasChanges {
try context.save()
}
Expand Down
3 changes: 3 additions & 0 deletions Meshtastic/Views/Messages/UserMessageList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ struct UserMessageList: View {
readMessageIDs.append(unreadTapback.messageId)
}
notificationManager.cancelNotificationsForMessageIds(readMessageIDs)
// Also clear any notifications for this conversation that were already delivered to
// Notification Center, so opening the DM wipes its piled-up notifications.
notificationManager.removeDeliveredNotifications(forDirectMessageUserNum: user.num)
Comment on lines +86 to +88

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.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Update docs/user/messages.md for this user-visible behavior change.

Same as the channel-side change: clearing delivered notifications when a DM thread is opened is a user-visible behavior change under Meshtastic/Views/Messages/.

As per path instructions, Meshtastic/Views/Messages/**/*.swift: "Update docs/user/messages.md when code in Meshtastic/Views/Messages/ changes in a user-visible way."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Meshtastic/Views/Messages/UserMessageList.swift` around lines 86 - 88,
Document the new user-visible behavior in docs/user/messages.md: explain that
opening a direct-message thread clears its already-delivered Notification Center
notifications, alongside the existing channel behavior documentation. Update the
relevant messages documentation section without changing the implementation in
UserMessageList.

Source: Path instructions

if context.hasChanges {
try context.save()
}
Expand Down