From 0e4593c476adafd5e89da72423bc2000dd24b6fc Mon Sep 17 00:00:00 2001 From: Ivan Sein Date: Mon, 9 Dec 2024 19:45:00 +0100 Subject: [PATCH 1/4] feat(PushNotifications): Allow to test push notifications Signed-off-by: Ivan Sein --- .../DiagnosticsTableViewController.swift | 67 +++++++++++++++---- NextcloudTalk/NCAPIControllerExtensions.swift | 17 +++++ NextcloudTalk/NCDatabaseManager.h | 1 + NextcloudTalk/NCDatabaseManager.m | 1 + 4 files changed, 72 insertions(+), 14 deletions(-) diff --git a/NextcloudTalk/DiagnosticsTableViewController.swift b/NextcloudTalk/DiagnosticsTableViewController.swift index 1048b3b29..68857b6b9 100644 --- a/NextcloudTalk/DiagnosticsTableViewController.swift +++ b/NextcloudTalk/DiagnosticsTableViewController.swift @@ -34,10 +34,10 @@ class DiagnosticsTableViewController: UITableViewController { } enum AccountSections: Int { - case kAccountSectionServer = 0 - case kAccountSectionUser - case kAccountPushSubscribed - case kAccountSectionCount + case server = 0 + case user + case pushSubscribed + case testPushNotifications } enum ServerSections: Int { @@ -87,7 +87,7 @@ class DiagnosticsTableViewController: UITableViewController { let notRequestedString = NSLocalizedString("Not requested", comment: "'{Microphone, Camera, ...} access was not requested'") let deniedFunctionalityString = NSLocalizedString("This will impact the functionality of this app. Please review your settings.", comment: "") - let cellIdentifierOpenAppSettings = "cellIdentifierOpenAppSettings" + let cellIdentifierAction = "cellIdentifierAction" let cellIdentifierSubtitle = "cellIdentifierSubtitle" let cellIdentifierSubtitleAccessory = "cellIdentifierSubtitleAccessory" @@ -133,13 +133,25 @@ class DiagnosticsTableViewController: UITableViewController { self.navigationItem.compactAppearance = appearance self.navigationItem.scrollEdgeAppearance = appearance - self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifierOpenAppSettings) + self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifierAction) self.tableView.register(SubtitleTableViewCell.self, forCellReuseIdentifier: cellIdentifierSubtitle) self.tableView.register(SubtitleTableViewCell.self, forCellReuseIdentifier: cellIdentifierSubtitleAccessory) runChecks() } + // MARK: - Account section options + + func accountSections() -> [AccountSections] { + var sections: [AccountSections] = [.server, .user, .pushSubscribed] + if NCDatabaseManager.sharedInstance().serverHasNotificationsCapability(kNotificationsCapabilityTestPush, forAccountId: account.accountId) { + sections.append(.testPushNotifications) + } + + return sections + } + + // MARK: Async. checks func runChecks() { @@ -191,7 +203,7 @@ class DiagnosticsTableViewController: UITableViewController { return AppSections.kAppSectionCount.rawValue case DiagnosticsSections.kDiagnosticsSectionAccount.rawValue: - return AccountSections.kAccountSectionCount.rawValue + return accountSections().count case DiagnosticsSections.kDiagnosticsSectionServer.rawValue: return ServerSections.kServerSectionCount.rawValue @@ -259,6 +271,11 @@ class DiagnosticsTableViewController: UITableViewController { UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil) + } else if indexPath.section == DiagnosticsSections.kDiagnosticsSectionAccount.rawValue, + accountSections()[indexPath.row] == .testPushNotifications { + + testPushNotifications() + } else if indexPath.section == DiagnosticsSections.kDiagnosticsSectionTalk.rawValue, indexPath.row == TalkSections.kTalkSectionVersion.rawValue { @@ -307,7 +324,7 @@ class DiagnosticsTableViewController: UITableViewController { return appPhotoLibraryAccessCell(for: indexPath) case AppSections.kAppSectionOpenSettings.rawValue: - let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifierOpenAppSettings, for: indexPath) + let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifierAction, for: indexPath) cell.textLabel?.text = NSLocalizedString("Open app settings", comment: "") cell.textLabel?.textAlignment = .center @@ -452,17 +469,18 @@ class DiagnosticsTableViewController: UITableViewController { func accountCell(for indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifierSubtitle, for: indexPath) + let row: AccountSections = accountSections()[indexPath.row] - switch indexPath.row { - case AccountSections.kAccountSectionServer.rawValue: + switch row { + case .server: cell.textLabel?.text = NSLocalizedString("Server", comment: "") cell.detailTextLabel?.text = account.server - case AccountSections.kAccountSectionUser.rawValue: + case .user: cell.textLabel?.text = NSLocalizedString("User", comment: "") cell.detailTextLabel?.text = account.user - case AccountSections.kAccountPushSubscribed.rawValue: + case .pushSubscribed: cell.textLabel?.text = NSLocalizedString("Push notifications", comment: "") if account.lastPushSubscription > 0 { let lastSubsctiptionString = NSLocalizedString("Last subscription", comment: "Last subscription to the push notification server") @@ -472,8 +490,12 @@ class DiagnosticsTableViewController: UITableViewController { cell.detailTextLabel?.text = NSLocalizedString("Never subscribed", comment: "Never subscribed to the push notification server") } - default: - break + case .testPushNotifications: + let actionCell = self.tableView.dequeueReusableCell(withIdentifier: self.cellIdentifierAction, for: indexPath) + actionCell.textLabel?.text = NSLocalizedString("Test push notifications", comment: "") + actionCell.textLabel?.textAlignment = .center + actionCell.textLabel?.textColor = UIColor.systemBlue + return actionCell } return cell @@ -623,6 +645,23 @@ class DiagnosticsTableViewController: UITableViewController { return cell } + // MARK: Test push notifications + + func testPushNotifications() { + NCAPIController.sharedInstance().testPushnotifications(forAccount: account) { result, _ in + let alert = UIAlertController(title: NSLocalizedString("Test results", comment: ""), + message: result, + preferredStyle: .alert) + + alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default)) + alert.addAction(UIAlertAction(title: NSLocalizedString("Copy", comment: ""), style: .default) { _ in + UIPasteboard.general.string = result + NotificationPresenter.shared().present(text: NSLocalizedString("Test results copied", comment: ""), dismissAfterDelay: 5.0, includedStyle: .dark) + }) + NCUserInterfaceController.sharedInstance().presentAlertViewController(alert) + } + } + // MARK: Capabilities details func presentCapabilitiesDetails() { diff --git a/NextcloudTalk/NCAPIControllerExtensions.swift b/NextcloudTalk/NCAPIControllerExtensions.swift index de4c2a6e7..8c2c09070 100644 --- a/NextcloudTalk/NCAPIControllerExtensions.swift +++ b/NextcloudTalk/NCAPIControllerExtensions.swift @@ -559,4 +559,21 @@ import Foundation completionBlock(error == nil) } } + + // MARK: - Push notification test + + public func testPushnotifications(forAccount account: TalkAccount, completionBlock: @escaping (_ result: String?, _ error: Error?) -> Void) { + guard let apiSessionManager = self.apiSessionManagers.object(forKey: account.accountId) as? NCAPISessionManager + else { + completionBlock(nil, nil) + return + } + + let urlString = "\(account.server)/ocs/v2.php/apps/notifications/api/v3/test/self" + + apiSessionManager.postOcs(urlString, account: account) { ocsResponse, ocsError in + let message = ocsResponse?.dataDict?["message"] as? String + completionBlock(message, ocsError?.error) + } + } } diff --git a/NextcloudTalk/NCDatabaseManager.h b/NextcloudTalk/NCDatabaseManager.h index 511932de8..07ea8956c 100644 --- a/NextcloudTalk/NCDatabaseManager.h +++ b/NextcloudTalk/NCDatabaseManager.h @@ -78,6 +78,7 @@ extern NSString * const kCapabilityChatSummary; extern NSString * const kCapabilityArchivedConversationsV2; extern NSString * const kNotificationsCapabilityExists; +extern NSString * const kNotificationsCapabilityTestPush; extern NSString * const kMinimumRequiredTalkCapability; diff --git a/NextcloudTalk/NCDatabaseManager.m b/NextcloudTalk/NCDatabaseManager.m index 8b2640905..f7de9a745 100644 --- a/NextcloudTalk/NCDatabaseManager.m +++ b/NextcloudTalk/NCDatabaseManager.m @@ -79,6 +79,7 @@ NSString * const kCapabilityArchivedConversationsV2 = @"archived-conversations-v2"; NSString * const kNotificationsCapabilityExists = @"exists"; +NSString * const kNotificationsCapabilityTestPush = @"test-push"; NSString * const kMinimumRequiredTalkCapability = kCapabilitySystemMessages; // Talk 4.0 is the minimum required version From b4d215662d95321f7898b4bc026af70fc7826bcb Mon Sep 17 00:00:00 2001 From: Ivan Sein Date: Mon, 9 Dec 2024 19:50:19 +0100 Subject: [PATCH 2/4] Update localizable strings file. Signed-off-by: Ivan Sein --- NextcloudTalk/en.lproj/Localizable.strings | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NextcloudTalk/en.lproj/Localizable.strings b/NextcloudTalk/en.lproj/Localizable.strings index 30ba6b4e7..3306fd686 100644 --- a/NextcloudTalk/en.lproj/Localizable.strings +++ b/NextcloudTalk/en.lproj/Localizable.strings @@ -1726,6 +1726,15 @@ /* No comment provided by engineer. */ "Tap and hold to record a voice message, release the button to send it." = "Tap and hold to record a voice message, release the button to send it."; +/* No comment provided by engineer. */ +"Test push notifications" = "Test push notifications"; + +/* No comment provided by engineer. */ +"Test results" = "Test results"; + +/* No comment provided by engineer. */ +"Test results copied" = "Test results copied"; + /* No comment provided by engineer. */ "The app is too old and no longer supported by this server." = "The app is too old and no longer supported by this server."; From ec0ca7753a5220aa61229b0830ef1313bcb870a7 Mon Sep 17 00:00:00 2001 From: Ivan Sein Date: Tue, 10 Dec 2024 23:22:05 +0100 Subject: [PATCH 3/4] Show activity indicator when push notification test is running. Signed-off-by: Ivan Sein --- .../DiagnosticsTableViewController.swift | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/NextcloudTalk/DiagnosticsTableViewController.swift b/NextcloudTalk/DiagnosticsTableViewController.swift index 68857b6b9..62a8d773f 100644 --- a/NextcloudTalk/DiagnosticsTableViewController.swift +++ b/NextcloudTalk/DiagnosticsTableViewController.swift @@ -79,6 +79,8 @@ class DiagnosticsTableViewController: UITableViewController { var serverReachable: Bool? var serverReachableIndicator = UIActivityIndicatorView(frame: .init(x: 0, y: 0, width: 24, height: 24)) + var testingPushNotificationsIndicator = UIActivityIndicatorView(frame: .init(x: 0, y: 0, width: 24, height: 24)) + var notificationSettings: UNNotificationSettings? var notificationSettingsIndicator = UIActivityIndicatorView(frame: .init(x: 0, y: 0, width: 24, height: 24)) @@ -648,6 +650,7 @@ class DiagnosticsTableViewController: UITableViewController { // MARK: Test push notifications func testPushNotifications() { + self.showPushNotificationTestRunningIndicator() NCAPIController.sharedInstance().testPushnotifications(forAccount: account) { result, _ in let alert = UIAlertController(title: NSLocalizedString("Test results", comment: ""), message: result, @@ -659,6 +662,34 @@ class DiagnosticsTableViewController: UITableViewController { NotificationPresenter.shared().present(text: NSLocalizedString("Test results copied", comment: ""), dismissAfterDelay: 5.0, includedStyle: .dark) }) NCUserInterfaceController.sharedInstance().presentAlertViewController(alert) + self.hidePushNotificationTestRunningIndicator() + } + } + + func testPushNotificationsCell() -> UITableViewCell? { + if let index = accountSections().firstIndex(of: AccountSections.testPushNotifications), + let testPushCell = tableView.cellForRow(at: IndexPath(row: index, section: DiagnosticsSections.kDiagnosticsSectionAccount.rawValue)) { + return testPushCell + } + + return nil + } + + func showPushNotificationTestRunningIndicator() { + if let testPushNotificationsCell = testPushNotificationsCell() { + testPushNotificationsCell.isUserInteractionEnabled = false + testPushNotificationsCell.textLabel?.textColor = UIColor.systemBlue.withAlphaComponent(0.5) + testingPushNotificationsIndicator.startAnimating() + testPushNotificationsCell.accessoryView = testingPushNotificationsIndicator + } + } + + func hidePushNotificationTestRunningIndicator() { + if let testPushNotificationsCell = testPushNotificationsCell() { + testPushNotificationsCell.isUserInteractionEnabled = true + testPushNotificationsCell.textLabel?.textColor = UIColor.systemBlue + testingPushNotificationsIndicator.stopAnimating() + testPushNotificationsCell.accessoryView = nil } } From cb991310b846713bde1998d80fe33c718169af99 Mon Sep 17 00:00:00 2001 From: Ivan Sein Date: Wed, 11 Dec 2024 15:12:25 +0100 Subject: [PATCH 4/4] Show error message and disable copy button when there are no test results Signed-off-by: Ivan Sein --- .../DiagnosticsTableViewController.swift | 19 ++++++++++++------- NextcloudTalk/NCAPIControllerExtensions.swift | 6 +++--- NextcloudTalk/en.lproj/Localizable.strings | 6 ++++++ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/NextcloudTalk/DiagnosticsTableViewController.swift b/NextcloudTalk/DiagnosticsTableViewController.swift index 62a8d773f..312294c9f 100644 --- a/NextcloudTalk/DiagnosticsTableViewController.swift +++ b/NextcloudTalk/DiagnosticsTableViewController.swift @@ -651,16 +651,21 @@ class DiagnosticsTableViewController: UITableViewController { func testPushNotifications() { self.showPushNotificationTestRunningIndicator() - NCAPIController.sharedInstance().testPushnotifications(forAccount: account) { result, _ in - let alert = UIAlertController(title: NSLocalizedString("Test results", comment: ""), - message: result, + NCAPIController.sharedInstance().testPushnotifications(forAccount: account) { result in + let isEmptyResult = result?.isEmpty ?? true + let title = isEmptyResult ? NSLocalizedString("Test failed", comment: "") : NSLocalizedString("Test results", comment: "") + let message = isEmptyResult ? NSLocalizedString("An error occurred while testing push notifications", comment: "") : result + let alert = UIAlertController(title: title, + message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default)) - alert.addAction(UIAlertAction(title: NSLocalizedString("Copy", comment: ""), style: .default) { _ in - UIPasteboard.general.string = result - NotificationPresenter.shared().present(text: NSLocalizedString("Test results copied", comment: ""), dismissAfterDelay: 5.0, includedStyle: .dark) - }) + if !isEmptyResult { + alert.addAction(UIAlertAction(title: NSLocalizedString("Copy", comment: ""), style: .default) { _ in + UIPasteboard.general.string = result + NotificationPresenter.shared().present(text: NSLocalizedString("Test results copied", comment: ""), dismissAfterDelay: 5.0, includedStyle: .dark) + }) + } NCUserInterfaceController.sharedInstance().presentAlertViewController(alert) self.hidePushNotificationTestRunningIndicator() } diff --git a/NextcloudTalk/NCAPIControllerExtensions.swift b/NextcloudTalk/NCAPIControllerExtensions.swift index 8c2c09070..fdefe0741 100644 --- a/NextcloudTalk/NCAPIControllerExtensions.swift +++ b/NextcloudTalk/NCAPIControllerExtensions.swift @@ -562,10 +562,10 @@ import Foundation // MARK: - Push notification test - public func testPushnotifications(forAccount account: TalkAccount, completionBlock: @escaping (_ result: String?, _ error: Error?) -> Void) { + public func testPushnotifications(forAccount account: TalkAccount, completionBlock: @escaping (_ result: String?) -> Void) { guard let apiSessionManager = self.apiSessionManagers.object(forKey: account.accountId) as? NCAPISessionManager else { - completionBlock(nil, nil) + completionBlock(nil) return } @@ -573,7 +573,7 @@ import Foundation apiSessionManager.postOcs(urlString, account: account) { ocsResponse, ocsError in let message = ocsResponse?.dataDict?["message"] as? String - completionBlock(message, ocsError?.error) + completionBlock(message) } } } diff --git a/NextcloudTalk/en.lproj/Localizable.strings b/NextcloudTalk/en.lproj/Localizable.strings index 3306fd686..7a7560ba2 100644 --- a/NextcloudTalk/en.lproj/Localizable.strings +++ b/NextcloudTalk/en.lproj/Localizable.strings @@ -283,6 +283,9 @@ /* No comment provided by engineer. */ "An error occurred while sharing the file" = "An error occurred while sharing the file"; +/* No comment provided by engineer. */ +"An error occurred while testing push notifications" = "An error occurred while testing push notifications"; + /* No comment provided by engineer. */ "an hour" = "an hour"; @@ -1726,6 +1729,9 @@ /* No comment provided by engineer. */ "Tap and hold to record a voice message, release the button to send it." = "Tap and hold to record a voice message, release the button to send it."; +/* No comment provided by engineer. */ +"Test failed" = "Test failed"; + /* No comment provided by engineer. */ "Test push notifications" = "Test push notifications";