diff --git a/Telegram/NotificationService/Sources/NotificationService.swift b/Telegram/NotificationService/Sources/NotificationService.swift index 794b4bcdc1..f3a1f0d7f5 100644 --- a/Telegram/NotificationService/Sources/NotificationService.swift +++ b/Telegram/NotificationService/Sources/NotificationService.swift @@ -1054,7 +1054,12 @@ private final class NotificationServiceHandler { } 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 diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index 3c145fc513..bf0e6f878e 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -2395,7 +2395,7 @@ private func extractAccountManagerState(records: AccountRecordsView Void = { _ in }) { - if #available(iOS 10.0, *) { - let notificationCenter = UNUserNotificationCenter.current() - Logger.shared.log("App \(self.episodeId)", "register for notifications: get settings (authorize: \(authorize))") - notificationCenter.getNotificationSettings(completionHandler: { settings in - Logger.shared.log("App \(self.episodeId)", "register for notifications: received settings: \(settings.authorizationStatus)") - - switch (settings.authorizationStatus, authorize) { - case (.authorized, _), (.notDetermined, true): - var authorizationOptions: UNAuthorizationOptions = [.badge, .sound, .alert, .carPlay] - if #available(iOS 12.0, *) { - authorizationOptions.insert(.providesAppNotificationSettings) - } - if #available(iOS 13.0, *) { - authorizationOptions.insert(.announcement) - } - Logger.shared.log("App \(self.episodeId)", "register for notifications: request authorization") - notificationCenter.requestAuthorization(options: authorizationOptions, completionHandler: { result, _ in - Logger.shared.log("App \(self.episodeId)", "register for notifications: received authorization: \(result)") - completion(result) - if result { - Queue.mainQueue().async { - let reply = UNTextInputNotificationAction(identifier: "reply", title: replyString, options: [], textInputButtonTitle: replyString, textInputPlaceholder: messagePlaceholderString) - - let unknownMessageCategory: UNNotificationCategory - let replyMessageCategory: UNNotificationCategory - let replyLegacyMessageCategory: UNNotificationCategory - let replyLegacyMediaMessageCategory: UNNotificationCategory - let replyMediaMessageCategory: UNNotificationCategory - let legacyChannelMessageCategory: UNNotificationCategory - let muteMessageCategory: UNNotificationCategory - let muteMediaMessageCategory: UNNotificationCategory - - if #available(iOS 11.0, *) { - 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: []) + let notificationCenter = UNUserNotificationCenter.current() + Logger.shared.log("App \(self.episodeId)", "register for notifications: get settings (authorize: \(authorize))") + notificationCenter.getNotificationSettings(completionHandler: { settings in + Logger.shared.log("App \(self.episodeId)", "register for notifications: received settings: \(settings.authorizationStatus)") + + switch (settings.authorizationStatus, authorize) { + case (.authorized, _), (.notDetermined, true): + var authorizationOptions: UNAuthorizationOptions = [.badge, .sound, .alert, .carPlay] + if #available(iOS 12.0, *) { + authorizationOptions.insert(.providesAppNotificationSettings) + } + if #available(iOS 13.0, *) { + authorizationOptions.insert(.announcement) + } + Logger.shared.log("App \(self.episodeId)", "register for notifications: request authorization") + notificationCenter.requestAuthorization(options: authorizationOptions, completionHandler: { result, _ in + Logger.shared.log("App \(self.episodeId)", "register for notifications: received authorization: \(result)") + completion(result) + if result { + Queue.mainQueue().async { + let reply = UNTextInputNotificationAction(identifier: "reply", title: replyString, options: [], textInputButtonTitle: replyString, textInputPlaceholder: messagePlaceholderString) + + let unknownMessageCategory: UNNotificationCategory + let repliableMessageCategory: UNNotificationCategory + let repliableMediaMessageCategory: UNNotificationCategory + let groupRepliableMessageCategory: UNNotificationCategory + let groupRepliableMediaMessageCategory: UNNotificationCategory + let channelMessageCategory: UNNotificationCategory + + if #available(iOS 11.0, *) { + var options: UNNotificationCategoryOptions = [] + if includeNames { + options.insert(.hiddenPreviewsShowTitle) } - 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") - UIApplication.shared.registerForRemoteNotifications() + unknownMessageCategory = UNNotificationCategory(identifier: "unknown", actions: [], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options) + 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 - } - }) - } 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() - } + } + }) + default: + break + } + }) } @available(iOS 10.0, *) diff --git a/submodules/TelegramUI/Sources/ApplicationContext.swift b/submodules/TelegramUI/Sources/ApplicationContext.swift index 22e46ca77a..76e2e97d7b 100644 --- a/submodules/TelegramUI/Sources/ApplicationContext.swift +++ b/submodules/TelegramUI/Sources/ApplicationContext.swift @@ -101,8 +101,6 @@ final class AuthorizedApplicationContext { let rootController: TelegramRootController let notificationController: NotificationContainerController - private var scheduledOpenNotificationSettings: Bool = false - private var scheduledOpenChatWithPeerId: (PeerId, MessageId?, Bool)? private let scheduledCallPeerDisposable = MetaDisposable() private var scheduledOpenExternalUrl: URL? @@ -395,7 +393,7 @@ final class AuthorizedApplicationContext { } 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: { if let strongSelf = self { var foundOverlay = false @@ -833,11 +831,7 @@ final class AuthorizedApplicationContext { } func openNotificationSettings() { - if self.rootController.rootTabController != nil { - self.rootController.pushViewController(notificationsAndSoundsController(context: self.context, exceptionsList: nil)) - } else { - self.scheduledOpenNotificationSettings = true - } + self.rootController.pushViewController(notificationsAndSoundsController(context: self.context, exceptionsList: nil)) } func startCall(peerId: PeerId, isVideo: Bool) { @@ -864,27 +858,40 @@ final class AuthorizedApplicationContext { } if visiblePeerId != peerId || messageId != nil { - if self.rootController.rootTabController != nil { - let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) - |> deliverOnMainQueue).start(next: { peer 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 - )) + let isOutgoingMessage: Signal + if let messageId { + let accountPeerId = self.context.account.peerId + isOutgoingMessage = self.context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: messageId)) + |> map { message -> Bool in + if let message { + return !message._asMessage().effectivelyIncoming(accountPeerId) } 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 { - 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)) + }) } }