diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index d8c2cb131..7476d75ac 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -165,8 +165,6 @@ D84FA0932AE6915800987F47 /* MBProgressHUD in Frameworks */ = {isa = PBXBuildFile; productRef = D84FA0922AE6915800987F47 /* MBProgressHUD */; }; D852C23C2AC5D02C00309232 /* AboutInstanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D852C23B2AC5D02C00309232 /* AboutInstanceViewController.swift */; }; D852C23E2AC5D03300309232 /* InstanceRulesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D852C23D2AC5D03300309232 /* InstanceRulesViewController.swift */; }; - D85DF96B2C481AF700A01408 /* NotificationPolicyFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85DF9682C481AF400A01408 /* NotificationPolicyFilterTableViewCell.swift */; }; - D85DF96C2C481AF700A01408 /* NotificationPolicyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85DF9692C481AF700A01408 /* NotificationPolicyViewController.swift */; }; D85DF96D2C481AF700A01408 /* NotificationPolicyHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85DF96A2C481AF700A01408 /* NotificationPolicyHeaderView.swift */; }; D85DF9712C481B1100A01408 /* NotificationRequestsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85DF96E2C481B1100A01408 /* NotificationRequestsTableViewController.swift */; }; D85DF9722C481B1100A01408 /* NotificationRequestTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85DF96F2C481B1100A01408 /* NotificationRequestTableViewCell.swift */; }; @@ -820,8 +818,6 @@ D84C09A42B0F9E41009E685E /* Acknowledgments.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Acknowledgments.md; sourceTree = ""; }; D852C23B2AC5D02C00309232 /* AboutInstanceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutInstanceViewController.swift; sourceTree = ""; }; D852C23D2AC5D03300309232 /* InstanceRulesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceRulesViewController.swift; sourceTree = ""; }; - D85DF9682C481AF400A01408 /* NotificationPolicyFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NotificationPolicyFilterTableViewCell.swift; path = Policy/NotificationPolicyFilterTableViewCell.swift; sourceTree = ""; }; - D85DF9692C481AF700A01408 /* NotificationPolicyViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NotificationPolicyViewController.swift; path = Policy/NotificationPolicyViewController.swift; sourceTree = ""; }; D85DF96A2C481AF700A01408 /* NotificationPolicyHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NotificationPolicyHeaderView.swift; path = Policy/NotificationPolicyHeaderView.swift; sourceTree = ""; }; D85DF96E2C481B1100A01408 /* NotificationRequestsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationRequestsTableViewController.swift; sourceTree = ""; }; D85DF96F2C481B1100A01408 /* NotificationRequestTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationRequestTableViewCell.swift; sourceTree = ""; }; @@ -1842,9 +1838,7 @@ D80EC2602C2978CB009724A5 /* Notification Filtering */ = { isa = PBXGroup; children = ( - D85DF9682C481AF400A01408 /* NotificationPolicyFilterTableViewCell.swift */, D85DF96A2C481AF700A01408 /* NotificationPolicyHeaderView.swift */, - D85DF9692C481AF700A01408 /* NotificationPolicyViewController.swift */, FB0F8E922DA54A090058C09E /* NotificationPolicyHostingViewController.swift */, ); path = "Notification Filtering"; @@ -3710,7 +3704,6 @@ 2D38F1EB25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift in Sources */, DB5B7295273112B100081888 /* FollowingListViewController.swift in Sources */, 0F202201261326E6000C64BF /* HashtagTimelineViewModel.swift in Sources */, - D85DF96C2C481AF700A01408 /* NotificationPolicyViewController.swift in Sources */, D81A94172B07A1D30067A19D /* ProfileCardView+Configuration.swift in Sources */, DB63F7452799056400455B82 /* HashtagTableViewCell.swift in Sources */, D82BD7552ABC73AF009A374A /* NotificationPolicyTableViewCell.swift in Sources */, @@ -3732,7 +3725,6 @@ 2DAC9E38262FC2320062E1A6 /* SuggestionAccountViewController.swift in Sources */, DB6180E02639194B0018D199 /* MediaPreviewPagingViewController.swift in Sources */, D8E5C349296DB8A3007E76A7 /* StatusEditHistoryViewController.swift in Sources */, - D85DF96B2C481AF700A01408 /* NotificationPolicyFilterTableViewCell.swift in Sources */, DBE0822425CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift in Sources */, D8318A882A4468D300C0FB73 /* NotificationSettingsViewController.swift in Sources */, 2D82B9FF25E7863200E36F0F /* OnboardingViewControllerAppearance.swift in Sources */, diff --git a/Mastodon/Scene/Notification/Notification Filtering/Policy/NotificationPolicyFilterTableViewCell.swift b/Mastodon/Scene/Notification/Notification Filtering/Policy/NotificationPolicyFilterTableViewCell.swift deleted file mode 100644 index 83bba7a85..000000000 --- a/Mastodon/Scene/Notification/Notification Filtering/Policy/NotificationPolicyFilterTableViewCell.swift +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright © 2024 Mastodon gGmbH. All rights reserved. - -import MastodonSDK -import UIKit -import MastodonLocalization -import MastodonAsset - -protocol NotificationPolicyFilterTableViewCellDelegate: AnyObject { - func pickerValueChanged( - _ tableViewCell: NotificationPolicyFilterTableViewCell, - filterItem: NotificationFilterItem, - newValue: Mastodon.Entity.NotificationPolicy.NotificationFilterAction) -} - -class NotificationPolicyFilterTableViewCell: TrailingButtonTableViewCell -{ - typealias FilterActionOption = Mastodon.Entity.NotificationPolicy.NotificationFilterAction - - override class var reuseIdentifier: String { - return "NotificationPolicyFilterTableViewCell" - } - - private let options: - [FilterActionOption] = [ - .accept, .filter, .drop, - ] - - var filterItem: NotificationFilterItem? - weak var delegate: NotificationPolicyFilterTableViewCellDelegate? - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - - label.font = UIFontMetrics(forTextStyle: .body).scaledFont( - for: .systemFont(ofSize: 17, weight: .regular)) - subtitleLabel.textColor = .secondaryLabel - subtitleLabel.font = UIFontMetrics(forTextStyle: .subheadline) - .scaledFont(for: .systemFont(ofSize: 15, weight: .regular)) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private func indexForOption(_ option: FilterActionOption) -> Int { - return options.firstIndex(of: option) ?? 0 - } - - public func configure( - with filterItem: NotificationFilterItem, - viewModel: NotificationFilterViewModel - ) { - label.text = filterItem.title - subtitleLabel.text = filterItem.subtitle - self.filterItem = filterItem - - let buttonTitle: String - switch viewModel.value(forItem: filterItem) { - case .accept: buttonTitle = L10n.Scene.Notification.Policy.Action.Accept.title - case .filter: buttonTitle = L10n.Scene.Notification.Policy.Action.Filter.title - case .drop: buttonTitle = L10n.Scene.Notification.Policy.Action.Drop.title - case ._other(let string): buttonTitle = string - } - button.configuration = .bordered() - button.configuration?.title = buttonTitle - button.configuration?.background.strokeColor = Asset.Colors.Brand.blurple.color - button.configuration?.baseForegroundColor = Asset.Colors.Brand.blurple.color - button.showsMenuAsPrimaryAction = true - - let menuActions = [FilterActionOption.accept, .filter, .drop].map { option in - UIAction(title: option.displayTitle, subtitle: option.displaySubtitle, state: viewModel.value(forItem: filterItem) == option ? .on : .off, handler: { [weak self] _ in - guard let self else { return } - self.delegate?.pickerValueChanged(self, filterItem: filterItem, newValue: option) - }) - } - - button.menu = UIMenu.init(children: menuActions) - } -} - -protocol NotificationAdminFilterTableViewCellDelegate: AnyObject { - func toggleValueChanged( - _ tableViewCell: NotificationAdminFilterTableViewCell, - filterItem: NotificationFilterItem, - newValue: Bool) -} - -class NotificationAdminFilterTableViewCell: ToggleTableViewCell { - override class var reuseIdentifier: String { - return "NotificationAdminFilterTableViewCell" - } - - var filterItem: NotificationFilterItem? - weak var delegate: NotificationAdminFilterTableViewCellDelegate? - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - - label.font = UIFontMetrics(forTextStyle: .body).scaledFont( - for: .systemFont(ofSize: 17, weight: .regular)) - subtitleLabel.textColor = .secondaryLabel - subtitleLabel.font = UIFontMetrics(forTextStyle: .subheadline) - .scaledFont(for: .systemFont(ofSize: 15, weight: .regular)) - - toggle.addTarget( - self, - action: #selector( - NotificationAdminFilterTableViewCell.toggleValueChanged(_:)), - for: .valueChanged) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - public func configure( - with filterItem: NotificationFilterItem, - viewModel: NotificationFilterViewModel - ) { - label.text = filterItem.title - subtitleLabel.text = filterItem.subtitle - self.filterItem = filterItem - - let toggleIsOn = viewModel.value(forItem: filterItem) == .accept - - toggle.isOn = toggleIsOn - } - - @objc func toggleValueChanged(_ sender: UISwitch) { - guard let filterItem, let delegate else { return } - - delegate.toggleValueChanged( - self, filterItem: filterItem, newValue: sender.isOn) - } -} - -extension Mastodon.Entity.NotificationPolicy.NotificationFilterAction { - var displayTitle: String { - switch self { - case .accept: return L10n.Scene.Notification.Policy.Action.Accept.title - case .filter: return L10n.Scene.Notification.Policy.Action.Filter.title - case .drop: return L10n.Scene.Notification.Policy.Action.Drop.title - case ._other(let string): return string - } - } - - var displaySubtitle: String { - switch self { - case .accept: return L10n.Scene.Notification.Policy.Action.Accept.subtitle - case .filter: return L10n.Scene.Notification.Policy.Action.Filter.subtitle - case .drop: return L10n.Scene.Notification.Policy.Action.Drop.subtitle - case ._other: return "" - } - } -} diff --git a/Mastodon/Scene/Notification/Notification Filtering/Policy/NotificationPolicyViewController.swift b/Mastodon/Scene/Notification/Notification Filtering/Policy/NotificationPolicyViewController.swift deleted file mode 100644 index 3bdd0bbf4..000000000 --- a/Mastodon/Scene/Notification/Notification Filtering/Policy/NotificationPolicyViewController.swift +++ /dev/null @@ -1,392 +0,0 @@ -// Copyright © 2024 Mastodon gGmbH. All rights reserved. - -import MastodonAsset -import MastodonCore -import MastodonLocalization -import MastodonSDK -import UIKit - -enum NotificationFilterSection: Hashable { - case main - case admin -} - -enum NotificationFilterItem: Hashable { - case notFollowing - case notFollowers - case newAccounts - case privateMentions - case limitedAccounts - - case adminReports - case adminSignups - - static let regularOptions = [Self.notFollowing, .notFollowers, .newAccounts, .privateMentions, .limitedAccounts] - static let adminOptions = [Self.adminReports, .adminSignups] - - var title: String { - switch self { - case .notFollowing: - return L10n.Scene.Notification.Policy.NotFollowing.title - case .notFollowers: - return L10n.Scene.Notification.Policy.NoFollower.title - case .newAccounts: - return L10n.Scene.Notification.Policy.NewAccount.title - case .privateMentions: - return L10n.Scene.Notification.Policy.PrivateMentions.title - case .limitedAccounts: - return L10n.Scene.Notification.Policy.ModeratedAccounts.title - - case .adminReports: - return L10n.Scene.Notification.AdminFilter.Reports.title - case .adminSignups: - return L10n.Scene.Notification.AdminFilter.Signups.title - } - } - - var subtitle: String { - switch self { - case .notFollowing: - return L10n.Scene.Notification.Policy.NotFollowing.subtitle - case .notFollowers: - return L10n.Scene.Notification.Policy.NoFollower.subtitle - case .newAccounts: - return L10n.Scene.Notification.Policy.NewAccount.subtitle - case .privateMentions: - return L10n.Scene.Notification.Policy.PrivateMentions.subtitle - case .limitedAccounts: - return L10n.Scene.Notification.Policy.ModeratedAccounts.subtitle - - case .adminReports: - return L10n.Scene.Notification.AdminFilter.Reports.subtitle - case .adminSignups: - return L10n.Scene.Notification.AdminFilter.Signups.subtitle - } - } -} - -struct NotificationFilterSettings: Codable, Equatable { - let forNotFollowing: Mastodon.Entity.NotificationPolicy.NotificationFilterAction - let forNotFollowers: Mastodon.Entity.NotificationPolicy.NotificationFilterAction - let forNewAccounts: Mastodon.Entity.NotificationPolicy.NotificationFilterAction - let forPrivateMentions: Mastodon.Entity.NotificationPolicy.NotificationFilterAction - let forLimitedAccounts: Mastodon.Entity.NotificationPolicy.NotificationFilterAction -} -struct AdminNotificationFilterSettings: Codable, Equatable { - let forReports: Mastodon.Entity.NotificationPolicy.NotificationFilterAction - let forSignups: Mastodon.Entity.NotificationPolicy.NotificationFilterAction - - var excludedNotificationTypes: [Mastodon.Entity.NotificationType]? { - var excluded = [Mastodon.Entity.NotificationType]() - if forReports != .accept { - excluded.append(.adminReport) - } - if forSignups != .accept { - excluded.append(.adminSignUp) - } - return excluded.isEmpty ? nil : excluded - } -} - -class NotificationFilterViewModel { - let originalRegularSettings: NotificationFilterSettings - let originalAdminSettings: AdminNotificationFilterSettings? - - var regularFilterSettings: NotificationFilterSettings - var adminFilterSettings: AdminNotificationFilterSettings? - - init( - _ regularSettings: NotificationFilterSettings, - adminSettings: AdminNotificationFilterSettings? - ) async { - self.originalRegularSettings = regularSettings - self.regularFilterSettings = regularSettings - self.originalAdminSettings = adminSettings - self.adminFilterSettings = adminSettings - } - - func value(forItem item: NotificationFilterItem) -> Mastodon.Entity.NotificationPolicy.NotificationFilterAction { - switch item { - case .notFollowing: - return regularFilterSettings.forNotFollowing - case .notFollowers: - return regularFilterSettings.forNotFollowers - case .newAccounts: - return regularFilterSettings.forNewAccounts - case .privateMentions: - return regularFilterSettings.forPrivateMentions - case .limitedAccounts: - return regularFilterSettings.forLimitedAccounts - case .adminReports: - return adminFilterSettings?.forReports ?? .drop - case .adminSignups: - return adminFilterSettings?.forSignups ?? .drop - } - } - - func setValue(_ value: Mastodon.Entity.NotificationPolicy.NotificationFilterAction, forItem item: NotificationFilterItem) { - switch item { - case .notFollowing: - regularFilterSettings = NotificationFilterSettings( - forNotFollowing: value, - forNotFollowers: regularFilterSettings.forNotFollowers, - forNewAccounts: regularFilterSettings.forNewAccounts, - forPrivateMentions: regularFilterSettings.forPrivateMentions, - forLimitedAccounts: regularFilterSettings.forLimitedAccounts) - case .notFollowers: - regularFilterSettings = NotificationFilterSettings( - forNotFollowing: regularFilterSettings.forNotFollowing, - forNotFollowers: value, - forNewAccounts: regularFilterSettings.forNewAccounts, - forPrivateMentions: regularFilterSettings.forPrivateMentions, - forLimitedAccounts: regularFilterSettings.forLimitedAccounts) - case .newAccounts: - regularFilterSettings = NotificationFilterSettings( - forNotFollowing: regularFilterSettings.forNotFollowing, - forNotFollowers: regularFilterSettings.forNotFollowers, - forNewAccounts: value, - forPrivateMentions: regularFilterSettings.forPrivateMentions, - forLimitedAccounts: regularFilterSettings.forLimitedAccounts) - case .privateMentions: - regularFilterSettings = NotificationFilterSettings( - forNotFollowing: regularFilterSettings.forNotFollowing, - forNotFollowers: regularFilterSettings.forNotFollowers, - forNewAccounts: regularFilterSettings.forNewAccounts, - forPrivateMentions: value, - forLimitedAccounts: regularFilterSettings.forLimitedAccounts) - case .limitedAccounts: - regularFilterSettings = NotificationFilterSettings( - forNotFollowing: regularFilterSettings.forNotFollowing, - forNotFollowers: regularFilterSettings.forNotFollowers, - forNewAccounts: regularFilterSettings.forNewAccounts, - forPrivateMentions: regularFilterSettings.forPrivateMentions, - forLimitedAccounts: value) - - case .adminReports: - guard let adminFilterSettings else { return } - self.adminFilterSettings = AdminNotificationFilterSettings( - forReports: value, - forSignups: adminFilterSettings.forSignups) - case .adminSignups: - guard let adminFilterSettings else { return } - self.adminFilterSettings = AdminNotificationFilterSettings( - forReports: adminFilterSettings.forReports, - forSignups: value) - } - } -} - -protocol NotificationPolicyViewControllerDelegate: AnyObject { - func policyUpdated( - _ viewController: NotificationPolicyViewController, - newPolicy: Mastodon.Entity.NotificationPolicy) -} - -class NotificationPolicyViewController: UIViewController { - - let tableView: UITableView - let headerBar: NotificationPolicyHeaderView - var saveItem: UIBarButtonItem? - var dataSource: - UITableViewDiffableDataSource< - NotificationFilterSection, NotificationFilterItem - >? - let regularItems: [NotificationFilterItem] - let adminItems: [NotificationFilterItem] - var viewModel: NotificationFilterViewModel - weak var delegate: NotificationPolicyViewControllerDelegate? - - init(viewModel: NotificationFilterViewModel) { - self.viewModel = viewModel - regularItems = [.notFollowing, .notFollowers, .newAccounts, .privateMentions, .limitedAccounts] - adminItems = [.adminReports, .adminSignups] - - headerBar = NotificationPolicyHeaderView() - headerBar.translatesAutoresizingMaskIntoConstraints = false - - tableView = UITableView(frame: .zero, style: .insetGrouped) - tableView.translatesAutoresizingMaskIntoConstraints = false - tableView.register( - NotificationPolicyFilterTableViewCell.self, - forCellReuseIdentifier: NotificationPolicyFilterTableViewCell.reuseIdentifier - ) - tableView.register( - NotificationAdminFilterTableViewCell.self, - forCellReuseIdentifier: NotificationAdminFilterTableViewCell.reuseIdentifier - ) - tableView.contentInset.top = -20 - - super.init(nibName: nil, bundle: nil) - - let dataSource = UITableViewDiffableDataSource< - NotificationFilterSection, NotificationFilterItem - >(tableView: tableView) { - [weak self] tableView, indexPath, itemIdentifier in - guard let self else { - fatalError("No NotificationPolicyFilterTableViewCell") - } - - let cell = tableView.dequeueReusableCell( - withIdentifier: indexPath.section == 0 ? NotificationPolicyFilterTableViewCell - .reuseIdentifier: NotificationAdminFilterTableViewCell.reuseIdentifier, for: indexPath) - - let item: NotificationFilterItem? - switch indexPath.section { - case 0: - item = regularItems[indexPath.row] - case 1: - item = adminItems[indexPath.row] - default: - item = nil - assertionFailure() - } - guard let item else { return nil } - if let cell = cell as? NotificationAdminFilterTableViewCell { - cell.configure(with: item, viewModel: self.viewModel) - cell.delegate = self - } else if let cell = cell as? NotificationPolicyFilterTableViewCell { - cell.configure(with: item, viewModel: self.viewModel) - cell.delegate = self - } - return cell - } - - tableView.dataSource = dataSource - tableView.delegate = self - - self.dataSource = dataSource - view.addSubview(headerBar) - view.addSubview(tableView) - view.backgroundColor = .systemGroupedBackground - headerBar.closeButton.addTarget( - self, action: #selector(NotificationPolicyViewController.save(_:)), - for: .touchUpInside) - - setupConstraints() - } - - override func viewDidLoad() { - super.viewDidLoad() - - var snapshot = NSDiffableDataSourceSnapshot< - NotificationFilterSection, NotificationFilterItem - >() - - snapshot.appendSections([.main]) - snapshot.appendItems(regularItems) - if viewModel.adminFilterSettings != nil { - snapshot.appendSections([.admin]) - snapshot.appendItems(adminItems) - } - - dataSource?.apply(snapshot, animatingDifferences: false) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private func setupConstraints() { - let constraints = [ - headerBar.topAnchor.constraint(equalTo: view.topAnchor), - headerBar.leadingAnchor.constraint(equalTo: view.leadingAnchor), - view.trailingAnchor.constraint(equalTo: headerBar.trailingAnchor), - - tableView.topAnchor.constraint(equalTo: headerBar.bottomAnchor), - tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - view.trailingAnchor.constraint(equalTo: tableView.trailingAnchor), - view.bottomAnchor.constraint(equalTo: tableView.bottomAnchor), - ] - - NSLayoutConstraint.activate(constraints) - } - - // MARK: - Action - - @objc private func save(_ sender: UIButton) { - guard - let authenticationBox = AuthenticationServiceProvider.shared - .currentActiveUser.value - else { return } - - Task { [weak self] in - guard let self else { return } - - do { - if let adminPreferences = viewModel.adminFilterSettings, viewModel.adminFilterSettings != viewModel.originalAdminSettings { - try await BodegaPersistence.Notifications.updatePreferences(adminPreferences, for: authenticationBox) - } - } catch {} - - do { - let updatedPolicy = try await APIService.shared - .updateNotificationPolicy( - authenticationBox: authenticationBox, - forNotFollowing: viewModel.value(forItem: .notFollowing), - forNotFollowers: viewModel.value(forItem: .notFollowers), - forNewAccounts: viewModel.value(forItem: .newAccounts), - forPrivateMentions: viewModel.value(forItem: .privateMentions), - forLimitedAccounts: viewModel.value(forItem: .limitedAccounts) - ).value - - delegate?.policyUpdated(self, newPolicy: updatedPolicy) - - NotificationCenter.default.post( - name: .notificationFilteringChanged, object: nil) - - } catch {} - } - - dismiss(animated: true) - } - - @objc private func cancel(_ sender: UIBarButtonItem) { - dismiss(animated: true) - } -} - -//MARK: - UITableViewDelegate - -extension NotificationPolicyViewController: UITableViewDelegate { - func tableView( - _ tableView: UITableView, didSelectRowAt indexPath: IndexPath - ) { - tableView.deselectRow(at: indexPath, animated: true) - - guard indexPath.section == 1 else { return } - let filterItem: NotificationFilterItem? = adminItems[indexPath.row] - guard let filterItem else { return } - let currentValue = viewModel.value(forItem: filterItem) == .accept - setBool(!currentValue, forItem: filterItem) - - if let snapshot = dataSource?.snapshot() { - dataSource?.applySnapshotUsingReloadData(snapshot) - } - } -} - -extension NotificationPolicyViewController { - func setBool(_ boolValue: Bool, forItem filterItem: NotificationFilterItem) { - let option = boolValue ? Mastodon.Entity.NotificationPolicy.NotificationFilterAction.accept : .drop - viewModel.setValue(option, forItem: filterItem) - tableView.reloadData() - } -} - -extension NotificationPolicyViewController: - NotificationPolicyFilterTableViewCellDelegate -{ - func pickerValueChanged(_ tableViewCell: NotificationPolicyFilterTableViewCell, filterItem: NotificationFilterItem, newValue: MastodonSDK.Mastodon.Entity.NotificationPolicy.NotificationFilterAction) { - viewModel.setValue(newValue, forItem: filterItem) - tableView.reloadData() - } -} - -extension NotificationPolicyViewController : NotificationAdminFilterTableViewCellDelegate { - func toggleValueChanged( - _ tableViewCell: NotificationAdminFilterTableViewCell, - filterItem: NotificationFilterItem, newValue: Bool - ) { - setBool(newValue, forItem: filterItem) - } -}