diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 003fef6e8..83e72ae63 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -538,13 +538,15 @@ private extension SceneCoordinator { viewController = activityViewController case .settings(let setting): guard let presentedOn = sender, - let accountName = authContext?.mastodonAuthenticationBox.authenticationRecord.object(in: appContext.managedObjectContext)?.username + let accountName = authContext?.mastodonAuthenticationBox.authenticationRecord.object(in: appContext.managedObjectContext)?.username, + let authContext else { return nil } let settingsCoordinator = SettingsCoordinator(presentedOn: presentedOn, accountName: accountName, setting: setting, - appContext: appContext) + appContext: appContext, + authContext: authContext) settingsCoordinator.delegate = self settingsCoordinator.start() diff --git a/Mastodon/Scene/Settings/Notification Settings/NotificationSettingTableViewToggleCell.swift b/Mastodon/Scene/Settings/Notification Settings/NotificationSettingTableViewToggleCell.swift index c8b1600f6..032b20ed6 100644 --- a/Mastodon/Scene/Settings/Notification Settings/NotificationSettingTableViewToggleCell.swift +++ b/Mastodon/Scene/Settings/Notification Settings/NotificationSettingTableViewToggleCell.swift @@ -3,7 +3,7 @@ import UIKit protocol NotificationSettingToggleCellDelegate: AnyObject { - + func toggleValueChanged(_ tableViewCell: NotificationSettingTableViewToggleCell, alert: NotificationAlert, newValue: Bool) } class NotificationSettingTableViewToggleCell: ToggleTableViewCell { @@ -45,6 +45,8 @@ class NotificationSettingTableViewToggleCell: ToggleTableViewCell { @objc func toggleValueChanged(_ sender: UISwitch) { - + guard let alert else { return } + + delegate?.toggleValueChanged(self, alert: alert, newValue: sender.isOn) } } diff --git a/Mastodon/Scene/Settings/Notification Settings/NotificationSettingsViewController.swift b/Mastodon/Scene/Settings/Notification Settings/NotificationSettingsViewController.swift index 499d9ab0a..c56c23e4c 100644 --- a/Mastodon/Scene/Settings/Notification Settings/NotificationSettingsViewController.swift +++ b/Mastodon/Scene/Settings/Notification Settings/NotificationSettingsViewController.swift @@ -5,6 +5,7 @@ import CoreDataStack import MastodonLocalization protocol NotificationSettingsViewControllerDelegate: AnyObject { + func viewWillDisappear(_ viewController: UIViewController, viewModel: NotificationSettingsViewModel) func showPolicyList(_ viewController: UIViewController, viewModel: NotificationSettingsViewModel) } @@ -88,6 +89,20 @@ class NotificationSettingsViewController: UIViewController { tableViewDataSource?.apply(snapshot, animatingDifferences: false) } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + if let snapshot = tableViewDataSource?.snapshot() { + tableViewDataSource?.applySnapshotUsingReloadData(snapshot) + } + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + + delegate?.viewWillDisappear(self, viewModel: viewModel) + } } extension NotificationSettingsViewController: UITableViewDelegate { @@ -107,5 +122,18 @@ extension NotificationSettingsViewController: UITableViewDelegate { } extension NotificationSettingsViewController: NotificationSettingToggleCellDelegate { - + func toggleValueChanged(_ tableViewCell: NotificationSettingTableViewToggleCell, alert: NotificationAlert, newValue: Bool) { + switch alert { + case .mentionsAndReplies: + viewModel.notifyMentions = newValue + case .boosts: + viewModel.notifyBoosts = newValue + case .favorites: + viewModel.notifyFavorites = newValue + case .newFollowers: + viewModel.notifyNewFollowers = newValue + } + + viewModel.updated = true + } } diff --git a/Mastodon/Scene/Settings/Notification Settings/PolicySelectionViewController.swift b/Mastodon/Scene/Settings/Notification Settings/PolicySelectionViewController.swift index edda3bc35..b0fa34cae 100644 --- a/Mastodon/Scene/Settings/Notification Settings/PolicySelectionViewController.swift +++ b/Mastodon/Scene/Settings/Notification Settings/PolicySelectionViewController.swift @@ -64,15 +64,17 @@ class PolicySelectionViewController: UIViewController { extension PolicySelectionViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - tableView.deselectRow(at: indexPath, animated: true) let newPolicy = sections[indexPath.section].entries[indexPath.row] viewModel.selectedPolicy = newPolicy + viewModel.updated = true if let dataSource { dataSource.applySnapshotUsingReloadData(dataSource.snapshot()) } delegate?.newPolicySelected(self, newPolicy: newPolicy) + + tableView.deselectRow(at: indexPath, animated: true) } } diff --git a/Mastodon/Scene/Settings/SettingsCoordinator.swift b/Mastodon/Scene/Settings/SettingsCoordinator.swift index e00d56b98..b945632a7 100644 --- a/Mastodon/Scene/Settings/SettingsCoordinator.swift +++ b/Mastodon/Scene/Settings/SettingsCoordinator.swift @@ -4,6 +4,8 @@ import UIKit import AuthenticationServices import MastodonCore import CoreDataStack +import MastodonSDK +import Combine protocol SettingsCoordinatorDelegate: AnyObject { func logout(_ settingsCoordinator: SettingsCoordinator) @@ -22,12 +24,15 @@ class SettingsCoordinator: NSObject, Coordinator { let setting: Setting let appContext: AppContext + let authContext: AuthContext + var disposeBag = Set() - init(presentedOn: UIViewController, accountName: String, setting: Setting, appContext: AppContext) { + init(presentedOn: UIViewController, accountName: String, setting: Setting, appContext: AppContext, authContext: AuthContext) { self.presentedOn = presentedOn navigationController = UINavigationController() self.setting = setting self.appContext = appContext + self.authContext = authContext settingsViewController = SettingsViewController(accountName: accountName) } @@ -131,11 +136,50 @@ extension SettingsCoordinator: NotificationSettingsViewControllerDelegate { navigationController.pushViewController(policyListViewController, animated: true) } + + func viewWillDisappear(_ viewController: UIViewController, viewModel: NotificationSettingsViewModel) { + + guard viewModel.updated else { return } + + let authenticationBox = authContext.mastodonAuthenticationBox + guard let subscription = setting.activeSubscription, + setting.domain == authenticationBox.domain, + setting.userID == authenticationBox.userID, + let legacyViewModel = appContext.notificationService.dequeueNotificationViewModel(mastodonAuthenticationBox: authenticationBox), let deviceToken = appContext.notificationService.deviceToken.value else { return } + + let queryData = Mastodon.API.Subscriptions.QueryData( + policy: viewModel.selectedPolicy.subscriptionPolicy, + alerts: Mastodon.API.Subscriptions.QueryData.Alerts( + favourite: viewModel.notifyFavorites, + follow: viewModel.notifyNewFollowers, + reblog: viewModel.notifyBoosts, + mention: viewModel.notifyMentions, + poll: subscription.alert.poll + ) + ) + let query = legacyViewModel.createSubscribeQuery( + deviceToken: deviceToken, + queryData: queryData, + mastodonAuthenticationBox: authenticationBox + ) + + appContext.apiService.createSubscription( + subscriptionObjectID: subscription.objectID, + query: query, + mastodonAuthenticationBox: authenticationBox + ).sink(receiveCompletion: { completion in + print(completion) + }, receiveValue: { output in + print(output) + }) + .store(in: &disposeBag) + } } //MARK: - PolicySelectionViewControllerDelegate extension SettingsCoordinator: PolicySelectionViewControllerDelegate { func newPolicySelected(_ viewController: PolicySelectionViewController, newPolicy: NotificationPolicy) { - //TODO: Send to backend etc. + self.setting.activeSubscription?.policyRaw = newPolicy.subscriptionPolicy.rawValue + try? self.appContext.managedObjectContext.save() } } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Subscriptions.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Subscriptions.swift index c29505785..5b90eb8c3 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Subscriptions.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Subscriptions.swift @@ -13,7 +13,7 @@ import MastodonSDK extension APIService { - func createSubscription( + public func createSubscription( subscriptionObjectID: NSManagedObjectID, query: Mastodon.API.Subscriptions.CreateSubscriptionQuery, mastodonAuthenticationBox: MastodonAuthenticationBox @@ -34,6 +34,12 @@ extension APIService { assertionFailure() return } + + subscription.alert.update(favourite: response.value.alerts.favourite) + subscription.alert.update(reblog: response.value.alerts.reblog) + subscription.alert.update(follow: response.value.alerts.follow) + subscription.alert.update(mention: response.value.alerts.mention) + subscription.endpoint = response.value.endpoint subscription.serverKey = response.value.serverKey subscription.userToken = authorization.accessToken diff --git a/MastodonSDK/Sources/MastodonCore/Service/Notification/NotificationService.swift b/MastodonSDK/Sources/MastodonCore/Service/Notification/NotificationService.swift index 0ed4004e3..b1f467385 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/Notification/NotificationService.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/Notification/NotificationService.swift @@ -127,7 +127,7 @@ extension NotificationService { extension NotificationService { - func dequeueNotificationViewModel( + public func dequeueNotificationViewModel( mastodonAuthenticationBox: MastodonAuthenticationBox ) -> NotificationViewModel? { var _notificationSubscription: NotificationViewModel? @@ -281,7 +281,7 @@ extension NotificationService { } extension NotificationService.NotificationViewModel { - func createSubscribeQuery( + public func createSubscribeQuery( deviceToken: Data, queryData: Mastodon.API.Subscriptions.QueryData, mastodonAuthenticationBox: MastodonAuthenticationBox