From 58425ecad5bf7ee7bc86935b2d9aa76b77d46bd2 Mon Sep 17 00:00:00 2001 From: shannon Date: Thu, 3 Apr 2025 14:57:49 -0400 Subject: [PATCH] Remove obsolete NotificationViewController Functionality replaced by #399 [BUG] Multiple interactions do not collapse into a single notification --- Mastodon.xcodeproj/project.pbxproj | 4 - .../NotificationViewController.swift | 249 ------------------ .../Root/MainTab/MainTabBarController.swift | 3 - 3 files changed, 256 deletions(-) delete mode 100644 Mastodon/Scene/Notification/NotificationViewController.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index e03fe33d8..421717699 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -421,7 +421,6 @@ DB98EB6227B215EB0082E365 /* ReportResultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB6127B215EB0082E365 /* ReportResultViewController.swift */; }; DB98EB6527B216500082E365 /* ReportResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB6427B216500082E365 /* ReportResultViewModel.swift */; }; DB9D6BE925E4F5340051B173 /* SearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6BE825E4F5340051B173 /* SearchViewController.swift */; }; - DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6BF725E4F5690051B173 /* NotificationViewController.swift */; }; DB9D6BFF25E4F5940051B173 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6BFE25E4F5940051B173 /* ProfileViewController.swift */; }; DB9E0D6F25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */; }; DB9F58EC26EF435000E7BBE9 /* AccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58EB26EF435000E7BBE9 /* AccountViewController.swift */; }; @@ -1140,7 +1139,6 @@ DB98EB6127B215EB0082E365 /* ReportResultViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportResultViewController.swift; sourceTree = ""; }; DB98EB6427B216500082E365 /* ReportResultViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportResultViewModel.swift; sourceTree = ""; }; DB9D6BE825E4F5340051B173 /* SearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewController.swift; sourceTree = ""; }; - DB9D6BF725E4F5690051B173 /* NotificationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationViewController.swift; sourceTree = ""; }; DB9D6BFE25E4F5940051B173 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = ""; }; DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIInterpolatingMotionEffect.swift; sourceTree = ""; }; DB9F58EB26EF435000E7BBE9 /* AccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountViewController.swift; sourceTree = ""; }; @@ -2786,7 +2784,6 @@ DB63F765279A5E5600455B82 /* NotificationTimeline */, 2D35237F26256F470031AF25 /* Cell */, D80F627E2B5C32E400877059 /* NotificationView */, - DB9D6BF725E4F5690051B173 /* NotificationViewController.swift */, 2D607AD726242FC500B70763 /* NotificationViewModel.swift */, 2D35237926256D920031AF25 /* NotificationSection.swift */, 2D7867182625B77500211898 /* NotificationListItem.swift */, @@ -3850,7 +3847,6 @@ DBEFCD7B282A162400C0ABEA /* ReportReasonView.swift in Sources */, D8E5C346296DAB84007E76A7 /* DataSourceFacade+Status+History.swift in Sources */, DB63F77B279ACAE500455B82 /* DataSourceFacade+Favorite.swift in Sources */, - DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */, 2DAC9E46262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift in Sources */, D8D688F92AB8B970000F651A /* SearchResultOverviewCoordinator.swift in Sources */, DB4FFC2C269EC39600D62E92 /* SearchTransitionController.swift in Sources */, diff --git a/Mastodon/Scene/Notification/NotificationViewController.swift b/Mastodon/Scene/Notification/NotificationViewController.swift deleted file mode 100644 index 4b9de69e1..000000000 --- a/Mastodon/Scene/Notification/NotificationViewController.swift +++ /dev/null @@ -1,249 +0,0 @@ -// -// NotificationViewController.swift -// Mastodon -// -// Created by sxiaojian on 2021/4/12. -// - -import UIKit -import Combine -import MastodonAsset -import MastodonLocalization -import Tabman -import Pageboy -import MastodonCore -import MastodonSDK - -final class NotificationViewController: TabmanViewController { - - var disposeBag = Set() - var observations = Set() - - var viewModel: NotificationViewModel? - - let pageSegmentedControl = UISegmentedControl() - - override func pageboyViewController( - _ pageboyViewController: PageboyViewController, - didScrollToPageAt index: TabmanViewController.PageIndex, - direction: PageboyViewController.NavigationDirection, - animated: Bool - ) { - super.pageboyViewController( - pageboyViewController, - didScrollToPageAt: index, - direction: direction, - animated: animated - ) - - viewModel?.currentPageIndex = index - } - -} - -extension NotificationViewController { - override func viewDidLoad() { - super.viewDidLoad() - - view.backgroundColor = .secondarySystemBackground - - setupSegmentedControl(scopes: [.everything, .mentions]) - pageSegmentedControl.translatesAutoresizingMaskIntoConstraints = false - navigationItem.titleView = pageSegmentedControl - NSLayoutConstraint.activate([ - pageSegmentedControl.widthAnchor.constraint(greaterThanOrEqualToConstant: 287) - ]) - pageSegmentedControl.addTarget(self, action: #selector(NotificationViewController.pageSegmentedControlValueChanged(_:)), for: .valueChanged) - - dataSource = viewModel - viewModel?.$viewControllers - .receive(on: DispatchQueue.main) - .sink { [weak self] viewControllers in - guard let self = self else { return } - self.reloadData() - self.bounces = viewControllers.count > 1 - - } - .store(in: &disposeBag) - - viewModel?.viewControllers = [NotificationTimelineViewModel.Scope.everything, .mentions].map { scope in - createViewController(for: scope) - } - - viewModel?.$currentPageIndex - .receive(on: DispatchQueue.main) - .sink { [weak self] currentPageIndex in - guard let self = self else { return } - if self.pageSegmentedControl.selectedSegmentIndex != currentPageIndex { - self.pageSegmentedControl.selectedSegmentIndex = currentPageIndex - } - } - .store(in: &disposeBag) - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - - // https://github.com/mastodon/documentation/pull/1447#issuecomment-2149225659 - if let viewModel, viewModel.notificationPolicy != nil { - navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "line.3.horizontal.decrease.circle"), style: .plain, target: self, action: #selector(NotificationViewController.showNotificationPolicySettings(_:))) - } - - // needs trigger manually after onboarding dismiss - setNeedsStatusBarAppearanceUpdate() - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - - // reset notification count - NotificationService.shared.clearNotificationCountForActiveUser() - } - - override func viewWillDisappear(_ animated: Bool) { - super.viewWillDisappear(animated) - - // reset notification count - NotificationService.shared.clearNotificationCountForActiveUser() - } - - override func viewDidDisappear(_ animated: Bool) { - super.viewDidDisappear(animated) - -// aspectViewDidDisappear(animated) - } - - //MARK: - Actions - - @objc private func showNotificationPolicySettings(_ sender: Any) { - guard let viewModel, let policy = viewModel.notificationPolicy else { return } - - Task { - } - } -} - -extension NotificationViewController { - private func setupSegmentedControl(scopes: [NotificationTimelineViewModel.Scope]) { - pageSegmentedControl.removeAllSegments() - for (i, scope) in scopes.enumerated() { - pageSegmentedControl.insertSegment(withTitle: scope.title, at: i, animated: false) - } - - // set initial selection - guard let viewModel, !pageSegmentedControl.isSelected else { return } - if viewModel.currentPageIndex < pageSegmentedControl.numberOfSegments { - pageSegmentedControl.selectedSegmentIndex = viewModel.currentPageIndex - } else { - pageSegmentedControl.selectedSegmentIndex = 0 - } - } - - private func createViewController(for scope: NotificationTimelineViewModel.Scope) -> UIViewController { - guard let viewModel else { return UITableViewController() } - - let viewController = NotificationTimelineViewController( - viewModel: NotificationTimelineViewModel( - authenticationBox: viewModel.authenticationBox, - scope: scope, notificationPolicy: viewModel.notificationPolicy - ) - ) - - return viewController - } -} - -extension NotificationViewController { - @objc private func pageSegmentedControlValueChanged(_ sender: UISegmentedControl) { - let index = sender.selectedSegmentIndex - scrollToPage(.at(index: index), animated: true, completion: nil) - } -} - -// MARK: - ScrollViewContainer -extension NotificationViewController: ScrollViewContainer { - var scrollView: UIScrollView { - guard let viewController = currentViewController as? NotificationTimelineViewController else { - return UIScrollView() - } - return viewController.scrollView - } -} - - -extension NotificationViewController { - - enum CategorySwitch: String, CaseIterable { - case everything - case mentions - - var title: String { - switch self { - case .everything: return L10n.Scene.Notification.Keyobard.showEverything - case .mentions: return L10n.Scene.Notification.Keyobard.showMentions - } - } - - // UIKeyCommand input - var input: String { - switch self { - case .everything: return "[" // + shift + command - case .mentions: return "]" // + shift + command - } - } - - var modifierFlags: UIKeyModifierFlags { - switch self { - case .everything: return [.shift, .command] - case .mentions: return [.shift, .command] - } - } - - var propertyList: Any { - return rawValue - } - } - - var categorySwitchKeyCommands: [UIKeyCommand] { - CategorySwitch.allCases.map { category in - UIKeyCommand( - title: category.title, - image: nil, - action: #selector(NotificationViewController.showCategory(_:)), - input: category.input, - modifierFlags: category.modifierFlags, - propertyList: category.propertyList, - alternates: [], - discoverabilityTitle: nil, - attributes: [], - state: .off - ) - } - } - - @objc private func showCategory(_ sender: UIKeyCommand) { - guard let rawValue = sender.propertyList as? String, - let category = CategorySwitch(rawValue: rawValue) - else { return } - - switch category { - case .mentions: - scrollToPage(.last, animated: true, completion: nil) - case .everything: - scrollToPage(.first, animated: true, completion: nil) - } - } - - override var keyCommands: [UIKeyCommand]? { - return categorySwitchKeyCommands - } -} - - -//MARK: - NotificationPolicyViewControllerDelegate - -extension NotificationViewController: NotificationPolicyViewControllerDelegate { - func policyUpdated(_ viewController: NotificationPolicyViewController, newPolicy: Mastodon.Entity.NotificationPolicy) { - viewModel?.notificationPolicy = newPolicy - } -} diff --git a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift index 96e7be38a..9a54c4fbf 100644 --- a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift @@ -68,9 +68,6 @@ class MainTabBarController: UITabBarController { meProfileViewController.configureTabBarItem(with: .me) if let authenticationBox { - if let notificationController = notificationViewController as? NotificationViewController { - notificationController.viewModel = NotificationViewModel(context: AppContext.shared, authenticationBox: authenticationBox) - } homeTimelineViewController.viewModel = HomeTimelineViewModel(authenticationBox: authenticationBox) searchViewController.viewModel = SearchViewModel(authenticationBox: authenticationBox) }