From eb8c27d38e293c94c84174b64ba8a760b973d429 Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 17 Jan 2024 11:33:29 +0700 Subject: [PATCH] TF-2464 Sort list new emails push notification by `receivedAt` Signed-off-by: dab246 (cherry picked from commit 44a1f4a44c9bc5612cef610334ce01dbaff9e051) --- ios/Runner/AppDelegate.swift | 9 ++++--- .../Extensions/StringExtensions.swift | 20 ++++++++++++++ ios/TwakeCore/Jmap/JmapClient.swift | 17 ++++++++++-- ios/TwakeCore/Jmap/Model/Email/Email.swift | 1 + ios/TwakeCore/Jmap/Utils/JmapConstants.swift | 3 ++- ios/TwakeMailNSE/NotificationService.swift | 26 ++++++++----------- 6 files changed, 54 insertions(+), 22 deletions(-) diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 440c53a4f..0c13269e0 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -88,7 +88,7 @@ import flutter_local_notifications if let notificationBadgeCount = notification.request.content.badge?.intValue, notificationBadgeCount > 0 { let newBadgeCount = UIApplication.shared.applicationIconBadgeNumber + notificationBadgeCount TwakeLogger.shared.log(message: "AppDelegate::userNotificationCenter::willPresent:newBadgeCount: \(newBadgeCount)") - updateAppBadger(currentBadgeCount: newBadgeCount) + updateAppBadger(newBadgeCount: newBadgeCount) } if let emailId = notification.request.content.userInfo[JmapConstants.EMAIL_ID] as? String, !emailId.isEmpty, @@ -101,7 +101,9 @@ import flutter_local_notifications override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { TwakeLogger.shared.log(message: "AppDelegate::userNotificationCenter::didReceive::response: \(response)") - updateAppBadger(currentBadgeCount: UIApplication.shared.applicationIconBadgeNumber) + let currentBadgeCount = UIApplication.shared.applicationIconBadgeNumber + let newBadgeCount = currentBadgeCount > 0 ? currentBadgeCount - 1 : 0 + updateAppBadger(newBadgeCount: newBadgeCount) if let emailId = response.notification.request.content.userInfo[JmapConstants.EMAIL_ID] as? String { self.notificationInteractionChannel?.invokeMethod("openEmail", arguments: emailId) @@ -112,8 +114,7 @@ import flutter_local_notifications } extension AppDelegate { - private func updateAppBadger(currentBadgeCount: Int) { - let newBadgeCount = currentBadgeCount > 0 ? currentBadgeCount - 1 : 0 + private func updateAppBadger(newBadgeCount: Int) { TwakeLogger.shared.log(message: "AppDelegate::updateAppBadger::newBadgeCount: \(newBadgeCount)") if #available(iOS 16.0, *) { UNUserNotificationCenter.current().setBadgeCount(newBadgeCount) diff --git a/ios/TwakeCore/Extensions/StringExtensions.swift b/ios/TwakeCore/Extensions/StringExtensions.swift index 5c6c2d011..0f334098a 100644 --- a/ios/TwakeCore/Extensions/StringExtensions.swift +++ b/ios/TwakeCore/Extensions/StringExtensions.swift @@ -9,4 +9,24 @@ extension String { } return nil } + + func convertUTCDateToLocalDate() -> Date? { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'" + dateFormatter.timeZone = TimeZone(identifier: "UTC") + + if let utcDate = dateFormatter.date(from: self) { + TwakeLogger.shared.log(message: "UTC Date: \(utcDate)") + dateFormatter.timeZone = TimeZone.current + let localDateString = dateFormatter.string(from: utcDate) + TwakeLogger.shared.log(message: "Local Date: \(localDateString)") + if let localDate = dateFormatter.date(from: localDateString) { + return localDate + } + return nil + } else { + TwakeLogger.shared.log(message: "Error converting UTC date string to Date.") + return nil + } + } } diff --git a/ios/TwakeCore/Jmap/JmapClient.swift b/ios/TwakeCore/Jmap/JmapClient.swift index 6033ef770..b7dd4edb8 100644 --- a/ios/TwakeCore/Jmap/JmapClient.swift +++ b/ios/TwakeCore/Jmap/JmapClient.swift @@ -83,8 +83,10 @@ class JmapClient { interceptor: authenticationInterceptor, onSuccess: { (data: JmapResponseObject) in if let response = data.parsing(methodName: JmapConstants.EMAIL_GET_METHOD_NAME, methodCallId: "c1") { - if let listEmail = response.list, !listEmail.isEmpty { - self.totalListEmails.append(contentsOf: listEmail) + if let listEmail = response.list, + !listEmail.isEmpty { + let sortedListEmails = self.sortListEmails(currentListEmails: listEmail) + self.totalListEmails.append(contentsOf: sortedListEmails) } self.hasMoreChanges = response.hasMoreChanges ?? false self.currentSinceState = response.newState @@ -107,4 +109,15 @@ class JmapClient { } ) } + + private func sortListEmails(currentListEmails: [Email]) -> [Email] { + let sortedListEmails = currentListEmails.sorted(by: { (email1, email2) -> Bool in + if let date1 = email1.receivedAt?.convertUTCDateToLocalDate(), + let date2 = email2.receivedAt?.convertUTCDateToLocalDate() { + return date1 < date2 + } + return false + }) + return sortedListEmails + } } diff --git a/ios/TwakeCore/Jmap/Model/Email/Email.swift b/ios/TwakeCore/Jmap/Model/Email/Email.swift index 70a09e658..10a4cecd8 100644 --- a/ios/TwakeCore/Jmap/Model/Email/Email.swift +++ b/ios/TwakeCore/Jmap/Model/Email/Email.swift @@ -5,4 +5,5 @@ struct Email: Codable { let subject: String? let preview: String? let from: [EmailAddress]? + let receivedAt: String? } diff --git a/ios/TwakeCore/Jmap/Utils/JmapConstants.swift b/ios/TwakeCore/Jmap/Utils/JmapConstants.swift index d5b6b31d1..05d867798 100644 --- a/ios/TwakeCore/Jmap/Utils/JmapConstants.swift +++ b/ios/TwakeCore/Jmap/Utils/JmapConstants.swift @@ -13,7 +13,8 @@ class JmapConstants { "id", "subject", "preview", - "from" + "from", + "receivedAt" ] static let EMAIL_ID = "email_id" diff --git a/ios/TwakeMailNSE/NotificationService.swift b/ios/TwakeMailNSE/NotificationService.swift index 72bb0f7ef..576bb0dd3 100644 --- a/ios/TwakeMailNSE/NotificationService.swift +++ b/ios/TwakeMailNSE/NotificationService.swift @@ -3,7 +3,6 @@ import SwiftUI class NotificationService: UNNotificationServiceExtension { - private let timeIntervalNotificationTriggerInSecond: Int = 2 private let newEmailDefaultMessageKey: String = "newMessageInTwakeMail" private var handler: ((UNNotificationContent) -> Void)? @@ -75,24 +74,20 @@ class NotificationService: UNNotificationServiceExtension { if (emails.count > 1) { for email in emails { if (email.id == emails.last?.id) { - break + self.modifiedContent?.subtitle = email.subject ?? "" + self.modifiedContent?.body = email.preview ?? "" + self.modifiedContent?.sound = .default + self.modifiedContent?.badge = NSNumber(value: emails.count) + self.modifiedContent?.userInfo[JmapConstants.EMAIL_ID] = email.id + return self.notify() } self.scheduleLocalNotification(email: email) } - - let delayTimeIntervalNotification: TimeInterval = TimeInterval(self.timeIntervalNotificationTriggerInSecond * (emails.count - 1)) - - DispatchQueue.main.asyncAfter(deadline: .now() + delayTimeIntervalNotification) { - self.modifiedContent?.subtitle = emails.last?.subject ?? "" - self.modifiedContent?.body = emails.last?.preview ?? "" - self.modifiedContent?.badge = NSNumber(value: emails.count) - self.modifiedContent?.userInfo[JmapConstants.EMAIL_ID] = emails.last?.id ?? "" - return self.notify() - } } else { self.modifiedContent?.subtitle = emails.first?.subject ?? "" self.modifiedContent?.body = emails.first?.preview ?? "" self.modifiedContent?.badge = NSNumber(value: 1) + self.modifiedContent?.sound = .default self.modifiedContent?.userInfo[JmapConstants.EMAIL_ID] = emails.first?.id ?? "" return self.notify() } @@ -102,18 +97,19 @@ class NotificationService: UNNotificationServiceExtension { } } - func scheduleLocalNotification(email: Email) { + private func scheduleLocalNotification(email: Email) { // Create a notification content let content = UNMutableNotificationContent() content.title = InfoPlistReader(bundle: .app).bundleDisplayName content.subtitle = email.subject ?? "" content.body = email.preview ?? "" content.sound = .default + content.badge = 1 content.userInfo[JmapConstants.EMAIL_ID] = "\(email.id)" // Create a notification trigger - let trigger = UNTimeIntervalNotificationTrigger(timeInterval: TimeInterval(timeIntervalNotificationTriggerInSecond), repeats: false) - + let triggerDateTime = Calendar.current.dateComponents([.hour, .minute, .second], from: Date()) + let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDateTime, repeats: false) // Create a notification request let request = UNNotificationRequest(identifier: "\(email.id)", content: content, trigger: trigger)