Do not show group message notifications in CarPlay

Navigate to original message on tapping reaction notifications
This commit is contained in:
Ilya Laktyushin 2023-03-23 19:46:09 +04:00
parent da558c4026
commit d700f45c1c
3 changed files with 110 additions and 139 deletions

View File

@ -1054,7 +1054,12 @@ private final class NotificationServiceHandler {
} }
if let category = aps["category"] as? String { if let category = aps["category"] as? String {
content.category = category if peerId.isGroupOrChannel && ["r", "m"].contains(category) {
content.category = "g\(category)"
} else {
content.category = category
}
let _ = messageId let _ = messageId

View File

@ -2395,7 +2395,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
if response.actionIdentifier == UNNotificationDefaultActionIdentifier { if response.actionIdentifier == UNNotificationDefaultActionIdentifier {
if let (peerId, threadId) = peerIdFromNotification(response.notification) { if let (peerId, threadId) = peerIdFromNotification(response.notification) {
var messageId: MessageId? = nil var messageId: MessageId? = nil
if response.notification.request.content.categoryIdentifier == "watch" { if response.notification.request.content.categoryIdentifier == "c" {
messageId = messageIdFromNotification(peerId: peerId, notification: response.notification) messageId = messageIdFromNotification(peerId: peerId, notification: response.notification)
} }
self.openChatWhenReady(accountId: accountId, peerId: peerId, threadId: threadId, messageId: messageId) self.openChatWhenReady(accountId: accountId, peerId: peerId, threadId: threadId, messageId: messageId)
@ -2493,123 +2493,82 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
} }
private func registerForNotifications(replyString: String, messagePlaceholderString: String, hiddenContentString: String, includeNames: Bool, authorize: Bool = true, completion: @escaping (Bool) -> Void = { _ in }) { private func registerForNotifications(replyString: String, messagePlaceholderString: String, hiddenContentString: String, includeNames: Bool, authorize: Bool = true, completion: @escaping (Bool) -> Void = { _ in }) {
if #available(iOS 10.0, *) { let notificationCenter = UNUserNotificationCenter.current()
let notificationCenter = UNUserNotificationCenter.current() Logger.shared.log("App \(self.episodeId)", "register for notifications: get settings (authorize: \(authorize))")
Logger.shared.log("App \(self.episodeId)", "register for notifications: get settings (authorize: \(authorize))") notificationCenter.getNotificationSettings(completionHandler: { settings in
notificationCenter.getNotificationSettings(completionHandler: { settings in Logger.shared.log("App \(self.episodeId)", "register for notifications: received settings: \(settings.authorizationStatus)")
Logger.shared.log("App \(self.episodeId)", "register for notifications: received settings: \(settings.authorizationStatus)")
switch (settings.authorizationStatus, authorize) {
switch (settings.authorizationStatus, authorize) { case (.authorized, _), (.notDetermined, true):
case (.authorized, _), (.notDetermined, true): var authorizationOptions: UNAuthorizationOptions = [.badge, .sound, .alert, .carPlay]
var authorizationOptions: UNAuthorizationOptions = [.badge, .sound, .alert, .carPlay] if #available(iOS 12.0, *) {
if #available(iOS 12.0, *) { authorizationOptions.insert(.providesAppNotificationSettings)
authorizationOptions.insert(.providesAppNotificationSettings) }
} if #available(iOS 13.0, *) {
if #available(iOS 13.0, *) { authorizationOptions.insert(.announcement)
authorizationOptions.insert(.announcement) }
} Logger.shared.log("App \(self.episodeId)", "register for notifications: request authorization")
Logger.shared.log("App \(self.episodeId)", "register for notifications: request authorization") notificationCenter.requestAuthorization(options: authorizationOptions, completionHandler: { result, _ in
notificationCenter.requestAuthorization(options: authorizationOptions, completionHandler: { result, _ in Logger.shared.log("App \(self.episodeId)", "register for notifications: received authorization: \(result)")
Logger.shared.log("App \(self.episodeId)", "register for notifications: received authorization: \(result)") completion(result)
completion(result) if result {
if result { Queue.mainQueue().async {
Queue.mainQueue().async { let reply = UNTextInputNotificationAction(identifier: "reply", title: replyString, options: [], textInputButtonTitle: replyString, textInputPlaceholder: messagePlaceholderString)
let reply = UNTextInputNotificationAction(identifier: "reply", title: replyString, options: [], textInputButtonTitle: replyString, textInputPlaceholder: messagePlaceholderString)
let unknownMessageCategory: UNNotificationCategory
let unknownMessageCategory: UNNotificationCategory let repliableMessageCategory: UNNotificationCategory
let replyMessageCategory: UNNotificationCategory let repliableMediaMessageCategory: UNNotificationCategory
let replyLegacyMessageCategory: UNNotificationCategory let groupRepliableMessageCategory: UNNotificationCategory
let replyLegacyMediaMessageCategory: UNNotificationCategory let groupRepliableMediaMessageCategory: UNNotificationCategory
let replyMediaMessageCategory: UNNotificationCategory let channelMessageCategory: UNNotificationCategory
let legacyChannelMessageCategory: UNNotificationCategory
let muteMessageCategory: UNNotificationCategory if #available(iOS 11.0, *) {
let muteMediaMessageCategory: UNNotificationCategory var options: UNNotificationCategoryOptions = []
if includeNames {
if #available(iOS 11.0, *) { options.insert(.hiddenPreviewsShowTitle)
var options: UNNotificationCategoryOptions = []
if includeNames {
options.insert(.hiddenPreviewsShowTitle)
}
var carPlayOptions = options
carPlayOptions.insert(.allowInCarPlay)
if #available(iOS 13.2, *) {
carPlayOptions.insert(.allowAnnouncement)
}
unknownMessageCategory = UNNotificationCategory(identifier: "unknown", actions: [], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options)
replyMessageCategory = UNNotificationCategory(identifier: "withReply", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: carPlayOptions)
replyLegacyMessageCategory = UNNotificationCategory(identifier: "r", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: carPlayOptions)
replyLegacyMediaMessageCategory = UNNotificationCategory(identifier: "m", actions: [reply], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: carPlayOptions)
replyMediaMessageCategory = UNNotificationCategory(identifier: "withReplyMedia", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: carPlayOptions)
legacyChannelMessageCategory = UNNotificationCategory(identifier: "c", actions: [], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options)
muteMessageCategory = UNNotificationCategory(identifier: "withMute", actions: [], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options)
muteMediaMessageCategory = UNNotificationCategory(identifier: "withMuteMedia", actions: [], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options)
} else {
let carPlayOptions: UNNotificationCategoryOptions = [.allowInCarPlay]
unknownMessageCategory = UNNotificationCategory(identifier: "unknown", actions: [], intentIdentifiers: [], options: [])
replyMessageCategory = UNNotificationCategory(identifier: "withReply", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], options: carPlayOptions)
replyLegacyMessageCategory = UNNotificationCategory(identifier: "r", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], options: carPlayOptions)
replyLegacyMediaMessageCategory = UNNotificationCategory(identifier: "m", actions: [reply], intentIdentifiers: [], options: [])
replyMediaMessageCategory = UNNotificationCategory(identifier: "withReplyMedia", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], options: carPlayOptions)
legacyChannelMessageCategory = UNNotificationCategory(identifier: "c", actions: [], intentIdentifiers: [], options: [])
muteMessageCategory = UNNotificationCategory(identifier: "withMute", actions: [], intentIdentifiers: [], options: [])
muteMediaMessageCategory = UNNotificationCategory(identifier: "withMuteMedia", actions: [], intentIdentifiers: [], options: [])
} }
UNUserNotificationCenter.current().setNotificationCategories([unknownMessageCategory, replyMessageCategory, replyLegacyMessageCategory, replyLegacyMediaMessageCategory, replyMediaMessageCategory, legacyChannelMessageCategory, muteMessageCategory, muteMediaMessageCategory]) var carPlayOptions = options
carPlayOptions.insert(.allowInCarPlay)
if #available(iOS 13.2, *) {
carPlayOptions.insert(.allowAnnouncement)
}
Logger.shared.log("App \(self.episodeId)", "register for notifications: invoke registerForRemoteNotifications") unknownMessageCategory = UNNotificationCategory(identifier: "unknown", actions: [], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options)
UIApplication.shared.registerForRemoteNotifications() repliableMessageCategory = UNNotificationCategory(identifier: "r", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: carPlayOptions)
repliableMediaMessageCategory = UNNotificationCategory(identifier: "m", actions: [reply], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: carPlayOptions)
groupRepliableMessageCategory = UNNotificationCategory(identifier: "gr", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options)
groupRepliableMediaMessageCategory = UNNotificationCategory(identifier: "gm", actions: [reply], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options)
channelMessageCategory = UNNotificationCategory(identifier: "c", actions: [], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options)
} else {
let carPlayOptions: UNNotificationCategoryOptions = [.allowInCarPlay]
unknownMessageCategory = UNNotificationCategory(identifier: "unknown", actions: [], intentIdentifiers: [], options: [])
repliableMessageCategory = UNNotificationCategory(identifier: "r", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], options: carPlayOptions)
repliableMediaMessageCategory = UNNotificationCategory(identifier: "m", actions: [reply], intentIdentifiers: [], options: [])
groupRepliableMessageCategory = UNNotificationCategory(identifier: "gr", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], options: [])
groupRepliableMediaMessageCategory = UNNotificationCategory(identifier: "gm", actions: [reply], intentIdentifiers: [], options: [])
channelMessageCategory = UNNotificationCategory(identifier: "c", actions: [], intentIdentifiers: [], options: [])
} }
UNUserNotificationCenter.current().setNotificationCategories([
unknownMessageCategory,
repliableMessageCategory,
repliableMediaMessageCategory,
channelMessageCategory,
groupRepliableMessageCategory,
groupRepliableMediaMessageCategory
])
Logger.shared.log("App \(self.episodeId)", "register for notifications: invoke registerForRemoteNotifications")
UIApplication.shared.registerForRemoteNotifications()
} }
}) }
default: })
break default:
} break
}) }
} else { })
let reply = UIMutableUserNotificationAction()
reply.identifier = "reply"
reply.title = replyString
reply.isDestructive = false
reply.isAuthenticationRequired = false
reply.behavior = .textInput
reply.activationMode = .background
let unknownMessageCategory = UIMutableUserNotificationCategory()
unknownMessageCategory.identifier = "unknown"
let replyMessageCategory = UIMutableUserNotificationCategory()
replyMessageCategory.identifier = "withReply"
replyMessageCategory.setActions([reply], for: .default)
let replyLegacyMessageCategory = UIMutableUserNotificationCategory()
replyLegacyMessageCategory.identifier = "r"
replyLegacyMessageCategory.setActions([reply], for: .default)
let replyLegacyMediaMessageCategory = UIMutableUserNotificationCategory()
replyLegacyMediaMessageCategory.identifier = "m"
replyLegacyMediaMessageCategory.setActions([reply], for: .default)
let replyMediaMessageCategory = UIMutableUserNotificationCategory()
replyMediaMessageCategory.identifier = "withReplyMedia"
replyMediaMessageCategory.setActions([reply], for: .default)
let legacyChannelMessageCategory = UIMutableUserNotificationCategory()
legacyChannelMessageCategory.identifier = "c"
let muteMessageCategory = UIMutableUserNotificationCategory()
muteMessageCategory.identifier = "withMute"
let muteMediaMessageCategory = UIMutableUserNotificationCategory()
muteMediaMessageCategory.identifier = "withMuteMedia"
let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: [])
UIApplication.shared.registerUserNotificationSettings(settings)
UIApplication.shared.registerForRemoteNotifications()
}
} }
@available(iOS 10.0, *) @available(iOS 10.0, *)

View File

@ -101,8 +101,6 @@ final class AuthorizedApplicationContext {
let rootController: TelegramRootController let rootController: TelegramRootController
let notificationController: NotificationContainerController let notificationController: NotificationContainerController
private var scheduledOpenNotificationSettings: Bool = false
private var scheduledOpenChatWithPeerId: (PeerId, MessageId?, Bool)?
private let scheduledCallPeerDisposable = MetaDisposable() private let scheduledCallPeerDisposable = MetaDisposable()
private var scheduledOpenExternalUrl: URL? private var scheduledOpenExternalUrl: URL?
@ -395,7 +393,7 @@ final class AuthorizedApplicationContext {
} }
if inAppNotificationSettings.displayPreviews { if inAppNotificationSettings.displayPreviews {
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
strongSelf.notificationController.enqueue(ChatMessageNotificationItem(context: strongSelf.context, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, messages: messages, threadData: threadData, tapAction: { strongSelf.notificationController.enqueue(ChatMessageNotificationItem(context: strongSelf.context, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, messages: messages, threadData: threadData, tapAction: {
if let strongSelf = self { if let strongSelf = self {
var foundOverlay = false var foundOverlay = false
@ -833,11 +831,7 @@ final class AuthorizedApplicationContext {
} }
func openNotificationSettings() { func openNotificationSettings() {
if self.rootController.rootTabController != nil { self.rootController.pushViewController(notificationsAndSoundsController(context: self.context, exceptionsList: nil))
self.rootController.pushViewController(notificationsAndSoundsController(context: self.context, exceptionsList: nil))
} else {
self.scheduledOpenNotificationSettings = true
}
} }
func startCall(peerId: PeerId, isVideo: Bool) { func startCall(peerId: PeerId, isVideo: Bool) {
@ -864,27 +858,40 @@ final class AuthorizedApplicationContext {
} }
if visiblePeerId != peerId || messageId != nil { if visiblePeerId != peerId || messageId != nil {
if self.rootController.rootTabController != nil { let isOutgoingMessage: Signal<Bool, NoError>
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) if let messageId {
|> deliverOnMainQueue).start(next: { peer in let accountPeerId = self.context.account.peerId
guard let peer = peer else { isOutgoingMessage = self.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId))
return |> map { message -> Bool in
} if let message {
return !message._asMessage().effectivelyIncoming(accountPeerId)
let chatLocation: NavigateToChatControllerParams.Location
if let threadId = threadId {
chatLocation = .replyThread(ChatReplyThreadMessage(
messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadId)), channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false
))
} else { } else {
chatLocation = .peer(peer) return false
} }
}
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) }, activateInput: activateInput ? .text : nil))
})
} else { } else {
self.scheduledOpenChatWithPeerId = (peerId, messageId, activateInput) isOutgoingMessage = .single(false)
} }
let _ = combineLatest(
queue: Queue.mainQueue(),
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)),
isOutgoingMessage
).start(next: { peer, isOutgoingMessage in
guard let peer = peer else {
return
}
let chatLocation: NavigateToChatControllerParams.Location
if let threadId = threadId {
chatLocation = .replyThread(ChatReplyThreadMessage(
messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadId)), channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false
))
} else {
chatLocation = .peer(peer)
}
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: isOutgoingMessage ? messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) } : nil, activateInput: activateInput ? .text : nil))
})
} }
} }