From 65bf555d9891fe1ac17dbff86f89044934700c70 Mon Sep 17 00:00:00 2001 From: shannon Date: Mon, 2 Dec 2024 14:45:15 -0500 Subject: [PATCH] Refactor: Remove NeedsDependency The AppContext is already a singleton. SceneCoordinators are unique to UIWindowScenes, so fetch them that way. Fixes iOS-324 --- Mastodon.xcodeproj/project.pbxproj | 4 -- Mastodon/Activity/SafariActivity.swift | 2 +- Mastodon/Coordinator/NeedsDependency.swift | 19 ------- Mastodon/Coordinator/SceneCoordinator.swift | 44 +++++++-------- Mastodon/Diffable/Report/ReportSection.swift | 4 -- Mastodon/Diffable/Status/StatusSection.swift | 18 +----- Mastodon/Diffable/User/UserSection.swift | 1 - .../Provider/DataSourceFacade+Block.swift | 4 +- .../Provider/DataSourceFacade+Bookmark.swift | 2 +- .../Provider/DataSourceFacade+Follow.swift | 9 +-- .../Provider/DataSourceFacade+Hashtag.swift | 10 ++-- .../Provider/DataSourceFacade+Media.swift | 12 ++-- .../Provider/DataSourceFacade+Meta.swift | 5 +- .../Provider/DataSourceFacade+Mute.swift | 2 +- .../DataSourceFacade+Notifications.swift | 23 ++++---- .../Provider/DataSourceFacade+Profile.swift | 55 +++++++++++-------- .../DataSourceFacade+SearchHistory.swift | 2 +- .../DataSourceFacade+Status+History.swift | 2 +- .../Provider/DataSourceFacade+Status.swift | 49 +++++++++-------- .../Provider/DataSourceFacade+Thread.swift | 11 ++-- .../Provider/DataSourceFacade+Translate.swift | 4 +- .../Provider/DataSourceFacade+URL.swift | 7 ++- .../Provider/DataSourceFacade+UserView.swift | 3 +- ...Provider+StatusTableViewCellDelegate.swift | 27 +++++---- ...tatusTableViewControllerNavigateable.swift | 3 +- ...taSourceProvider+UITableViewDelegate.swift | 9 ++- .../Provider/DataSourceProvider.swift | 2 +- .../Scene/Account/AccountListViewModel.swift | 4 +- .../Scene/Account/AccountViewController.swift | 19 +++---- .../Scene/Compose/ComposeViewController.swift | 14 ++--- Mastodon/Scene/Compose/ComposeViewModel.swift | 3 - .../Scene/Discovery/DiscoverySection.swift | 1 - .../Discovery/DiscoveryViewController.swift | 5 +- .../Scene/Discovery/DiscoveryViewModel.swift | 21 ++----- .../DiscoveryForYouViewController.swift | 12 ++-- .../DiscoveryForYouViewModel+Diffable.swift | 1 - .../ForYou/DiscoveryForYouViewModel.swift | 4 +- .../DiscoveryHashtagsViewController.swift | 13 ++--- .../DiscoveryHashtagsViewModel+Diffable.swift | 1 - .../Hashtags/DiscoveryHashtagsViewModel.swift | 4 +- .../News/DiscoveryNewsViewController.swift | 9 +-- .../DiscoveryNewsViewModel+Diffable.swift | 1 - .../News/DiscoveryNewsViewModel.swift | 4 +- .../Posts/DiscoveryPostsViewController.swift | 4 +- .../DiscoveryPostsViewModel+Diffable.swift | 2 - .../Posts/DiscoveryPostsViewModel.swift | 4 +- .../Donation/NewDonationNavigationFlow.swift | 5 +- .../HashtagTimelineViewController.swift | 8 +-- .../HashtagTimelineViewModel+Diffable.swift | 2 - .../HashtagTimelineViewModel.swift | 4 +- .../HomeTimelineViewController.swift | 18 +++--- .../HomeTimelineViewModel+Diffable.swift | 2 - .../HomeTimeline/HomeTimelineViewModel.swift | 6 +- .../MediaPreviewViewController.swift | 13 ++--- ...ntNotificationTimelineViewController.swift | 12 ++-- ...ificationRequestsTableViewController.swift | 7 +-- .../NotificationRequestsViewModel.swift | 6 +- .../Notification/NotificationSection.swift | 5 -- .../NotificationTimelineViewController.swift | 12 +--- ...tificationTimelineViewModel+Diffable.swift | 1 - .../NotificationTimelineViewModel.swift | 5 +- .../NotificationViewController.swift | 12 +--- .../MastodonConfirmEmailViewController.swift | 13 ++--- .../PickServer/CategoryPickerSection.swift | 2 +- .../MastodonPickServerViewController.swift | 6 +- ...MastodonPickServerViewModel+Diffable.swift | 2 +- .../PickServer/PickServerSection.swift | 2 +- .../MastodonRegisterViewController.swift | 7 +-- .../MastodonResendEmailViewController.swift | 5 +- .../Welcome/WelcomeViewController.swift | 23 ++++---- .../Onboarding/Welcome/WelcomeViewModel.swift | 7 +-- .../About/ProfileAboutViewController.swift | 3 - .../Bookmark/BookmarkViewController.swift | 5 +- .../Bookmark/BookmarkViewModel+Diffable.swift | 2 - .../Profile/Bookmark/BookmarkViewModel.swift | 4 +- .../FamiliarFollowersViewController.swift | 9 +-- .../FamiliarFollowersViewModel.swift | 5 +- .../Favorite/FavoriteViewController.swift | 5 +- .../Favorite/FavoriteViewModel+Diffable.swift | 2 - .../Profile/Favorite/FavoriteViewModel.swift | 4 +- .../FollowedTagsViewController.swift | 11 +--- .../FollowedTags/FollowedTagsViewModel.swift | 4 +- .../Follower/FollowerListViewController.swift | 9 +-- .../FollowerListViewModel+Diffable.swift | 1 - .../Follower/FollowerListViewModel.swift | 3 - .../FollowingListViewController.swift | 9 +-- .../FollowingListViewModel+Diffable.swift | 1 - .../Following/FollowingListViewModel.swift | 3 - .../Header/ProfileHeaderViewController.swift | 17 ++---- .../Header/ProfileHeaderViewModel.swift | 4 +- .../Scene/Profile/ProfileViewController.swift | 48 +++++++--------- .../Timeline/UserTimelineViewController.swift | 5 +- .../UserTimelineViewModel+Diffable.swift | 2 - .../FavoritedByViewController.swift | 4 +- .../RebloggedByViewController.swift | 5 +- .../UserList/UserListViewModel+Diffable.swift | 1 - .../Report/Report/ReportViewController.swift | 23 +++----- .../ReportReasonViewController.swift | 5 +- .../ReportResultViewController.swift | 5 +- .../ReportResult/ReportResultViewModel.swift | 3 - .../ReportServerRulesViewController.swift | 5 +- .../ReportStatusViewController.swift | 5 +- .../ReportSupplementaryViewController.swift | 5 +- .../Root/ContentSplitViewController.swift | 15 ++--- .../Root/MainTab/MainTabBarController.swift | 45 +++++---------- .../Scene/Root/RootSplitViewController.swift | 16 +----- .../Root/Sidebar/SidebarViewController.swift | 11 ++-- .../Scene/Root/Sidebar/SidebarViewModel.swift | 4 +- .../Search/Search/SearchViewController.swift | 28 ++++------ .../Scene/Search/Search/SearchViewModel.swift | 4 +- .../SearchResultOverviewCoordinator.swift | 20 +++---- ...chResultsOverviewTableViewController.swift | 8 +-- .../SearchDetailViewController.swift | 19 ++----- .../SearchHistory/SearchHistorySection.swift | 1 - .../SearchHistoryViewController.swift | 5 +- .../SearchHistoryViewModel+Diffable.swift | 1 - .../SearchHistoryViewModel.swift | 4 +- .../SearchResult/SearchResultSection.swift | 5 -- .../SearchResultViewController.swift | 5 +- .../SearchResultViewModel+Diffable.swift | 1 - .../SearchResult/SearchResultViewModel.swift | 4 +- .../AboutInstanceViewController.swift | 9 +-- .../ServerDetailsViewController.swift | 2 +- .../Scene/Settings/SettingsCoordinator.swift | 4 +- .../UserTableViewCell+ViewModel.swift | 2 +- .../RecommendAccountSection.swift | 1 - .../SuggestionAccountViewController.swift | 7 +-- .../SuggestionAccountViewModel.swift | 8 +-- .../MastodonStatusThreadViewModel.swift | 4 +- .../Scene/Thread/RemoteThreadViewModel.swift | 4 -- .../Scene/Thread/ThreadViewController.swift | 8 +-- .../Thread/ThreadViewModel+Diffable.swift | 2 - Mastodon/Scene/Thread/ThreadViewModel.swift | 5 +- Mastodon/Supporting Files/SceneDelegate.swift | 19 ++++++- .../DataController/FeedDataController.swift | 4 +- .../CustomEmojiPickerSection+Diffable.swift | 6 +- .../AutoComplete/AutoCompleteViewModel.swift | 4 +- .../ComposeContentViewController.swift | 2 +- .../ComposeContentViewModel+DataSource.swift | 3 +- .../ComposeContentViewModel.swift | 3 - .../View/Content/StatusView+ViewModel.swift | 3 +- .../Scene/ShareViewController.swift | 1 - 142 files changed, 401 insertions(+), 757 deletions(-) delete mode 100644 Mastodon/Coordinator/NeedsDependency.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 65a245bde..73e5b7807 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -397,7 +397,6 @@ DB87D4452609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB87D4442609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift */; }; DB87D4512609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB87D4502609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift */; }; DB8AF54425C13647002E6C99 /* SceneCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF54225C13647002E6C99 /* SceneCoordinator.swift */; }; - DB8AF54525C13647002E6C99 /* NeedsDependency.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF54325C13647002E6C99 /* NeedsDependency.swift */; }; DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF54F25C13703002E6C99 /* MainTabBarController.swift */; }; DB8AF55D25C138B7002E6C99 /* UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF55C25C138B7002E6C99 /* UIViewController.swift */; }; DB8F7076279E954700E1225B /* DataSourceFacade+Follow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8F7075279E954700E1225B /* DataSourceFacade+Follow.swift */; }; @@ -1100,7 +1099,6 @@ DB87D4502609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusPollOptionAppendEntryCollectionViewCell.swift; sourceTree = ""; }; DB89BA1025C10FF5008580ED /* Mastodon.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Mastodon.entitlements; sourceTree = ""; }; DB8AF54225C13647002E6C99 /* SceneCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneCoordinator.swift; sourceTree = ""; }; - DB8AF54325C13647002E6C99 /* NeedsDependency.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NeedsDependency.swift; sourceTree = ""; }; DB8AF54F25C13703002E6C99 /* MainTabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainTabBarController.swift; sourceTree = ""; }; DB8AF55C25C138B7002E6C99 /* UIViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = ""; }; DB8D8E3128196FA0009FD90F /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Intents.strings; sourceTree = ""; }; @@ -2588,7 +2586,6 @@ isa = PBXGroup; children = ( DB8AF54225C13647002E6C99 /* SceneCoordinator.swift */, - DB8AF54325C13647002E6C99 /* NeedsDependency.swift */, D8F9170E2A4B47EF008A5370 /* Coordinator.swift */, ); path = Coordinator; @@ -3812,7 +3809,6 @@ 2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */, DBEFCD7B282A162400C0ABEA /* ReportReasonView.swift in Sources */, D8E5C346296DAB84007E76A7 /* DataSourceFacade+Status+History.swift in Sources */, - DB8AF54525C13647002E6C99 /* NeedsDependency.swift in Sources */, DB63F77B279ACAE500455B82 /* DataSourceFacade+Favorite.swift in Sources */, DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */, 2DAC9E46262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift in Sources */, diff --git a/Mastodon/Activity/SafariActivity.swift b/Mastodon/Activity/SafariActivity.swift index e20a9f815..f3660fc50 100644 --- a/Mastodon/Activity/SafariActivity.swift +++ b/Mastodon/Activity/SafariActivity.swift @@ -15,7 +15,7 @@ final class SafariActivity: UIActivity { weak var sceneCoordinator: SceneCoordinator? var url: NSURL? - init(sceneCoordinator: SceneCoordinator) { + init(sceneCoordinator: SceneCoordinator?) { self.sceneCoordinator = sceneCoordinator } diff --git a/Mastodon/Coordinator/NeedsDependency.swift b/Mastodon/Coordinator/NeedsDependency.swift deleted file mode 100644 index eb0589e58..000000000 --- a/Mastodon/Coordinator/NeedsDependency.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// NeedsDependency.swift -// Mastodon -// -// Created by Cirno MainasuK on 2021-1-27. -// - -import UIKit -import MastodonCore - -protocol NeedsDependency: AnyObject { - //FIXME: Get rid of ! ~@zeitschlag - var context: AppContext! { get set } - var coordinator: SceneCoordinator! { get set } -} - -typealias ViewControllerWithDependencies = NeedsDependency & UIViewController - - diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 38d7a5e6e..51be3f82d 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -17,11 +17,14 @@ import MBProgressHUD @MainActor final public class SceneCoordinator { + fileprivate static func coordinator(for view: UIView) -> SceneCoordinator? { + return SceneDelegate.delegate(for: view)?.coordinator + } + private var disposeBag = Set() private weak var scene: UIScene! private weak var sceneDelegate: SceneDelegate! - private(set) weak var appContext: AppContext! var authenticationBox: MastodonAuthenticationBox? { AuthenticationServiceProvider.shared.currentActiveUser.value @@ -45,7 +48,6 @@ final public class SceneCoordinator { ) { self.scene = scene self.sceneDelegate = sceneDelegate - self.appContext = appContext NotificationService.shared.requestRevealNotificationPublisher .receive(on: DispatchQueue.main) @@ -118,7 +120,6 @@ final public class SceneCoordinator { break case .mention, .reblog, .favourite, .poll, .status: let threadViewModel = RemoteThreadViewModel( - context: appContext, authenticationBox: authenticationBox, notificationID: notificationID ) @@ -250,17 +251,18 @@ extension SceneCoordinator { switch UIDevice.current.userInterfaceIdiom { case .phone: - let viewController = MainTabBarController(context: appContext, coordinator: self, authenticationBox: authenticationBox) + let viewController = MainTabBarController(authenticationBox: authenticationBox) self.splitViewController = nil self.tabBarController = viewController rootViewController = viewController default: - let splitViewController = RootSplitViewController(context: appContext, coordinator: self, authenticationBox: authenticationBox) + let splitViewController = RootSplitViewController(authenticationBox: authenticationBox) self.splitViewController = splitViewController self.tabBarController = splitViewController.contentSplitViewController.mainTabBarController rootViewController = splitViewController } + // this feels wrong sceneDelegate.window?.rootViewController = rootViewController // base: main self.rootViewController = rootViewController @@ -268,7 +270,7 @@ extension SceneCoordinator { DispatchQueue.main.async { _ = self.present( scene: .welcome, - from: self.sceneDelegate.window?.rootViewController, + from: rootViewController, // self.sceneDelegate.window?.rootViewController, transition: .modal(animated: true, completion: nil) ) } @@ -422,13 +424,11 @@ private extension SceneCoordinator { let _viewController = WebViewController(viewModel) viewController = _viewController case .searchDetail(let viewModel): - let _viewController = SearchDetailViewController(appContext: appContext, sceneCoordinator: self, authenticationBox: viewModel.authenticationBox) + let _viewController = SearchDetailViewController(authenticationBox: viewModel.authenticationBox) _viewController.viewModel = viewModel viewController = _viewController case .searchResult(let viewModel): let searchResultViewController = SearchResultViewController() - searchResultViewController.context = appContext - searchResultViewController.coordinator = self searchResultViewController.viewModel = viewModel viewController = searchResultViewController case .compose(let viewModel): @@ -460,19 +460,19 @@ private extension SceneCoordinator { case .followedTags(let viewModel): guard let authenticationBox else { return nil } - viewController = FollowedTagsViewController(appContext: appContext, sceneCoordinator: self, authenticationBox: authenticationBox, viewModel: viewModel) + viewController = FollowedTagsViewController(authenticationBox: authenticationBox, viewModel: viewModel) case .favorite(let viewModel): let _viewController = FavoriteViewController() _viewController.viewModel = viewModel viewController = _viewController case .follower(let viewModel): - let followerListViewController = FollowerListViewController(viewModel: viewModel, coordinator: self, context: appContext) + let followerListViewController = FollowerListViewController(viewModel: viewModel) viewController = followerListViewController case .following(let viewModel): - let followingListViewController = FollowingListViewController(viewModel: viewModel, coordinator: self, context: appContext) + let followingListViewController = FollowingListViewController(viewModel: viewModel) viewController = followingListViewController case .familiarFollowers(let viewModel): - viewController = FamiliarFollowersViewController(viewModel: viewModel, context: appContext, coordinator: self) + viewController = FamiliarFollowersViewController(viewModel: viewModel) case .rebloggedBy(let viewModel): let _viewController = RebloggedByViewController() _viewController.viewModel = viewModel @@ -539,7 +539,7 @@ private extension SceneCoordinator { let settingsCoordinator = SettingsCoordinator(presentedOn: presentedOn, accountName: accountName, setting: setting, - appContext: appContext, + appContext: AppContext.shared, authenticationBox: authenticationBox, sceneCoordinator: self ) @@ -557,18 +557,11 @@ private extension SceneCoordinator { case .notificationPolicy(let viewModel): viewController = NotificationPolicyViewController(viewModel: viewModel) case .accountNotificationTimeline(let viewModel, let request): - viewController = AccountNotificationTimelineViewController(viewModel: viewModel, context: appContext, coordinator: self, notificationRequest: request) + viewController = AccountNotificationTimelineViewController(viewModel: viewModel, notificationRequest: request) } - setupDependency(for: viewController as? NeedsDependency) - return viewController } - - private func setupDependency(for needs: NeedsDependency?) { - needs?.context = appContext - needs?.coordinator = self - } } //MARK: - Loading @@ -692,3 +685,10 @@ extension SceneCoordinator: SettingsCoordinatorDelegate { self.mastodonAuthenticationController = authenticationController } } + +public extension UIViewController { + var sceneCoordinator: SceneCoordinator? { + guard let view = viewIfLoaded else { assert(false); return nil } + return SceneCoordinator.coordinator(for: view) + } +} diff --git a/Mastodon/Diffable/Report/ReportSection.swift b/Mastodon/Diffable/Report/ReportSection.swift index 51abc0fdc..b2b553b1d 100644 --- a/Mastodon/Diffable/Report/ReportSection.swift +++ b/Mastodon/Diffable/Report/ReportSection.swift @@ -47,7 +47,6 @@ extension ReportSection { case .status(let status): let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ReportStatusTableViewCell.self), for: indexPath) as! ReportStatusTableViewCell configure( - context: context, tableView: tableView, cell: cell, viewModel: .init(value: status), @@ -83,19 +82,16 @@ extension ReportSection { extension ReportSection { static func configure( - context: AppContext, tableView: UITableView, cell: ReportStatusTableViewCell, viewModel: ReportStatusTableViewCell.ViewModel, configuration: Configuration ) { StatusSection.setupStatusPollDataSource( - context: context, authenticationBox: configuration.authenticationBox, statusView: cell.statusView ) - cell.statusView.viewModel.context = context cell.statusView.viewModel.authenticationBox = configuration.authenticationBox cell.configure( diff --git a/Mastodon/Diffable/Status/StatusSection.swift b/Mastodon/Diffable/Status/StatusSection.swift index 783fb4bfc..137613670 100644 --- a/Mastodon/Diffable/Status/StatusSection.swift +++ b/Mastodon/Diffable/Status/StatusSection.swift @@ -24,7 +24,6 @@ enum StatusSection: Equatable, Hashable { extension StatusSection { struct Configuration { - let context: AppContext let authenticationBox: MastodonAuthenticationBox weak var statusTableViewCellDelegate: StatusTableViewCellDelegate? weak var timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate? @@ -33,7 +32,6 @@ extension StatusSection { static func diffableDataSource( tableView: UITableView, - context: AppContext, configuration: Configuration ) -> UITableViewDiffableDataSource { tableView.register(StatusTableViewCell.self, forCellReuseIdentifier: String(describing: StatusTableViewCell.self)) @@ -48,7 +46,6 @@ extension StatusSection { let displayItem = StatusTableViewCell.StatusTableViewCellViewModel.DisplayItem.feed(feed) let contentConcealModel = StatusView.ContentConcealViewModel(status: feed.status, filterBox: StatusFilterService.shared.activeFilterBox, filterContext: configuration.filterContext) configure( - context: context, tableView: tableView, cell: cell, viewModel: StatusTableViewCell.StatusTableViewCellViewModel(displayItem: displayItem, contentConcealModel: contentConcealModel), @@ -68,7 +65,6 @@ extension StatusSection { let displayItem = StatusTableViewCell.StatusTableViewCellViewModel.DisplayItem.status(status) let contentConcealModel = StatusView.ContentConcealViewModel(status: status, filterBox: StatusFilterService.shared.activeFilterBox, filterContext: configuration.filterContext) configure( - context: context, tableView: tableView, cell: cell, viewModel: StatusTableViewCell.StatusTableViewCellViewModel(displayItem: displayItem, contentConcealModel: contentConcealModel), @@ -77,7 +73,6 @@ extension StatusSection { return cell case .thread(let thread): let cell = dequeueConfiguredReusableCell( - context: context, tableView: tableView, indexPath: indexPath, configuration: ThreadCellRegistrationConfiguration( @@ -108,7 +103,6 @@ extension StatusSection { } static func dequeueConfiguredReusableCell( - context: AppContext, tableView: UITableView, indexPath: IndexPath, configuration: ThreadCellRegistrationConfiguration @@ -118,7 +112,6 @@ extension StatusSection { let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: StatusThreadRootTableViewCell.self), for: indexPath) as! StatusThreadRootTableViewCell let contentConcealModel = StatusView.ContentConcealViewModel(status: threadContext.status, filterBox: StatusFilterService.shared.activeFilterBox, filterContext: .thread) StatusSection.configure( - context: context, tableView: tableView, cell: cell, viewModel: StatusTableViewCell.StatusTableViewCellViewModel(displayItem: .status(threadContext.status), contentConcealModel: contentConcealModel), @@ -132,9 +125,7 @@ extension StatusSection { let contentConcealModel = StatusView.ContentConcealViewModel(status: threadContext.status, filterBox: StatusFilterService.shared.activeFilterBox, filterContext: configuration.configuration.filterContext) assert(configuration.configuration.filterContext == .thread) StatusSection.configure( - context: context, - tableView: tableView, - cell: cell, + tableView: tableView, cell: cell, viewModel: StatusTableViewCell.StatusTableViewCellViewModel(displayItem: displayItem, contentConcealModel: contentConcealModel), configuration: configuration.configuration ) @@ -147,7 +138,6 @@ extension StatusSection { extension StatusSection { public static func setupStatusPollDataSource( - context: AppContext, authenticationBox: MastodonAuthenticationBox, statusView: StatusView ) { @@ -206,19 +196,16 @@ extension StatusSection { extension StatusSection { static func configure( - context: AppContext, tableView: UITableView, cell: StatusTableViewCell, viewModel: StatusTableViewCell.StatusTableViewCellViewModel, configuration: Configuration ) { setupStatusPollDataSource( - context: context, authenticationBox: configuration.authenticationBox, statusView: cell.statusView ) - cell.statusView.viewModel.context = configuration.context cell.statusView.viewModel.authenticationBox = configuration.authenticationBox cell.configure( @@ -229,19 +216,16 @@ extension StatusSection { } static func configure( - context: AppContext, tableView: UITableView, cell: StatusThreadRootTableViewCell, viewModel: StatusTableViewCell.StatusTableViewCellViewModel, configuration: Configuration ) { setupStatusPollDataSource( - context: context, authenticationBox: configuration.authenticationBox, statusView: cell.statusView ) - cell.statusView.viewModel.context = configuration.context cell.statusView.viewModel.authenticationBox = configuration.authenticationBox cell.configure( diff --git a/Mastodon/Diffable/User/UserSection.swift b/Mastodon/Diffable/User/UserSection.swift index 1c58feac0..ecaf2c4de 100644 --- a/Mastodon/Diffable/User/UserSection.swift +++ b/Mastodon/Diffable/User/UserSection.swift @@ -21,7 +21,6 @@ enum UserSection: Hashable { extension UserSection { static func diffableDataSource( tableView: UITableView, - context: AppContext, authenticationBox: MastodonAuthenticationBox, userTableViewCellDelegate: UserTableViewCellDelegate? ) -> UITableViewDiffableDataSource { diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Block.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Block.swift index 8abe707c9..8233db250 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Block.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Block.swift @@ -12,7 +12,7 @@ import MastodonSDK extension DataSourceFacade { static func responseToUserBlockAction( - dependency: NeedsDependency & AuthContextProvider, + dependency: AuthContextProvider, account: Mastodon.Entity.Account ) async throws -> Mastodon.Entity.Relationship { FeedbackGenerator.shared.generate(.selectionChanged) @@ -35,7 +35,7 @@ extension DataSourceFacade { } static func responseToDomainBlockAction( - dependency: NeedsDependency & AuthContextProvider, + dependency: AuthContextProvider, account: Mastodon.Entity.Account ) async throws -> Mastodon.Entity.Empty { FeedbackGenerator.shared.generate(.selectionChanged) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Bookmark.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Bookmark.swift index 00e525dba..2cdf52108 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Bookmark.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Bookmark.swift @@ -14,7 +14,7 @@ import MastodonSDK extension DataSourceFacade { @MainActor public static func responseToStatusBookmarkAction( - provider: NeedsDependency & AuthContextProvider & DataSourceProvider, + provider: AuthContextProvider & DataSourceProvider, status: MastodonStatus ) async throws { FeedbackGenerator.shared.generate(.selectionChanged) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Follow.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Follow.swift index e4e64df77..ea73d2b01 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Follow.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Follow.swift @@ -14,7 +14,7 @@ import MastodonLocalization extension DataSourceFacade { @MainActor static func responseToUserFollowAction( - dependency: ViewControllerWithDependencies & AuthContextProvider, + dependency: UIViewController & AuthContextProvider, account: Mastodon.Entity.Account ) async throws -> Mastodon.Entity.Relationship { let authBox = dependency.authenticationBox @@ -78,7 +78,7 @@ extension DataSourceFacade { extension DataSourceFacade { static func responseToUserFollowRequestAction( - dependency: NeedsDependency & AuthContextProvider, + dependency: UIViewController & AuthContextProvider, notification: MastodonNotification, notificationView: NotificationView, query: Mastodon.API.Account.FollowRequestQuery @@ -129,10 +129,11 @@ extension DataSourceFacade { case .notFound: break default: + guard let coordinator = await dependency.sceneCoordinator else { return } let alertController = await UIAlertController(for: error, title: nil, preferredStyle: .alert) let okAction = await UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) await alertController.addAction(okAction) - _ = await dependency.coordinator.present( + _ = await coordinator.present( scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil) @@ -146,7 +147,7 @@ extension DataSourceFacade { extension DataSourceFacade { static func responseToShowHideReblogAction( - dependency: NeedsDependency & AuthContextProvider, + dependency: AuthContextProvider, account: Mastodon.Entity.Account ) async throws { let newRelationship = try await APIService.shared.toggleShowReblogs( diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift index d5346af55..56694eb6f 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift @@ -13,16 +13,16 @@ import MastodonSDK extension DataSourceFacade { @MainActor static func coordinateToHashtagScene( - provider: ViewControllerWithDependencies & AuthContextProvider, + provider: UIViewController, tag: Mastodon.Entity.Tag ) async { + guard let authBox = AuthenticationServiceProvider.shared.currentActiveUser.value else { return } let hashtagTimelineViewModel = HashtagTimelineViewModel( - context: provider.context, - authenticationBox: provider.authenticationBox, + authenticationBox: authBox, hashtag: tag.name ) - - _ = provider.coordinator.present( + guard let coordinator = provider.sceneCoordinator else { return } + _ = coordinator.present( scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: provider, transition: .show diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Media.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Media.swift index 1cbc15b9d..c3b86675f 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Media.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Media.swift @@ -7,6 +7,7 @@ import UIKit import CoreDataStack +import MastodonCore import MastodonUI import MastodonLocalization import MastodonSDK @@ -15,16 +16,17 @@ extension DataSourceFacade { @MainActor static func coordinateToMediaPreviewScene( - dependency: NeedsDependency & MediaPreviewableViewController, + dependency: UIViewController & MediaPreviewableViewController, mediaPreviewItem: MediaPreviewViewModel.PreviewItem, mediaPreviewTransitionItem: MediaPreviewTransitionItem ) { let mediaPreviewViewModel = MediaPreviewViewModel( - context: dependency.context, + context: AppContext.shared, item: mediaPreviewItem, transitionItem: mediaPreviewTransitionItem ) - _ = dependency.coordinator.present( + guard let coordinator = dependency.sceneCoordinator else { return } + _ = coordinator.present( scene: .mediaPreview(viewModel: mediaPreviewViewModel), from: dependency, transition: .custom(transitioningDelegate: dependency.mediaPreviewTransitionController) @@ -61,7 +63,7 @@ extension DataSourceFacade { @MainActor static func coordinateToMediaPreviewScene( - dependency: NeedsDependency & MediaPreviewableViewController, + dependency: UIViewController & MediaPreviewableViewController, status: MastodonStatus, previewContext: AttachmentPreviewContext ) async throws { @@ -146,7 +148,7 @@ extension DataSourceFacade { @MainActor static func coordinateToMediaPreviewScene( - dependency: NeedsDependency & MediaPreviewableViewController, + dependency: MediaPreviewableViewController, account: Mastodon.Entity.Account, previewContext: ImagePreviewContext ) async throws { diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Meta.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Meta.swift index 588135635..377022bc4 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Meta.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Meta.swift @@ -53,8 +53,9 @@ extension DataSourceFacade { url: url ) case .hashtag(_, let hashtag, _): - let hashtagTimelineViewModel = await HashtagTimelineViewModel(context: provider.context, authenticationBox: provider.authenticationBox, hashtag: hashtag) - _ = await provider.coordinator.present(scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: provider, transition: .show) + let hashtagTimelineViewModel = await HashtagTimelineViewModel(authenticationBox: provider.authenticationBox, hashtag: hashtag) + guard let coordinator = await provider.sceneCoordinator else { return } + _ = await coordinator.present(scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: provider, transition: .show) case .mention(_, let mention, let userInfo): await coordinateToProfileScene( provider: provider, diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Mute.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Mute.swift index d82006556..012b238b5 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Mute.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Mute.swift @@ -11,7 +11,7 @@ import MastodonCore extension DataSourceFacade { static func responseToUserMuteAction( - dependency: NeedsDependency & AuthContextProvider, + dependency: AuthContextProvider, account: Mastodon.Entity.Account ) async throws -> Mastodon.Entity.Relationship { FeedbackGenerator.shared.generate(.selectionChanged) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Notifications.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Notifications.swift index 12cbd763c..920bd76db 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Notifications.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Notifications.swift @@ -3,19 +3,21 @@ import Foundation import MastodonCore import MastodonSDK +import UIKit extension DataSourceFacade { @MainActor static func coordinateToNotificationRequests( provider: DataSourceProvider & AuthContextProvider ) async { - provider.coordinator.showLoading() + guard let sceneCoordinator = provider.sceneCoordinator else { return } + sceneCoordinator.showLoading() do { let notificationRequests = try await APIService.shared.notificationRequests(authenticationBox: provider.authenticationBox).value - let viewModel = NotificationRequestsViewModel(appContext: provider.context, authenticationBox: provider.authenticationBox, coordinator: provider.coordinator, requests: notificationRequests) + let viewModel = NotificationRequestsViewModel(authenticationBox: provider.authenticationBox, requests: notificationRequests) - provider.coordinator.hideLoading() + sceneCoordinator.hideLoading() let transition: SceneCoordinator.Transition @@ -25,25 +27,26 @@ extension DataSourceFacade { transition = .modal(animated: true) } - provider.coordinator.present(scene: .notificationRequests(viewModel: viewModel), transition: transition) + sceneCoordinator.present(scene: .notificationRequests(viewModel: viewModel), transition: transition) } catch { //TODO: Error Handling - provider.coordinator.hideLoading() + sceneCoordinator.hideLoading() } } @MainActor static func coordinateToNotificationRequest( request: Mastodon.Entity.NotificationRequest, - provider: ViewControllerWithDependencies & AuthContextProvider + provider: UIViewController & AuthContextProvider ) async -> AccountNotificationTimelineViewController? { - provider.coordinator.showLoading() + guard let sceneCoordinator = provider.sceneCoordinator else { return nil } + sceneCoordinator.showLoading() - let notificationTimelineViewModel = NotificationTimelineViewModel(context: provider.context, authenticationBox: provider.authenticationBox, scope: .fromAccount(request.account)) + let notificationTimelineViewModel = NotificationTimelineViewModel(authenticationBox: provider.authenticationBox, scope: .fromAccount(request.account)) - provider.coordinator.hideLoading() + sceneCoordinator.hideLoading() - guard let viewController = provider.coordinator.present(scene: .accountNotificationTimeline(viewModel: notificationTimelineViewModel, request: request), transition: .show) as? AccountNotificationTimelineViewController else { return nil } + guard let viewController = sceneCoordinator.present(scene: .accountNotificationTimeline(viewModel: notificationTimelineViewModel, request: request), transition: .show) as? AccountNotificationTimelineViewController else { return nil } return viewController diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift index d61e8af7e..2060d6893 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift @@ -26,7 +26,9 @@ extension DataSourceFacade { acct = status.entity.account.acct } - provider.coordinator.showLoading() + guard let coordinator = provider.sceneCoordinator else { return } + + coordinator.showLoading() let _redirectRecord = try? await Mastodon.API.Account.lookupAccount( session: .shared, @@ -35,7 +37,7 @@ extension DataSourceFacade { authorization: provider.authenticationBox.userAuthorization ).singleOutput().value - provider.coordinator.hideLoading() + coordinator.hideLoading() guard let redirectRecord = _redirectRecord else { assertionFailure() @@ -50,11 +52,13 @@ extension DataSourceFacade { @MainActor static func coordinateToProfileScene( - provider: ViewControllerWithDependencies & AuthContextProvider, + provider: UIViewController & AuthContextProvider, username: String, domain: String ) async { - provider.coordinator.showLoading() + guard let coordinator = provider.sceneCoordinator else { return } + + coordinator.showLoading() do { guard let account = try await APIService.shared.fetchUser( @@ -62,24 +66,26 @@ extension DataSourceFacade { domain: domain, authenticationBox: provider.authenticationBox ) else { - return provider.coordinator.hideLoading() + return coordinator.hideLoading() } - provider.coordinator.hideLoading() + coordinator.hideLoading() await coordinateToProfileScene(provider: provider, account: account) } catch { - provider.coordinator.hideLoading() + coordinator.hideLoading() } } @MainActor static func coordinateToProfileScene( - provider: ViewControllerWithDependencies & AuthContextProvider, + provider: UIViewController & AuthContextProvider, domain: String, accountID: String ) async { - provider.coordinator.showLoading() + guard let coordinator = provider.sceneCoordinator else { return } + + coordinator.showLoading() do { let account = try await APIService.shared.accountInfo( @@ -89,37 +95,40 @@ extension DataSourceFacade { authorization: provider.authenticationBox.userAuthorization ) - provider.coordinator.hideLoading() + coordinator.hideLoading() await coordinateToProfileScene(provider: provider, account: account) } catch { - provider.coordinator.hideLoading() + coordinator.hideLoading() } } @MainActor public static func coordinateToProfileScene( - provider: ViewControllerWithDependencies & AuthContextProvider, + provider: UIViewController & AuthContextProvider, account: Mastodon.Entity.Account ) async { - provider.coordinator.showLoading() + + guard let coordinator = provider.sceneCoordinator else { return } + + coordinator.showLoading() guard let me = provider.authenticationBox.cachedAccount, let relationship = try? await APIService.shared.relationship(forAccounts: [account], authenticationBox: provider.authenticationBox).value.first else { - return provider.coordinator.hideLoading() + return coordinator.hideLoading() } - provider.coordinator.hideLoading() + coordinator.hideLoading() let profileViewModel = ProfileViewModel( - context: provider.context, + context: AppContext.shared, authenticationBox: provider.authenticationBox, account: account, relationship: relationship, me: me ) - _ = provider.coordinator.present( + _ = coordinator.present( scene: .profile(viewModel: profileViewModel), from: provider, transition: .show @@ -146,13 +155,13 @@ extension DataSourceFacade { } let mentions = status.entity.mentions + guard let coordinator = provider.sceneCoordinator else { return } guard let mention = mentions.first(where: { $0.url == href }) else { - _ = provider.coordinator.present( + _ = coordinator.present( scene: .safari(url: url), from: provider, transition: .safariPresent(animated: true, completion: nil) ) - return } @@ -163,21 +172,21 @@ extension DataSourceFacade { extension DataSourceFacade { static func createActivityViewController( - dependency: NeedsDependency, + dependency: UIViewController, account: Mastodon.Entity.Account ) -> UIActivityViewController { let activityViewController = UIActivityViewController( activityItems: [account.url], - applicationActivities: [SafariActivity(sceneCoordinator: dependency.coordinator)] + applicationActivities: [SafariActivity(sceneCoordinator: dependency.sceneCoordinator)] ) return activityViewController } - static func createActivityViewControllerForMastodonUser(status: Status, dependency: NeedsDependency) -> UIActivityViewController { + static func createActivityViewControllerForMastodonUser(status: Status, dependency: UIViewController) -> UIActivityViewController { let activityViewController = UIActivityViewController( activityItems: status.activityItems, - applicationActivities: [SafariActivity(sceneCoordinator: dependency.coordinator)] + applicationActivities: [SafariActivity(sceneCoordinator: dependency.sceneCoordinator)] ) return activityViewController } diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift b/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift index 0b1ad53ec..5316db5a6 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift @@ -13,7 +13,7 @@ import UIKit extension DataSourceFacade { static func responseToCreateSearchHistory( - provider: ViewControllerWithDependencies & AuthContextProvider, + provider: UIViewController & AuthContextProvider, item: DataSourceItem ) async { switch item { diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status+History.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status+History.swift index f7f1aaaf7..7223c38d3 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status+History.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status+History.swift @@ -8,7 +8,7 @@ import CoreDataStack extension DataSourceFacade { public static func getEditHistory( forStatus status: Status, - provider: NeedsDependency & AuthContextProvider + provider: AuthContextProvider ) async throws -> [Mastodon.Entity.StatusEdit] { let reponse = try await APIService.shared.getHistory(forStatusID: status.id, authenticationBox: provider.authenticationBox) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index d4d23bc6f..b3cf265db 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -20,7 +20,7 @@ import MastodonSDK extension DataSourceFacade { static func responseToDeleteStatus( - dependency: NeedsDependency & AuthContextProvider & DataSourceProvider, + dependency: AuthContextProvider & DataSourceProvider, status: MastodonStatus ) async throws { let deletedStatus = try await APIService.shared.deleteStatus( @@ -46,7 +46,8 @@ extension DataSourceFacade { dependency: provider, status: status ) - _ = provider.coordinator.present( + guard let coordinator = provider.sceneCoordinator else { /* TODO: throw? */ return } + _ = coordinator.present( scene: .activityViewController( activityViewController: activityViewController, sourceView: button, @@ -58,7 +59,7 @@ extension DataSourceFacade { } private static func createActivityViewController( - dependency: NeedsDependency, + dependency: UIViewController, status: MastodonStatus ) async throws -> UIActivityViewController { var activityItems: [Any] = { @@ -68,8 +69,8 @@ extension DataSourceFacade { ] }() - var applicationActivities: [UIActivity] = [ - SafariActivity(sceneCoordinator: dependency.coordinator), // open URL + var applicationActivities: [UIActivity] = await [ + SafariActivity(sceneCoordinator: dependency.sceneCoordinator), // open URL ] if let provider = dependency as? ShareActivityProvider { @@ -95,18 +96,19 @@ extension DataSourceFacade { sender: UIButton ) async throws { let _status = status.reblog ?? status + + guard let coordinator = provider.sceneCoordinator else { return } switch action { case .reply: FeedbackGenerator.shared.generate(.selectionChanged) let composeViewModel = ComposeViewModel( - context: provider.context, authenticationBox: provider.authenticationBox, composeContext: .composeStatus, destination: .reply(parent: _status) ) - _ = provider.coordinator.present( + _ = coordinator.present( scene: .compose(viewModel: composeViewModel), from: provider, transition: .modal(animated: true, completion: nil) @@ -144,7 +146,7 @@ extension DataSourceFacade { @MainActor static func responseToMenuAction( - dependency: UIViewController & NeedsDependency & AuthContextProvider & DataSourceProvider, + dependency: AuthContextProvider & DataSourceProvider, action: MastodonMenu.Action, menuContext: MenuContext, completion: ((T) -> Void)? = { (param: Void) in } @@ -237,7 +239,7 @@ extension DataSourceFacade { guard let relationship = try? await APIService.shared.relationship(forAccounts: [menuContext.author], authenticationBox: dependency.authenticationBox).value.first else { return } let reportViewModel = ReportViewModel( - context: dependency.context, + context: AppContext.shared, authenticationBox: dependency.authenticationBox, account: menuContext.author, relationship: relationship, @@ -245,7 +247,8 @@ extension DataSourceFacade { contentDisplayMode: .neverConceal ) - _ = dependency.coordinator.present( + guard let coordinator = dependency.sceneCoordinator else { return } + _ = coordinator.present( scene: .report(viewModel: reportViewModel), from: dependency, transition: .modal(animated: true, completion: nil) @@ -256,7 +259,8 @@ extension DataSourceFacade { account: menuContext.author ) - _ = dependency.coordinator.present( + guard let coordinator = dependency.sceneCoordinator else { return } + _ = coordinator.present( scene: .activityViewController( activityViewController: activityViewController, sourceView: menuContext.button, @@ -284,8 +288,8 @@ extension DataSourceFacade { dependency: dependency, status: status ) - - _ = dependency.coordinator.present( + guard let coordinator = dependency.sceneCoordinator else { return } + _ = coordinator.present( scene: .activityViewController( activityViewController: activityViewController, sourceView: menuContext.button, @@ -321,7 +325,7 @@ extension DataSourceFacade { guard let status = menuContext.statusViewModel?.originalStatus?.reblog ?? menuContext.statusViewModel?.originalStatus else { return } do { - let translation = try await DataSourceFacade.translateStatus(provider: dependency,status: status) + let translation = try await DataSourceFacade.translateStatus(provider: dependency, status: status) menuContext.statusViewModel?.translation = translation } catch TranslationFailure.emptyOrInvalidResponse { @@ -340,11 +344,11 @@ extension DataSourceFacade { ).value let editStatusViewModel = ComposeViewModel( - context: dependency.coordinator.appContext, authenticationBox: dependency.authenticationBox, composeContext: .editStatus(status: status, statusSource: statusSource), destination: .topLevel) - _ = dependency.coordinator.present(scene: .editStatus(viewModel: editStatusViewModel), transition: .modal(animated: true)) + guard let coordinator = dependency.sceneCoordinator else { return } + _ = coordinator.present(scene: .editStatus(viewModel: editStatusViewModel), transition: .modal(animated: true)) case .showOriginal: // do nothing, as the translation is reverted in `StatusTableViewCellDelegate` in `DataSourceProvider+StatusTableViewCellDelegate.swift`. @@ -416,14 +420,13 @@ extension DataSourceFacade { assertionFailure() return } - - dependency.coordinator.present(scene: .safari(url: url), transition: .safariPresent(animated: true)) + guard let coordinator = dependency.sceneCoordinator else { return } + coordinator.present(scene: .safari(url: url), transition: .safariPresent(animated: true)) case .copyProfileLink(let url): UIPasteboard.general.string = url?.absoluteString case .openUserInBrowser(let url): - guard let url else { return } - - dependency.coordinator.present(scene: .safari(url: url), transition: .safariPresent(animated: true)) + guard let url, let coordinator = dependency.sceneCoordinator else { return } + coordinator.present(scene: .safari(url: url), transition: .safariPresent(animated: true)) } } } @@ -431,7 +434,7 @@ extension DataSourceFacade { extension DataSourceFacade { @MainActor static func responseToToggleSensitiveAction( - dependency: NeedsDependency & DataSourceProvider, + dependency: DataSourceProvider, status: MastodonStatus ) async throws { let _status = status.reblog ?? status @@ -443,7 +446,7 @@ extension DataSourceFacade { } private extension DataSourceFacade { - static func performDeletion(of status: MastodonStatus, with dependency: NeedsDependency & AuthContextProvider & DataSourceProvider) { + static func performDeletion(of status: MastodonStatus, with dependency: AuthContextProvider & DataSourceProvider) { Task { try await DataSourceFacade.responseToDeleteStatus( dependency: dependency, diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift index 9f44821ea..151cc16aa 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift @@ -13,7 +13,7 @@ import MastodonSDK extension DataSourceFacade { static func coordinateToStatusThreadScene( - provider: ViewControllerWithDependencies & AuthContextProvider, + provider: UIViewController, target: StatusTarget, status: MastodonStatus ) async { @@ -39,15 +39,16 @@ extension DataSourceFacade { @MainActor static func coordinateToStatusThreadScene( - provider: ViewControllerWithDependencies & AuthContextProvider, + provider: UIViewController, root: StatusItem.Thread ) async { + guard let authBox = AuthenticationServiceProvider.shared.currentActiveUser.value else { return } let threadViewModel = ThreadViewModel( - context: provider.context, - authenticationBox: provider.authenticationBox, + authenticationBox: authBox, optionalRoot: root ) - _ = provider.coordinator.present( + guard let coordinator = provider.sceneCoordinator else { return } + _ = coordinator.present( scene: .thread(viewModel: threadViewModel), from: provider, transition: .show diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift index ff5246cd7..1e36594e5 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Translate.swift @@ -11,15 +11,13 @@ import CoreDataStack import MastodonCore import MastodonSDK -typealias Provider = UIViewController & NeedsDependency & AuthContextProvider - extension DataSourceFacade { enum TranslationFailure: Error { case emptyOrInvalidResponse } public static func translateStatus( - provider: Provider, + provider: AuthContextProvider, status: MastodonStatus ) async throws -> Mastodon.Entity.Translation { FeedbackGenerator.shared.generate(.selectionChanged) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+URL.swift b/Mastodon/Protocol/Provider/DataSourceFacade+URL.swift index b48abdba0..60e1a40fe 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+URL.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+URL.swift @@ -16,6 +16,7 @@ extension DataSourceFacade { provider: DataSourceProvider & AuthContextProvider, url: URL ) async { + guard let coordinator = await provider.sceneCoordinator else { return } let domain = provider.authenticationBox.domain if url.host == domain, url.pathComponents.count >= 4, @@ -23,10 +24,10 @@ extension DataSourceFacade { url.pathComponents[1] == "web", url.pathComponents[2] == "statuses" { let statusID = url.pathComponents[3] - let threadViewModel = await RemoteThreadViewModel(context: provider.context, authenticationBox: provider.authenticationBox, statusID: statusID) - _ = await provider.coordinator.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show) + let threadViewModel = await RemoteThreadViewModel(authenticationBox: provider.authenticationBox, statusID: statusID) + _ = await coordinator.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show) } else { - _ = await provider.coordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil)) + _ = await coordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil)) } } } diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+UserView.swift b/Mastodon/Protocol/Provider/DataSourceFacade+UserView.swift index f9edfd57e..a19e36f1d 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+UserView.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+UserView.swift @@ -5,10 +5,11 @@ import MastodonUI import CoreDataStack import MastodonCore import MastodonSDK +import UIKit extension DataSourceFacade { static func responseToUserViewButtonAction( - dependency: ViewControllerWithDependencies & AuthContextProvider, + dependency: UIViewController & AuthContextProvider, account: Mastodon.Entity.Account, buttonState: UserView.ButtonState ) async throws { diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift index f6b39b6d3..2c9bb0e88 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift @@ -184,7 +184,7 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte ], applicationActivities: [] ) - self.coordinator.present( + self.sceneCoordinator?.present( scene: .activityViewController( activityViewController: activityViewController, sourceView: statusCardControl, barButtonItem: nil @@ -200,9 +200,8 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte image: UIImage(systemName: "square.and.pencil") ) { DispatchQueue.main.async { - self.coordinator.present( + self.sceneCoordinator?.present( scene: .compose(viewModel: ComposeViewModel( - context: self.context, authenticationBox: self.authenticationBox, composeContext: .composeStatus, destination: .topLevel, @@ -534,12 +533,12 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte assertionFailure("only works for status data provider") return } - let userListViewModel = UserListViewModel( - context: context, + let userListViewModel = await UserListViewModel( + context: AppContext.shared, authenticationBox: authenticationBox, kind: .rebloggedBy(status: status) ) - _ = await coordinator.present( + _ = await self.sceneCoordinator?.present( scene: .rebloggedBy(viewModel: userListViewModel), from: self, transition: .show @@ -558,12 +557,12 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte assertionFailure("only works for status data provider") return } - let userListViewModel = UserListViewModel( - context: context, + let userListViewModel = await UserListViewModel( + context: AppContext.shared, authenticationBox: authenticationBox, kind: .favoritedBy(status: status) ) - _ = await coordinator.present( + _ = await self.sceneCoordinator?.present( scene: .favoritedBy(viewModel: userListViewModel), from: self, transition: .show @@ -574,7 +573,7 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, showEditHistory button: UIButton) { Task { - await coordinator.showLoading() + await self.sceneCoordinator?.showLoading() let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) guard let item = await self.item(from: source), @@ -586,12 +585,12 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte do { let edits = try await APIService.shared.getHistory(forStatusID: status.id, authenticationBox: authenticationBox).value - await coordinator.hideLoading() + await self.sceneCoordinator?.hideLoading() - let viewModel = StatusEditHistoryViewModel(status: status, edits: edits, appContext: context, authenticationBox: authenticationBox) - _ = await coordinator.present(scene: .editHistory(viewModel: viewModel), from: self, transition: .show) + let viewModel = await StatusEditHistoryViewModel(status: status, edits: edits, appContext: AppContext.shared, authenticationBox: authenticationBox) + _ = await self.sceneCoordinator?.present(scene: .editHistory(viewModel: viewModel), from: self, transition: .show) } catch { - await coordinator.hideLoading() + await self.sceneCoordinator?.hideLoading() } } } diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift index 219a7cff0..60ed0e6e3 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift @@ -88,12 +88,11 @@ extension StatusTableViewControllerNavigateableCore where Self: DataSourceProvid FeedbackGenerator.shared.generate(.selectionChanged) let composeViewModel = ComposeViewModel( - context: self.context, authenticationBox: authenticationBox, composeContext: .composeStatus, destination: .reply(parent: status) ) - _ = self.coordinator.present( + _ = self.sceneCoordinator?.present( scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil) diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift index 6b1e928c5..53085f0c3 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift @@ -45,12 +45,11 @@ extension UITableViewDelegate where Self: DataSourceProvider & AuthContextProvid ) } else if let accountWarning = notification.entity.accountWarning { let url = Mastodon.API.disputesEndpoint(domain: authenticationBox.domain, strikeId: accountWarning.id) - _ = coordinator.present( + self.sceneCoordinator?.present( scene: .safari(url: url), from: self, transition: .safariPresent(animated: true, completion: nil) ) - } else { await DataSourceFacade.coordinateToProfileScene( provider: self, @@ -135,7 +134,7 @@ extension UITableViewDelegate where Self: DataSourceProvider & MediaPreviewableV title: L10n.Common.Alerts.SavePhotoFailure.title, message: L10n.Common.Alerts.SavePhotoFailure.message ) - _ = self.coordinator.present( + self.sceneCoordinator?.present( scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil) @@ -166,10 +165,10 @@ extension UITableViewDelegate where Self: DataSourceProvider & MediaPreviewableV attributes: [], state: .off ) { [weak self] _ in - guard let self = self else { return } + guard let self = self, let coordinator = self.sceneCoordinator else { return } Task { let applicationActivities: [UIActivity] = [ - SafariActivity(sceneCoordinator: self.coordinator) + SafariActivity(sceneCoordinator: coordinator) ] let activityViewController = UIActivityViewController( activityItems: [assetURL], diff --git a/Mastodon/Protocol/Provider/DataSourceProvider.swift b/Mastodon/Protocol/Provider/DataSourceProvider.swift index 13dd841dd..10e33f6be 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider.swift @@ -36,7 +36,7 @@ extension DataSourceItem { } } -protocol DataSourceProvider: ViewControllerWithDependencies { +protocol DataSourceProvider: UIViewController { func item(from source: DataSourceItem.Source) async -> DataSourceItem? func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) diff --git a/Mastodon/Scene/Account/AccountListViewModel.swift b/Mastodon/Scene/Account/AccountListViewModel.swift index 45fef2dee..6943ad489 100644 --- a/Mastodon/Scene/Account/AccountListViewModel.swift +++ b/Mastodon/Scene/Account/AccountListViewModel.swift @@ -20,7 +20,6 @@ final class AccountListViewModel: NSObject { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox // output @@ -28,8 +27,7 @@ final class AccountListViewModel: NSObject { var diffableDataSource: UITableViewDiffableDataSource! - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox super.init() diff --git a/Mastodon/Scene/Account/AccountViewController.swift b/Mastodon/Scene/Account/AccountViewController.swift index 710234f5a..13b033ef1 100644 --- a/Mastodon/Scene/Account/AccountViewController.swift +++ b/Mastodon/Scene/Account/AccountViewController.swift @@ -12,10 +12,7 @@ import MastodonAsset import MastodonLocalization import MastodonCore -final class AccountListViewController: UIViewController, NeedsDependency { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class AccountListViewController: UIViewController { var disposeBag = Set() var viewModel: AccountListViewModel! @@ -83,7 +80,7 @@ extension AccountListViewController { extension AccountListViewController { @objc private func addBarButtonItem(_ sender: UIBarButtonItem) { - _ = coordinator.present(scene: .welcome, from: self, transition: .modal(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .welcome, from: self, transition: .modal(animated: true, completion: nil)) } override func accessibilityPerformEscape() -> Bool { @@ -115,7 +112,7 @@ extension AccountListViewController: UITableViewDelegate { FileManager.default.invalidateHomeTimelineCache(for: userIdentifier) FileManager.default.invalidateNotificationsAll(for: userIdentifier) FileManager.default.invalidateNotificationsMentions(for: userIdentifier) - self.coordinator.setup() + self.sceneCoordinator?.setup() } catch { assertionFailure("Failed to delete Authentication: \(error)") @@ -146,23 +143,23 @@ extension AccountListViewController: UITableViewDelegate { Task { @MainActor in let isActive = AuthenticationServiceProvider.shared.activateExistingUser(record.userID, inDomain: record.domain) guard isActive else { return } - self.coordinator.setup() + self.sceneCoordinator?.setup() } // end Task case .addAccount: // TODO: add dismiss entry for welcome scene - _ = coordinator.present(scene: .welcome, from: self, transition: .modal(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .welcome, from: self, transition: .modal(animated: true, completion: nil)) case .logoutOfAllAccounts: let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) let logoutAction = UIAlertAction(title: L10n.Scene.AccountList.logoutAllAccounts, style: .destructive) { _ in Task { @MainActor in - self.coordinator.showLoading() + self.sceneCoordinator?.showLoading() for authenticationBox in AuthenticationServiceProvider.shared.mastodonAuthenticationBoxes { try? await AuthenticationServiceProvider.shared.signOutMastodonUser(authentication: authenticationBox.authentication) } - self.coordinator.hideLoading() + self.sceneCoordinator?.hideLoading() - self.coordinator.setup() + self.sceneCoordinator?.setup() } } diff --git a/Mastodon/Scene/Compose/ComposeViewController.swift b/Mastodon/Scene/Compose/ComposeViewController.swift index 51d62b6ef..7e12c7207 100644 --- a/Mastodon/Scene/Compose/ComposeViewController.swift +++ b/Mastodon/Scene/Compose/ComposeViewController.swift @@ -17,11 +17,8 @@ import MastodonUI import MastodonLocalization import MastodonSDK -final class ComposeViewController: UIViewController, NeedsDependency { +final class ComposeViewController: UIViewController { static let minAutoCompleteVisibleHeight: CGFloat = 100 - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } var disposeBag = Set() var viewModel: ComposeViewModel @@ -48,7 +45,6 @@ final class ComposeViewController: UIViewController, NeedsDependency { } return ComposeContentViewModel( - context: context, authenticationBox: viewModel.authenticationBox, composeContext: composeContext, destination: viewModel.destination, @@ -217,7 +213,7 @@ extension ComposeViewController { let alertController = UIAlertController(for: error, title: nil, preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) alertController.addAction(okAction) - _ = coordinator.present(scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil)) return } @@ -235,7 +231,7 @@ extension ComposeViewController { self?.enqueuePublishStatus() } alertController.addAction(confirmAction) - _ = coordinator.present(scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil)) return } @@ -266,7 +262,7 @@ extension ComposeViewController { let alertController = UIAlertController(for: error, title: nil, preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) alertController.addAction(okAction) - _ = coordinator.present(scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil)) return } @@ -284,7 +280,7 @@ extension ComposeViewController { self?.enqueuePublishStatusEdit() } alertController.addAction(confirmAction) - _ = coordinator.present(scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil)) return } diff --git a/Mastodon/Scene/Compose/ComposeViewModel.swift b/Mastodon/Scene/Compose/ComposeViewModel.swift index 5c85feb28..6abca4f2a 100644 --- a/Mastodon/Scene/Compose/ComposeViewModel.swift +++ b/Mastodon/Scene/Compose/ComposeViewModel.swift @@ -29,7 +29,6 @@ final class ComposeViewModel { let id = UUID() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let composeContext: Context let destination: ComposeContentViewModel.Destination @@ -43,13 +42,11 @@ final class ComposeViewModel { @Published var title: String init( - context: AppContext, authenticationBox: MastodonAuthenticationBox, composeContext: ComposeViewModel.Context, destination: ComposeContentViewModel.Destination, initialContent: String = "" ) { - self.context = context self.authenticationBox = authenticationBox self.destination = destination self.initialContent = initialContent diff --git a/Mastodon/Scene/Discovery/DiscoverySection.swift b/Mastodon/Scene/Discovery/DiscoverySection.swift index b5c876f8f..db56e22b3 100644 --- a/Mastodon/Scene/Discovery/DiscoverySection.swift +++ b/Mastodon/Scene/Discovery/DiscoverySection.swift @@ -37,7 +37,6 @@ extension DiscoverySection { static func diffableDataSource( tableView: UITableView, - context: AppContext, configuration: Configuration ) -> UITableViewDiffableDataSource { diff --git a/Mastodon/Scene/Discovery/DiscoveryViewController.swift b/Mastodon/Scene/Discovery/DiscoveryViewController.swift index b74cc250b..3bf505659 100644 --- a/Mastodon/Scene/Discovery/DiscoveryViewController.swift +++ b/Mastodon/Scene/Discovery/DiscoveryViewController.swift @@ -12,15 +12,12 @@ import MastodonAsset import MastodonCore import MastodonUI -public class DiscoveryViewController: PageboyViewController, NeedsDependency { +public class DiscoveryViewController: PageboyViewController { public static let containerViewMarginForRegularHorizontalSizeClass: CGFloat = 64 public static let containerViewMarginForCompactHorizontalSizeClass: CGFloat = 16 var disposeBag = Set() - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } var viewModel: DiscoveryViewModel! diff --git a/Mastodon/Scene/Discovery/DiscoveryViewModel.swift b/Mastodon/Scene/Discovery/DiscoveryViewModel.swift index 0925af8c3..b4b0f050d 100644 --- a/Mastodon/Scene/Discovery/DiscoveryViewModel.swift +++ b/Mastodon/Scene/Discovery/DiscoveryViewModel.swift @@ -16,7 +16,6 @@ final class DiscoveryViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let discoveryPostsViewController: DiscoveryPostsViewController let discoveryHashtagsViewController: DiscoveryHashtagsViewController @@ -26,37 +25,27 @@ final class DiscoveryViewModel { @Published var viewControllers: [ScrollViewContainer] @MainActor - init(context: AppContext, coordinator: SceneCoordinator, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox - func setupDependency(_ needsDependency: NeedsDependency) { - needsDependency.context = context - needsDependency.coordinator = coordinator - } - discoveryPostsViewController = { let viewController = DiscoveryPostsViewController() - setupDependency(viewController) - viewController.viewModel = DiscoveryPostsViewModel(context: context, authenticationBox: authenticationBox) + viewController.viewModel = DiscoveryPostsViewModel(authenticationBox: authenticationBox) return viewController }() discoveryHashtagsViewController = { let viewController = DiscoveryHashtagsViewController() - setupDependency(viewController) - viewController.viewModel = DiscoveryHashtagsViewModel(context: context, authenticationBox: authenticationBox) + viewController.viewModel = DiscoveryHashtagsViewModel(authenticationBox: authenticationBox) return viewController }() discoveryNewsViewController = { let viewController = DiscoveryNewsViewController() - setupDependency(viewController) - viewController.viewModel = DiscoveryNewsViewModel(context: context, authenticationBox: authenticationBox) + viewController.viewModel = DiscoveryNewsViewModel(authenticationBox: authenticationBox) return viewController }() discoveryForYouViewController = { let viewController = DiscoveryForYouViewController() - setupDependency(viewController) - viewController.viewModel = DiscoveryForYouViewModel(context: context, authenticationBox: authenticationBox) + viewController.viewModel = DiscoveryForYouViewModel(authenticationBox: authenticationBox) return viewController }() self.viewControllers = [ diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift index 38052a6cf..91959ad02 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift @@ -11,10 +11,7 @@ import MastodonUI import MastodonCore import MastodonSDK -final class DiscoveryForYouViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class DiscoveryForYouViewController: UIViewController, MediaPreviewableViewController { var disposeBag = Set() var viewModel: DiscoveryForYouViewModel! @@ -137,7 +134,7 @@ extension DiscoveryForYouViewController: ProfileCardTableViewCellDelegate { guard let indexPath = tableView.indexPath(for: cell) else { return } guard case let .account(account, _) = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { return } - coordinator.showLoading() + self.sceneCoordinator?.showLoading() Task { [weak self] in @@ -147,16 +144,15 @@ extension DiscoveryForYouViewController: ProfileCardTableViewCellDelegate { let familiarFollowers = viewModel.familiarFollowers.first(where: { $0.id == userID })?.accounts ?? [] let relationships = try await APIService.shared.relationship(forAccounts: familiarFollowers, authenticationBox: authenticationBox).value - coordinator.hideLoading() + self.sceneCoordinator?.hideLoading() let familiarFollowersViewModel = FamiliarFollowersViewModel( - context: context, authenticationBox: authenticationBox, accounts: familiarFollowers, relationships: relationships ) - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .familiarFollowers(viewModel: familiarFollowersViewModel), from: self, transition: .show diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift index d2e20748e..1f2fe3599 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift @@ -17,7 +17,6 @@ extension DiscoveryForYouViewModel { ) { diffableDataSource = DiscoverySection.diffableDataSource( tableView: tableView, - context: context, configuration: DiscoverySection.Configuration( authenticationBox: authenticationBox, profileCardTableViewCellDelegate: profileCardTableViewCellDelegate, diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift index d46f60a38..1bc55ae37 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift @@ -16,7 +16,6 @@ final class DiscoveryForYouViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox @MainActor @@ -29,8 +28,7 @@ final class DiscoveryForYouViewModel { var diffableDataSource: UITableViewDiffableDataSource? let didLoadLatest = PassthroughSubject() - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox self.accounts = [] self.relationships = [] diff --git a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift index ad630c3f3..2907c2e69 100644 --- a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift +++ b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift @@ -10,10 +10,7 @@ import Combine import MastodonCore import MastodonUI -final class DiscoveryHashtagsViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class DiscoveryHashtagsViewController: UIViewController, MediaPreviewableViewController { var disposeBag = Set() var viewModel: DiscoveryHashtagsViewModel! @@ -88,8 +85,8 @@ extension DiscoveryHashtagsViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { guard case let .hashtag(tag) = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { return } - let hashtagTimelineViewModel = HashtagTimelineViewModel(context: context, authenticationBox: viewModel.authenticationBox, hashtag: tag.name) - _ = coordinator.present( + let hashtagTimelineViewModel = HashtagTimelineViewModel(authenticationBox: viewModel.authenticationBox, hashtag: tag.name) + _ = self.sceneCoordinator?.present( scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: self, transition: .show @@ -198,8 +195,8 @@ extension DiscoveryHashtagsViewController: TableViewControllerNavigateable { guard let item = diffableDataSource.itemIdentifier(for: indexPathForSelectedRow) else { return } guard case let .hashtag(tag) = item else { return } - let hashtagTimelineViewModel = HashtagTimelineViewModel(context: context, authenticationBox: viewModel.authenticationBox, hashtag: tag.name) - _ = coordinator.present( + let hashtagTimelineViewModel = HashtagTimelineViewModel(authenticationBox: viewModel.authenticationBox, hashtag: tag.name) + _ = self.sceneCoordinator?.present( scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: self, transition: .show diff --git a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel+Diffable.swift b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel+Diffable.swift index f476eab01..b83bc3724 100644 --- a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel+Diffable.swift @@ -14,7 +14,6 @@ extension DiscoveryHashtagsViewModel { ) { diffableDataSource = DiscoverySection.diffableDataSource( tableView: tableView, - context: context, configuration: DiscoverySection.Configuration(authenticationBox: authenticationBox) ) diff --git a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel.swift b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel.swift index 23f425133..9a3cafc81 100644 --- a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel.swift +++ b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel.swift @@ -18,7 +18,6 @@ final class DiscoveryHashtagsViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let viewDidAppeared = PassthroughSubject() @@ -26,8 +25,7 @@ final class DiscoveryHashtagsViewModel { var diffableDataSource: UITableViewDiffableDataSource? @Published var hashtags: [Mastodon.Entity.Tag] = [] - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox // end init diff --git a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift index bc09ad2f2..873ce6da6 100644 --- a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift +++ b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift @@ -10,10 +10,7 @@ import Combine import MastodonCore import MastodonUI -final class DiscoveryNewsViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class DiscoveryNewsViewController: UIViewController, MediaPreviewableViewController { var disposeBag = Set() var viewModel: DiscoveryNewsViewModel! @@ -85,7 +82,7 @@ extension DiscoveryNewsViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { guard case let .link(link) = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { return } guard let url = URL(string: link.url) else { return } - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .safari(url: url), from: self, transition: .safariPresent(animated: true, completion: nil) @@ -182,7 +179,7 @@ extension DiscoveryNewsViewController: TableViewControllerNavigateable { guard case let .link(link) = item else { return } guard let url = URL(string: link.url) else { return } - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .safari(url: url), from: self, transition: .safariPresent(animated: true, completion: nil) diff --git a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+Diffable.swift b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+Diffable.swift index 0ebded10d..88491a6f2 100644 --- a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+Diffable.swift @@ -15,7 +15,6 @@ extension DiscoveryNewsViewModel { ) { diffableDataSource = DiscoverySection.diffableDataSource( tableView: tableView, - context: context, configuration: DiscoverySection.Configuration(authenticationBox: authenticationBox) ) diff --git a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel.swift b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel.swift index 411c0bb77..8874a46fb 100644 --- a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel.swift +++ b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel.swift @@ -18,7 +18,6 @@ final class DiscoveryNewsViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox // output @@ -40,8 +39,7 @@ final class DiscoveryNewsViewModel { let didLoadLatest = PassthroughSubject() @Published var isServerSupportEndpoint = true - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox // end init diff --git a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift index 42513ea93..d1b79ec2c 100644 --- a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift +++ b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift @@ -10,9 +10,7 @@ import Combine import MastodonCore import MastodonUI -final class DiscoveryPostsViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class DiscoveryPostsViewController: UIViewController, MediaPreviewableViewController { var disposeBag = Set() var viewModel: DiscoveryPostsViewModel! diff --git a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift index e55c86335..1191d3f61 100644 --- a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+Diffable.swift @@ -16,9 +16,7 @@ extension DiscoveryPostsViewModel { ) { diffableDataSource = StatusSection.diffableDataSource( tableView: tableView, - context: context, configuration: StatusSection.Configuration( - context: context, authenticationBox: authenticationBox, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel.swift b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel.swift index 396331fbb..52892cb9f 100644 --- a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel.swift +++ b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel.swift @@ -18,7 +18,6 @@ final class DiscoveryPostsViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let dataController: StatusDataController @@ -41,8 +40,7 @@ final class DiscoveryPostsViewModel { @Published var isServerSupportEndpoint = true @MainActor - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox self.dataController = StatusDataController() diff --git a/Mastodon/Scene/Donation/NewDonationNavigationFlow.swift b/Mastodon/Scene/Donation/NewDonationNavigationFlow.swift index 6b302cd0b..17a28c16f 100644 --- a/Mastodon/Scene/Donation/NewDonationNavigationFlow.swift +++ b/Mastodon/Scene/Donation/NewDonationNavigationFlow.swift @@ -10,17 +10,15 @@ import UIKit class NewDonationNavigationFlow: NavigationFlow { private let campaign: DonationCampaignViewModel - private let appContext: AppContext private let authenticationBox: MastodonAuthenticationBox private let sceneCoordinator: SceneCoordinator init( flowPresenter: NavigationFlowPresenter, - campaign: DonationCampaignViewModel, appContext: AppContext, + campaign: DonationCampaignViewModel, authenticationBox: MastodonAuthenticationBox, sceneCoordinator: SceneCoordinator ) { self.campaign = campaign - self.appContext = appContext self.authenticationBox = authenticationBox self.sceneCoordinator = sceneCoordinator super.init(flowPresenter: flowPresenter) @@ -106,7 +104,6 @@ class NewDonationNavigationFlow: NavigationFlow { private func composeDonationSuccessPost(_ suggestedText: String) { let composeViewModel = ComposeViewModel( - context: appContext, authenticationBox: authenticationBox, composeContext: .composeStatus, destination: .topLevel, diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift index 49430c59a..3c713b05a 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift @@ -16,10 +16,7 @@ import MastodonUI import MastodonLocalization import MastodonSDK -final class HashtagTimelineViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class HashtagTimelineViewController: UIViewController, MediaPreviewableViewController { let mediaPreviewTransitionController = MediaPreviewTransitionController() @@ -184,13 +181,12 @@ extension HashtagTimelineViewController { let hashtag = "#" + viewModel.hashtag UITextChecker.learnWord(hashtag) let composeViewModel = ComposeViewModel( - context: context, authenticationBox: viewModel.authenticationBox, composeContext: .composeStatus, destination: .topLevel, initialContent: hashtag ) - _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) } } diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift index d3564e48b..7de3764e6 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift @@ -17,9 +17,7 @@ extension HashtagTimelineViewModel { ) { diffableDataSource = StatusSection.diffableDataSource( tableView: tableView, - context: context, configuration: StatusSection.Configuration( - context: context, authenticationBox: authenticationBox, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift index 5083b1268..e38de655a 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift @@ -22,7 +22,6 @@ final class HashtagTimelineViewModel { var needLoadMiddleIndex: Int? = nil // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let dataController: StatusDataController let isFetchingLatestTimeline = CurrentValueSubject(false) @@ -50,8 +49,7 @@ final class HashtagTimelineViewModel { }() @MainActor - init(context: AppContext, authenticationBox: MastodonAuthenticationBox, hashtag: String) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox, hashtag: String) { self.authenticationBox = authenticationBox self.hashtag = hashtag self.dataController = StatusDataController() diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index fd4eb8a33..c894b5199 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -19,10 +19,7 @@ import MastodonCore import MastodonUI import MastodonLocalization -final class HomeTimelineViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class HomeTimelineViewController: UIViewController, MediaPreviewableViewController { var disposeBag = Set() var viewModel: HomeTimelineViewModel? @@ -616,9 +613,9 @@ extension HomeTimelineViewController { @objc private func findPeopleButtonPressed(_ sender: Any?) { guard let authenticationBox = viewModel?.authenticationBox else { return } - let suggestionAccountViewModel = SuggestionAccountViewModel(context: context, authenticationBox: authenticationBox) + let suggestionAccountViewModel = SuggestionAccountViewModel(authenticationBox: authenticationBox) suggestionAccountViewModel.delegate = viewModel - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .suggestionAccount(viewModel: suggestionAccountViewModel), from: self, transition: .modal(animated: true, completion: nil) @@ -626,13 +623,13 @@ extension HomeTimelineViewController { } @objc private func manuallySearchButtonPressed(_ sender: UIButton) { - coordinator.switchToTabBar(tab: .search) + self.sceneCoordinator?.switchToTabBar(tab: .search) } @objc private func settingBarButtonItemPressed(_ sender: UIBarButtonItem) { guard let setting = SettingService.shared.currentSetting.value else { return } - _ = coordinator.present(scene: .settings(setting: setting), from: self, transition: .none) + _ = self.sceneCoordinator?.present(scene: .settings(setting: setting), from: self, transition: .none) } @objc private func refreshControlValueChanged(_ sender: RefreshControl) { @@ -650,7 +647,7 @@ extension HomeTimelineViewController { FileManager.default.invalidateHomeTimelineCache(for: userIdentifier) FileManager.default.invalidateNotificationsAll(for: userIdentifier) FileManager.default.invalidateNotificationsMentions(for: userIdentifier) - self.coordinator.setup() + self.sceneCoordinator?.setup() } } @@ -741,7 +738,8 @@ extension HomeTimelineViewController { private func showDonationCampaign(_ campaign: Mastodon.Entity.DonationCampaign) { hideDonationCampaignBanner() - navigationFlow = NewDonationNavigationFlow(flowPresenter: self, campaign: campaign, appContext: context, authenticationBox: authenticationBox, sceneCoordinator: coordinator) + guard let coordinator = self.sceneCoordinator else { return } + navigationFlow = NewDonationNavigationFlow(flowPresenter: self, campaign: campaign, authenticationBox: authenticationBox, sceneCoordinator: coordinator) navigationFlow?.presentFlow { [weak self] in self?.navigationFlow = nil } diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift index f85c07cb7..c36e7a7ae 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift @@ -20,9 +20,7 @@ extension HomeTimelineViewModel { ) { diffableDataSource = StatusSection.diffableDataSource( tableView: tableView, - context: context, configuration: StatusSection.Configuration( - context: context, authenticationBox: authenticationBox, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: timelineMiddleLoaderTableViewCellDelegate, diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift index f0a915b2c..cd6b2f8b6 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift @@ -23,7 +23,6 @@ final class HomeTimelineViewModel: NSObject { var observations = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let dataController: FeedDataController @@ -91,10 +90,9 @@ final class HomeTimelineViewModel: NSObject { var cellFrameCache = NSCache() - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox - self.dataController = FeedDataController(context: context, authenticationBox: authenticationBox, kind: .home(timeline: timelineContext)) + self.dataController = FeedDataController(authenticationBox: authenticationBox, kind: .home(timeline: timelineContext)) super.init() self.dataController.records = (try? PersistenceManager.shared.cachedTimeline(.homeTimeline(authenticationBox)).map { MastodonFeed.fromStatus($0, kind: .home) diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index 551a97c27..0411f64f0 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -13,10 +13,7 @@ import MastodonCore import MastodonUI import MastodonLocalization -final class MediaPreviewViewController: UIViewController, NeedsDependency { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class MediaPreviewViewController: UIViewController { var disposeBag = Set() var viewModel: MediaPreviewViewModel! @@ -285,7 +282,7 @@ extension MediaPreviewViewController: MediaPreviewImageViewControllerDelegate { title: L10n.Common.Alerts.SavePhotoFailure.title, message: L10n.Common.Alerts.SavePhotoFailure.message ) - _ = self.coordinator.present( + _ = self.sceneCoordinator?.present( scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil) @@ -296,7 +293,7 @@ extension MediaPreviewViewController: MediaPreviewImageViewControllerDelegate { } receiveValue: { _ in // do nothing } - .store(in: &context.disposeBag) + .store(in: &AppContext.shared.disposeBag) case .copyPhoto: guard let assetURL = viewController.viewModel.item.assetURL else { return } @@ -311,10 +308,10 @@ extension MediaPreviewViewController: MediaPreviewImageViewControllerDelegate { } receiveValue: { _ in // do nothing } - .store(in: &context.disposeBag) + .store(in: &AppContext.shared.disposeBag) case .share: let applicationActivities: [UIActivity] = [ - SafariActivity(sceneCoordinator: self.coordinator) + SafariActivity(sceneCoordinator: self.sceneCoordinator) ] let activityViewController = UIActivityViewController( activityItems: { diff --git a/Mastodon/Scene/Notification/Notification Filtering/Requests/Account Notifications/AccountNotificationTimelineViewController.swift b/Mastodon/Scene/Notification/Notification Filtering/Requests/Account Notifications/AccountNotificationTimelineViewController.swift index cf67b8f2e..34727bfc0 100644 --- a/Mastodon/Scene/Notification/Notification Filtering/Requests/Account Notifications/AccountNotificationTimelineViewController.swift +++ b/Mastodon/Scene/Notification/Notification Filtering/Requests/Account Notifications/AccountNotificationTimelineViewController.swift @@ -15,10 +15,10 @@ class AccountNotificationTimelineViewController: NotificationTimelineViewControl let request: Mastodon.Entity.NotificationRequest weak var delegate: AccountNotificationTimelineViewControllerDelegate? - init(viewModel: NotificationTimelineViewModel, context: AppContext, coordinator: SceneCoordinator, notificationRequest: Mastodon.Entity.NotificationRequest) { + init(viewModel: NotificationTimelineViewModel, notificationRequest: Mastodon.Entity.NotificationRequest) { self.request = notificationRequest - super.init(viewModel: viewModel, context: context, coordinator: coordinator) + super.init(viewModel: viewModel) navigationItem.rightBarButtonItem = UIBarButtonItem(title: nil, image: UIImage(systemName: "ellipsis.circle"), target: nil, action: nil, menu: menu()) } @@ -32,18 +32,18 @@ class AccountNotificationTimelineViewController: NotificationTimelineViewControl UIAction(title: L10n.Scene.Notification.FilteredNotification.accept, image: UIImage(systemName: "checkmark")) { [weak self] _ in guard let self else { return } - coordinator.showLoading() + self.sceneCoordinator?.showLoading() self.navigationController?.popViewController(animated: true) self.delegate?.acceptRequest(self, request: request) - coordinator.hideLoading() + self.sceneCoordinator?.hideLoading() }, UIAction(title: L10n.Scene.Notification.FilteredNotification.dismiss, image: NotificationRequestConstants.dismissIcon) { [weak self] _ in guard let self else { return } - coordinator.showLoading() + self.sceneCoordinator?.showLoading() self.navigationController?.popViewController(animated: true) self.delegate?.dismissRequest(self, request: request) - coordinator.hideLoading() + self.sceneCoordinator?.hideLoading() } ]) diff --git a/Mastodon/Scene/Notification/Notification Filtering/Requests/NotificationRequestsTableViewController.swift b/Mastodon/Scene/Notification/Notification Filtering/Requests/NotificationRequestsTableViewController.swift index 726133c44..d29dc8dd3 100644 --- a/Mastodon/Scene/Notification/Notification Filtering/Requests/NotificationRequestsTableViewController.swift +++ b/Mastodon/Scene/Notification/Notification Filtering/Requests/NotificationRequestsTableViewController.swift @@ -18,9 +18,8 @@ protocol NotificationRequestsTableViewControllerDelegate: AnyObject { func notificationRequestsUpdated(_ viewController: NotificationRequestsTableViewController) } -class NotificationRequestsTableViewController: UIViewController, NeedsDependency { - var context: AppContext! - var coordinator: SceneCoordinator! +class NotificationRequestsTableViewController: UIViewController { + weak var delegate: NotificationRequestsTableViewControllerDelegate? let tableView: UITableView @@ -30,8 +29,6 @@ class NotificationRequestsTableViewController: UIViewController, NeedsDependency init(viewModel: NotificationRequestsViewModel) { self.viewModel = viewModel - self.context = viewModel.appContext - self.coordinator = viewModel.coordinator tableView = UITableView(frame: .zero) tableView.translatesAutoresizingMaskIntoConstraints = false diff --git a/Mastodon/Scene/Notification/Notification Filtering/Requests/NotificationRequestsViewModel.swift b/Mastodon/Scene/Notification/Notification Filtering/Requests/NotificationRequestsViewModel.swift index 524494bec..2202d3c85 100644 --- a/Mastodon/Scene/Notification/Notification Filtering/Requests/NotificationRequestsViewModel.swift +++ b/Mastodon/Scene/Notification/Notification Filtering/Requests/NotificationRequestsViewModel.swift @@ -5,16 +5,12 @@ import MastodonSDK import MastodonCore struct NotificationRequestsViewModel { - let appContext: AppContext let authenticationBox: MastodonAuthenticationBox - let coordinator: SceneCoordinator var requests: [Mastodon.Entity.NotificationRequest] - init(appContext: AppContext, authenticationBox: MastodonAuthenticationBox, coordinator: SceneCoordinator, requests: [Mastodon.Entity.NotificationRequest]) { - self.appContext = appContext + init(authenticationBox: MastodonAuthenticationBox, requests: [Mastodon.Entity.NotificationRequest]) { self.authenticationBox = authenticationBox - self.coordinator = coordinator self.requests = requests } } diff --git a/Mastodon/Scene/Notification/NotificationSection.swift b/Mastodon/Scene/Notification/NotificationSection.swift index 8e243ef50..42070501d 100644 --- a/Mastodon/Scene/Notification/NotificationSection.swift +++ b/Mastodon/Scene/Notification/NotificationSection.swift @@ -32,7 +32,6 @@ extension NotificationSection { static func diffableDataSource( tableView: UITableView, - context: AppContext, configuration: Configuration ) -> UITableViewDiffableDataSource { tableView.register(NotificationTableViewCell.self, forCellReuseIdentifier: String(describing: NotificationTableViewCell.self)) @@ -50,7 +49,6 @@ extension NotificationSection { } else { let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: NotificationTableViewCell.self), for: indexPath) as! NotificationTableViewCell configure( - context: context, tableView: tableView, cell: cell, viewModel: NotificationTableViewCell.ViewModel(value: .feed(feed)), @@ -81,20 +79,17 @@ extension NotificationSection { extension NotificationSection { static func configure( - context: AppContext, tableView: UITableView, cell: NotificationTableViewCell, viewModel: NotificationTableViewCell.ViewModel, configuration: Configuration ) { StatusSection.setupStatusPollDataSource( - context: context, authenticationBox: configuration.authenticationBox, statusView: cell.notificationView.statusView ) StatusSection.setupStatusPollDataSource( - context: context, authenticationBox: configuration.authenticationBox, statusView: cell.notificationView.quoteStatusView ) diff --git a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewController.swift b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewController.swift index 88941a8fb..c8df139a2 100644 --- a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewController.swift +++ b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewController.swift @@ -11,10 +11,7 @@ import CoreDataStack import MastodonCore import MastodonLocalization -class NotificationTimelineViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - weak var context: AppContext! - weak var coordinator: SceneCoordinator! +class NotificationTimelineViewController: UIViewController, MediaPreviewableViewController { let mediaPreviewTransitionController = MediaPreviewTransitionController() @@ -39,10 +36,8 @@ class NotificationTimelineViewController: UIViewController, NeedsDependency, Med let cellFrameCache = NSCache() - init(viewModel: NotificationTimelineViewModel, context: AppContext, coordinator: SceneCoordinator) { + init(viewModel: NotificationTimelineViewModel) { self.viewModel = viewModel - self.context = context - self.coordinator = coordinator super.init(nibName: nil, bundle: nil) @@ -288,11 +283,10 @@ extension NotificationTimelineViewController: TableViewControllerNavigateable { if let status = notification.status { let threadViewModel = ThreadViewModel( - context: self.context, authenticationBox: self.viewModel.authenticationBox, optionalRoot: .root(context: .init(status: .fromEntity(status))) ) - _ = self.coordinator.present( + _ = self.sceneCoordinator?.present( scene: .thread(viewModel: threadViewModel), from: self, transition: .show diff --git a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+Diffable.swift b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+Diffable.swift index 0594c9199..3e0110316 100644 --- a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+Diffable.swift @@ -18,7 +18,6 @@ extension NotificationTimelineViewModel { ) { diffableDataSource = NotificationSection.diffableDataSource( tableView: tableView, - context: context, configuration: NotificationSection.Configuration( authenticationBox: authenticationBox, notificationTableViewCellDelegate: notificationTableViewCellDelegate, diff --git a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel.swift b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel.swift index c557828d9..ba3c87497 100644 --- a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel.swift +++ b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel.swift @@ -19,7 +19,6 @@ final class NotificationTimelineViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let scope: Scope var notificationPolicy: Mastodon.Entity.NotificationPolicy? @@ -47,15 +46,13 @@ final class NotificationTimelineViewModel { @MainActor init( - context: AppContext, authenticationBox: MastodonAuthenticationBox, scope: Scope, notificationPolicy: Mastodon.Entity.NotificationPolicy? = nil ) { - self.context = context self.authenticationBox = authenticationBox self.scope = scope - self.dataController = FeedDataController(context: context, authenticationBox: authenticationBox, kind: scope.feedKind) + self.dataController = FeedDataController(authenticationBox: authenticationBox, kind: scope.feedKind) self.notificationPolicy = notificationPolicy switch scope { diff --git a/Mastodon/Scene/Notification/NotificationViewController.swift b/Mastodon/Scene/Notification/NotificationViewController.swift index d9a15a85e..2272da47c 100644 --- a/Mastodon/Scene/Notification/NotificationViewController.swift +++ b/Mastodon/Scene/Notification/NotificationViewController.swift @@ -14,10 +14,7 @@ import Pageboy import MastodonCore import MastodonSDK -final class NotificationViewController: TabmanViewController, NeedsDependency { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class NotificationViewController: TabmanViewController { var disposeBag = Set() var observations = Set() @@ -129,7 +126,7 @@ extension NotificationViewController { privateMentions: policy.filterPrivateMentions ) - guard let policyViewController = coordinator.present(scene: .notificationPolicy(viewModel: policyViewModel), transition: .formSheet) as? NotificationPolicyViewController else { return } + guard let policyViewController = self.sceneCoordinator?.present(scene: .notificationPolicy(viewModel: policyViewModel), transition: .formSheet) as? NotificationPolicyViewController else { return } policyViewController.delegate = self } @@ -156,12 +153,9 @@ extension NotificationViewController { let viewController = NotificationTimelineViewController( viewModel: NotificationTimelineViewModel( - context: context, authenticationBox: viewModel.authenticationBox, scope: scope, notificationPolicy: viewModel.notificationPolicy - ), - context: context, - coordinator: coordinator + ) ) return viewController diff --git a/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift b/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift index 6eb5cba8c..1218b9c59 100644 --- a/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift +++ b/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift @@ -13,13 +13,10 @@ import MastodonCore import MastodonUI import MastodonLocalization -final class MastodonConfirmEmailViewController: UIViewController, NeedsDependency { +final class MastodonConfirmEmailViewController: UIViewController { var disposeBag = Set() - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - var viewModel: MastodonConfirmEmailViewModel! let stackView = UIStackView() @@ -126,10 +123,10 @@ extension MastodonConfirmEmailViewController { } receiveValue: { _ in // do nothing } - .store(in: &self.context.disposeBag) // execute in the background + .store(in: &AppContext.shared.disposeBag) // execute in the background } // end switch } receiveValue: { _ in - self.coordinator.setup() + self.sceneCoordinator?.setup() // self.dismiss(animated: true, completion: nil) } .store(in: &self.disposeBag) @@ -208,13 +205,13 @@ extension MastodonConfirmEmailViewController { let resendAction = UIAlertAction(title: L10n.Scene.ConfirmEmail.DontReceiveEmail.resendEmail, style: .default) { _ in let url = Mastodon.API.resendEmailURL(domain: self.viewModel.authenticateInfo.domain) let viewModel = MastodonResendEmailViewModel(resendEmailURL: url, email: self.viewModel.email) - _ = self.coordinator.present(scene: .mastodonResendEmail(viewModel: viewModel), from: self, transition: .modal(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .mastodonResendEmail(viewModel: viewModel), from: self, transition: .modal(animated: true, completion: nil)) } let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) { _ in } alertController.addAction(resendAction) alertController.addAction(okAction) - _ = self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) } } diff --git a/Mastodon/Scene/Onboarding/PickServer/CategoryPickerSection.swift b/Mastodon/Scene/Onboarding/PickServer/CategoryPickerSection.swift index 26656f7b3..4f551a403 100644 --- a/Mastodon/Scene/Onboarding/PickServer/CategoryPickerSection.swift +++ b/Mastodon/Scene/Onboarding/PickServer/CategoryPickerSection.swift @@ -17,7 +17,7 @@ enum CategoryPickerSection: Equatable, Hashable { extension CategoryPickerSection { static func collectionViewDiffableDataSource( for collectionView: UICollectionView, - dependency: NeedsDependency, + dependency: UIViewController, viewModel: MastodonPickServerViewModel ) -> UICollectionViewDiffableDataSource { UICollectionViewDiffableDataSource(collectionView: collectionView) { [weak dependency] collectionView, indexPath, item -> UICollectionViewCell? in diff --git a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift index f1c33c887..ead79f4b6 100644 --- a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift +++ b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift @@ -14,11 +14,7 @@ import MastodonLocalization import MastodonUI import MastodonSDK -final class MastodonPickServerViewController: UIViewController, NeedsDependency { - var context: AppContext! { - get { return AppContext.shared } - set { } - } +final class MastodonPickServerViewController: UIViewController { var coordinator: SceneCoordinator! diff --git a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel+Diffable.swift b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel+Diffable.swift index f8a2937fb..a935df3b7 100644 --- a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel+Diffable.swift +++ b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel+Diffable.swift @@ -13,7 +13,7 @@ extension MastodonPickServerViewModel { func setupDiffableDataSource( for tableView: UITableView, - dependency: NeedsDependency, + dependency: UIViewController, pickServerServerSectionTableHeaderViewDelegate: PickServerServerSectionTableHeaderViewDelegate ) { // set section header diff --git a/Mastodon/Scene/Onboarding/PickServer/PickServerSection.swift b/Mastodon/Scene/Onboarding/PickServer/PickServerSection.swift index 9f1781657..1b340ad12 100644 --- a/Mastodon/Scene/Onboarding/PickServer/PickServerSection.swift +++ b/Mastodon/Scene/Onboarding/PickServer/PickServerSection.swift @@ -18,7 +18,7 @@ enum PickServerSection: Equatable, Hashable { extension PickServerSection { static func tableViewDiffableDataSource( for tableView: UITableView, - dependency: NeedsDependency + dependency: UIViewController ) -> UITableViewDiffableDataSource { tableView.register(PickServerCell.self, forCellReuseIdentifier: String(describing: PickServerCell.self)) tableView.register(PickServerLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: PickServerLoaderTableViewCell.self)) diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift index 5261fea46..d0c7f0e95 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift @@ -16,15 +16,12 @@ import MastodonAsset import MastodonCore import MastodonLocalization -final class MastodonRegisterViewController: UIViewController, NeedsDependency, OnboardingViewControllerAppearance { +final class MastodonRegisterViewController: UIViewController, OnboardingViewControllerAppearance { static let avatarImageMaxSizeInPixel = CGSize(width: 400, height: 400) var disposeBag = Set() private var observations = Set() - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } var viewModel: MastodonRegisterViewModel! private(set) lazy var mastodonRegisterView = MastodonRegisterView(viewModel: viewModel) @@ -92,7 +89,7 @@ extension MastodonRegisterViewController { let alertController = UIAlertController(for: error, title: L10n.Common.Alerts.SignUpFailure.title, preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) alertController.addAction(okAction) - _ = self.coordinator.present( + _ = self.sceneCoordinator?.present( scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil) diff --git a/Mastodon/Scene/Onboarding/ResendEmail/MastodonResendEmailViewController.swift b/Mastodon/Scene/Onboarding/ResendEmail/MastodonResendEmailViewController.swift index da43547f2..88c94fbf5 100644 --- a/Mastodon/Scene/Onboarding/ResendEmail/MastodonResendEmailViewController.swift +++ b/Mastodon/Scene/Onboarding/ResendEmail/MastodonResendEmailViewController.swift @@ -10,10 +10,7 @@ import UIKit import WebKit import MastodonCore -final class MastodonResendEmailViewController: UIViewController, NeedsDependency { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class MastodonResendEmailViewController: UIViewController { var disposeBag = Set() var viewModel: MastodonResendEmailViewModel! diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index 07ba94564..f154c6780 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -12,7 +12,7 @@ import MastodonCore import MastodonLocalization import MastodonSDK -final class WelcomeViewController: UIViewController, NeedsDependency { +final class WelcomeViewController: UIViewController { private enum Constants { static let topAnchorInset: CGFloat = 20 @@ -28,16 +28,13 @@ final class WelcomeViewController: UIViewController, NeedsDependency { } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } private let authenticationViewModel = AuthenticationViewModel() private var authenticationStateTask: Task<(), Never>? var disposeBag = Set() var observations = Set() - private(set) lazy var viewModel = WelcomeViewModel(context: context) + private(set) lazy var viewModel = WelcomeViewModel() let welcomeIllustrationView = WelcomeIllustrationView() let separatorView = WelcomeSeparatorView(frame: .zero) @@ -137,7 +134,7 @@ extension WelcomeViewController { let alertController = UIAlertController(for: error, title: "Error", preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) alertController.addAction(okAction) - _ = self.coordinator.present( + _ = self.sceneCoordinator?.present( scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil) @@ -151,25 +148,25 @@ extension WelcomeViewController { case .error(let error): displayError(error) case .logInToExistingAccountRequested: - _ = coordinator.present(scene: .mastodonLogin(authenticationViewModel: authenticationViewModel, suggestedDomain: viewModel.randomDefaultServer?.domain), from: self, transition: .show) + _ = self.sceneCoordinator?.present(scene: .mastodonLogin(authenticationViewModel: authenticationViewModel, suggestedDomain: viewModel.randomDefaultServer?.domain), from: self, transition: .show) case .joiningServer: break case .showingRules(let viewModel): if let viewModel { - _ = coordinator.present(scene: .mastodonServerRules(viewModel: viewModel), from: self, transition: .show) + _ = self.sceneCoordinator?.present(scene: .mastodonServerRules(viewModel: viewModel), from: self, transition: .show) } else { popBack() } case .registering(let viewModel): - _ = coordinator.present(scene: .mastodonRegister(viewModel: viewModel), from: self, transition: .show) + _ = self.sceneCoordinator?.present(scene: .mastodonRegister(viewModel: viewModel), from: self, transition: .show) case .showingPrivacyPolicy(let viewModel): - _ = coordinator.present(scene: .mastodonPrivacyPolicies(viewModel: viewModel), from: self, transition: .show) + _ = self.sceneCoordinator?.present(scene: .mastodonPrivacyPolicies(viewModel: viewModel), from: self, transition: .show) case .pickingServer: - _ = coordinator.present(scene: .mastodonPickServer(viewMode: MastodonPickServerViewModel(joinServer: { [weak self] server in try await self?.authenticationViewModel.joinServer(server) }, displayError: { [weak self] error in self?.displayError(error) })), from: self, transition: .show) + _ = self.sceneCoordinator?.present(scene: .mastodonPickServer(viewMode: MastodonPickServerViewModel(joinServer: { [weak self] server in try await self?.authenticationViewModel.joinServer(server) }, displayError: { [weak self] error in self?.displayError(error) })), from: self, transition: .show) case .confirmingEmail(let viewModel): - _ = coordinator.present(scene: .mastodonConfirmEmail(viewModel: viewModel), from: self, transition: .show) + _ = self.sceneCoordinator?.present(scene: .mastodonConfirmEmail(viewModel: viewModel), from: self, transition: .show) case .authenticatedUser(let authBox): - coordinator.setup() + self.sceneCoordinator?.setup() break case .authenticatingUser: break diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewModel.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewModel.swift index d2dcc30c6..fa80e824e 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewModel.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewModel.swift @@ -16,16 +16,11 @@ final class WelcomeViewModel { var disposeBag = Set() private(set) var defaultServers: [Mastodon.Entity.DefaultServer]? var randomDefaultServer: Mastodon.Entity.Server? - - // input - let context: AppContext // output @Published var needsShowDismissEntry = false - init(context: AppContext) { - self.context = context - + init() { AuthenticationServiceProvider.shared.$mastodonAuthenticationBoxes .map { !$0.isEmpty } .assign(to: &$needsShowDismissEntry) diff --git a/Mastodon/Scene/Profile/About/ProfileAboutViewController.swift b/Mastodon/Scene/Profile/About/ProfileAboutViewController.swift index 473c22d52..f6c1d5aa7 100644 --- a/Mastodon/Scene/Profile/About/ProfileAboutViewController.swift +++ b/Mastodon/Scene/Profile/About/ProfileAboutViewController.swift @@ -19,9 +19,6 @@ protocol ProfileAboutViewControllerDelegate: AnyObject { final class ProfileAboutViewController: UIViewController { - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - weak var delegate: ProfileAboutViewControllerDelegate? var disposeBag = Set() diff --git a/Mastodon/Scene/Profile/Bookmark/BookmarkViewController.swift b/Mastodon/Scene/Profile/Bookmark/BookmarkViewController.swift index 164e81510..2835799c8 100644 --- a/Mastodon/Scene/Profile/Bookmark/BookmarkViewController.swift +++ b/Mastodon/Scene/Profile/Bookmark/BookmarkViewController.swift @@ -14,10 +14,7 @@ import MastodonCore import MastodonUI import MastodonLocalization -final class BookmarkViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class BookmarkViewController: UIViewController, MediaPreviewableViewController { var disposeBag = Set() var viewModel: BookmarkViewModel! diff --git a/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift b/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift index 097366df4..67334aa4a 100644 --- a/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel+Diffable.swift @@ -15,9 +15,7 @@ extension BookmarkViewModel { ) { diffableDataSource = StatusSection.diffableDataSource( tableView: tableView, - context: context, configuration: StatusSection.Configuration( - context: context, authenticationBox: authenticationBox, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel.swift b/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel.swift index 03e4534ab..469c9157f 100644 --- a/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel.swift +++ b/Mastodon/Scene/Profile/Bookmark/BookmarkViewModel.swift @@ -17,7 +17,6 @@ final class BookmarkViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let dataController: StatusDataController @@ -38,8 +37,7 @@ final class BookmarkViewModel { }() @MainActor - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox self.dataController = StatusDataController() } diff --git a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift index f025d688d..d72dcdc2f 100644 --- a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift +++ b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift @@ -12,19 +12,14 @@ import MastodonLocalization import MastodonUI import MastodonSDK -final class FamiliarFollowersViewController: UIViewController, NeedsDependency { +final class FamiliarFollowersViewController: UIViewController { - weak var context: AppContext! - weak var coordinator: SceneCoordinator! let viewModel: FamiliarFollowersViewModel let tableView: UITableView - init(viewModel: FamiliarFollowersViewModel, context: AppContext, coordinator: SceneCoordinator) { + init(viewModel: FamiliarFollowersViewModel) { self.viewModel = viewModel - self.context = context - self.coordinator = coordinator - tableView = UITableView() tableView.rowHeight = UITableView.automaticDimension tableView.separatorStyle = .none diff --git a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift index f1ce7bdac..12be013a8 100644 --- a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift +++ b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift @@ -10,7 +10,6 @@ import MastodonCore import MastodonSDK final class FamiliarFollowersViewModel { - let context: AppContext let authenticationBox: MastodonAuthenticationBox var accounts: [Mastodon.Entity.Account] @@ -19,8 +18,7 @@ final class FamiliarFollowersViewModel { // output var diffableDataSource: UITableViewDiffableDataSource? - init(context: AppContext, authenticationBox: MastodonAuthenticationBox, accounts: [Mastodon.Entity.Account], relationships: [Mastodon.Entity.Relationship]) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox, accounts: [Mastodon.Entity.Account], relationships: [Mastodon.Entity.Relationship]) { self.authenticationBox = authenticationBox self.accounts = accounts self.relationships = relationships @@ -32,7 +30,6 @@ final class FamiliarFollowersViewModel { ) { diffableDataSource = UserSection.diffableDataSource( tableView: tableView, - context: context, authenticationBox: authenticationBox, userTableViewCellDelegate: userTableViewCellDelegate ) diff --git a/Mastodon/Scene/Profile/Favorite/FavoriteViewController.swift b/Mastodon/Scene/Profile/Favorite/FavoriteViewController.swift index eacc8d524..4d7a4779a 100644 --- a/Mastodon/Scene/Profile/Favorite/FavoriteViewController.swift +++ b/Mastodon/Scene/Profile/Favorite/FavoriteViewController.swift @@ -17,10 +17,7 @@ import MastodonCore import MastodonUI import MastodonLocalization -final class FavoriteViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class FavoriteViewController: UIViewController, MediaPreviewableViewController { var disposeBag = Set() var viewModel: FavoriteViewModel! diff --git a/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift b/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift index f84929e53..963f8545e 100644 --- a/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Favorite/FavoriteViewModel+Diffable.swift @@ -15,9 +15,7 @@ extension FavoriteViewModel { ) { diffableDataSource = StatusSection.diffableDataSource( tableView: tableView, - context: context, configuration: StatusSection.Configuration( - context: context, authenticationBox: authenticationBox, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/Profile/Favorite/FavoriteViewModel.swift b/Mastodon/Scene/Profile/Favorite/FavoriteViewModel.swift index db61f5fc1..429f2c084 100644 --- a/Mastodon/Scene/Profile/Favorite/FavoriteViewModel.swift +++ b/Mastodon/Scene/Profile/Favorite/FavoriteViewModel.swift @@ -17,7 +17,6 @@ final class FavoriteViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let dataController: StatusDataController @@ -37,8 +36,7 @@ final class FavoriteViewModel { }() @MainActor - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox self.dataController = StatusDataController() } diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift index ce0cf4242..98e5d1c86 100644 --- a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewController.swift @@ -11,9 +11,7 @@ import MastodonCore import MastodonUI import MastodonLocalization -final class FollowedTagsViewController: UIViewController, NeedsDependency { - var context: AppContext! - var coordinator: SceneCoordinator! +final class FollowedTagsViewController: UIViewController { let authenticationBox: MastodonAuthenticationBox var viewModel: FollowedTagsViewModel @@ -22,9 +20,7 @@ final class FollowedTagsViewController: UIViewController, NeedsDependency { let tableView: UITableView let refreshControl: UIRefreshControl - init(appContext: AppContext, sceneCoordinator: SceneCoordinator, authenticationBox: MastodonAuthenticationBox, viewModel: FollowedTagsViewModel) { - self.context = appContext - self.coordinator = sceneCoordinator + init(authenticationBox: MastodonAuthenticationBox, viewModel: FollowedTagsViewModel) { self.authenticationBox = authenticationBox self.viewModel = viewModel @@ -76,12 +72,11 @@ extension FollowedTagsViewController: UITableViewDelegate { let object = viewModel.followedTags[indexPath.row] let hashtagTimelineViewModel = HashtagTimelineViewModel( - context: self.context, authenticationBox: self.authenticationBox, hashtag: object.name ) - _ = self.coordinator.present( + _ = self.sceneCoordinator?.present( scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: self, transition: .show diff --git a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift index 3ac57d8a0..75e6ae713 100644 --- a/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift +++ b/Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift @@ -16,11 +16,9 @@ final class FollowedTagsViewModel: NSObject { var diffableDataSource: UITableViewDiffableDataSource? // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox self.followedTags = [] diff --git a/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift b/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift index e54b2b620..06e345cfe 100644 --- a/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift +++ b/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift @@ -13,10 +13,7 @@ import MastodonUI import MastodonLocalization import MastodonSDK -final class FollowerListViewController: UIViewController, NeedsDependency { - - weak var context: AppContext! - weak var coordinator: SceneCoordinator! +final class FollowerListViewController: UIViewController { var disposeBag = Set() var viewModel: FollowerListViewModel @@ -24,10 +21,8 @@ final class FollowerListViewController: UIViewController, NeedsDependency { let tableView: UITableView let refreshControl: UIRefreshControl - init(viewModel: FollowerListViewModel, coordinator: SceneCoordinator, context: AppContext) { + init(viewModel: FollowerListViewModel) { - self.context = context - self.coordinator = coordinator self.viewModel = viewModel tableView = UITableView() diff --git a/Mastodon/Scene/Profile/Follower/FollowerListViewModel+Diffable.swift b/Mastodon/Scene/Profile/Follower/FollowerListViewModel+Diffable.swift index 9d82b0c0c..f4055f4bd 100644 --- a/Mastodon/Scene/Profile/Follower/FollowerListViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Follower/FollowerListViewModel+Diffable.swift @@ -17,7 +17,6 @@ extension FollowerListViewModel { ) { diffableDataSource = UserSection.diffableDataSource( tableView: tableView, - context: context, authenticationBox: authenticationBox, userTableViewCellDelegate: userTableViewCellDelegate ) diff --git a/Mastodon/Scene/Profile/Follower/FollowerListViewModel.swift b/Mastodon/Scene/Profile/Follower/FollowerListViewModel.swift index ee5762b24..45ddf6b84 100644 --- a/Mastodon/Scene/Profile/Follower/FollowerListViewModel.swift +++ b/Mastodon/Scene/Profile/Follower/FollowerListViewModel.swift @@ -15,7 +15,6 @@ final class FollowerListViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox @Published var accounts: [Mastodon.Entity.Account] @Published var relationships: [Mastodon.Entity.Relationship] @@ -43,12 +42,10 @@ final class FollowerListViewModel { }() init( - context: AppContext, authenticationBox: MastodonAuthenticationBox, domain: String?, userID: String? ) { - self.context = context self.authenticationBox = authenticationBox self.domain = domain self.userID = userID diff --git a/Mastodon/Scene/Profile/Following/FollowingListViewController.swift b/Mastodon/Scene/Profile/Following/FollowingListViewController.swift index 7e4997c51..c95a55d4d 100644 --- a/Mastodon/Scene/Profile/Following/FollowingListViewController.swift +++ b/Mastodon/Scene/Profile/Following/FollowingListViewController.swift @@ -14,10 +14,7 @@ import MastodonUI import CoreDataStack import MastodonSDK -final class FollowingListViewController: UIViewController, NeedsDependency { - - weak var context: AppContext! - weak var coordinator: SceneCoordinator! +final class FollowingListViewController: UIViewController { var disposeBag = Set() var viewModel: FollowingListViewModel @@ -25,10 +22,8 @@ final class FollowingListViewController: UIViewController, NeedsDependency { let refreshControl: UIRefreshControl let tableView: UITableView - init(viewModel: FollowingListViewModel, coordinator: SceneCoordinator, context: AppContext) { + init(viewModel: FollowingListViewModel) { - self.context = context - self.coordinator = coordinator self.viewModel = viewModel tableView = UITableView() diff --git a/Mastodon/Scene/Profile/Following/FollowingListViewModel+Diffable.swift b/Mastodon/Scene/Profile/Following/FollowingListViewModel+Diffable.swift index 53db698ca..e3d49a947 100644 --- a/Mastodon/Scene/Profile/Following/FollowingListViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Following/FollowingListViewModel+Diffable.swift @@ -18,7 +18,6 @@ extension FollowingListViewModel { ) { diffableDataSource = UserSection.diffableDataSource( tableView: tableView, - context: context, authenticationBox: authenticationBox, userTableViewCellDelegate: userTableViewCellDelegate ) diff --git a/Mastodon/Scene/Profile/Following/FollowingListViewModel.swift b/Mastodon/Scene/Profile/Following/FollowingListViewModel.swift index 877617c05..f32c72604 100644 --- a/Mastodon/Scene/Profile/Following/FollowingListViewModel.swift +++ b/Mastodon/Scene/Profile/Following/FollowingListViewModel.swift @@ -16,7 +16,6 @@ final class FollowingListViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox @Published var accounts: [Mastodon.Entity.Account] @Published var relationships: [Mastodon.Entity.Relationship] @@ -44,12 +43,10 @@ final class FollowingListViewModel { }() init( - context: AppContext, authenticationBox: MastodonAuthenticationBox, domain: String?, userID: String? ) { - self.context = context self.authenticationBox = authenticationBox self.domain = domain self.userID = userID diff --git a/Mastodon/Scene/Profile/Header/ProfileHeaderViewController.swift b/Mastodon/Scene/Profile/Header/ProfileHeaderViewController.swift index 558ee8c30..a93f8f838 100644 --- a/Mastodon/Scene/Profile/Header/ProfileHeaderViewController.swift +++ b/Mastodon/Scene/Profile/Header/ProfileHeaderViewController.swift @@ -25,14 +25,11 @@ protocol ProfileHeaderViewControllerDelegate: AnyObject { func profileHeaderViewController(_ profileHeaderViewController: ProfileHeaderViewController, profileHeaderView: ProfileHeaderView, metaTextView: MetaTextView, metaDidPressed meta: Meta) } -final class ProfileHeaderViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { +final class ProfileHeaderViewController: UIViewController, MediaPreviewableViewController { static let segmentedControlHeight: CGFloat = 50 static let headerMinHeight: CGFloat = segmentedControlHeight - weak var context: AppContext! - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - var disposeBag = Set() let viewModel: ProfileHeaderViewModel @@ -82,10 +79,8 @@ final class ProfileHeaderViewController: UIViewController, NeedsDependency, Medi return documentPickerController }() - init(context: AppContext, authenticationBox: MastodonAuthenticationBox, coordinator: SceneCoordinator, profileViewModel: ProfileViewModel) { - self.context = context - self.coordinator = coordinator - self.viewModel = ProfileHeaderViewModel(context: context, authenticationBox: authenticationBox, account: profileViewModel.account, me: profileViewModel.me, relationship: profileViewModel.relationship) + init(authenticationBox: MastodonAuthenticationBox, profileViewModel: ProfileViewModel) { + self.viewModel = ProfileHeaderViewModel(authenticationBox: authenticationBox, account: profileViewModel.account, me: profileViewModel.me, relationship: profileViewModel.relationship) self.profileHeaderView = ProfileHeaderView(account: profileViewModel.account, me: profileViewModel.me, relationship: profileViewModel.relationship) super.init(nibName: nil, bundle: nil) @@ -341,12 +336,11 @@ extension ProfileHeaderViewController: ProfileHeaderViewDelegate { guard let domain = viewModel.account.domain else { return } let userID = viewModel.account.id let followerListViewModel = FollowerListViewModel( - context: context, authenticationBox: viewModel.authenticationBox, domain: domain, userID: userID ) - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .follower(viewModel: followerListViewModel), from: self, transition: .show @@ -357,12 +351,11 @@ extension ProfileHeaderViewController: ProfileHeaderViewDelegate { let userID = viewModel.account.id let followingListViewModel = FollowingListViewModel( - context: context, authenticationBox: viewModel.authenticationBox, domain: domain, userID: userID ) - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .following(viewModel: followingListViewModel), from: self, transition: .show diff --git a/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift b/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift index 8fed8a4c8..f52963a40 100644 --- a/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift +++ b/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift @@ -23,7 +23,6 @@ final class ProfileHeaderViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox @Published var me: Mastodon.Entity.Account @@ -45,8 +44,7 @@ final class ProfileHeaderViewModel { @Published var isTitleViewDisplaying = false @Published var isTitleViewContentOffsetSet = false - init(context: AppContext, authenticationBox: MastodonAuthenticationBox, account: Mastodon.Entity.Account, me: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox, account: Mastodon.Entity.Account, me: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?) { self.authenticationBox = authenticationBox self.account = account self.me = me diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 08efa4aed..fddca6508 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -22,14 +22,11 @@ protocol ProfileViewModelEditable { var isEdited: Bool { get } } -final class ProfileViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { +final class ProfileViewController: UIViewController, MediaPreviewableViewController { public static let containerViewMarginForRegularHorizontalSizeClass: CGFloat = 64 public static let containerViewMarginForCompactHorizontalSizeClass: CGFloat = 16 - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - var disposeBag = Set() var viewModel: ProfileViewModel? { @@ -144,7 +141,7 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi } private func createProfileHeaderViewController(viewModel: ProfileViewModel) -> ProfileHeaderViewController { - let viewController = ProfileHeaderViewController(context: context, authenticationBox: viewModel.authenticationBox, coordinator: coordinator, profileViewModel: viewModel) + let viewController = ProfileHeaderViewController(authenticationBox: viewModel.authenticationBox, profileViewModel: viewModel) return viewController } @@ -159,12 +156,6 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi mediaUserTimelineViewModel: viewModel.mediaUserTimelineViewModel, profileAboutViewModel: viewModel.profileAboutViewModel ) - profilePagingViewModel.viewControllers.forEach { viewController in - if let viewController = viewController as? NeedsDependency { - viewController.context = context - viewController.coordinator = coordinator - } - } return profilePagingViewModel }() return profilePagingViewController @@ -553,15 +544,15 @@ extension ProfileViewController { switch meta { case .url(_, _, let url, _): guard let url = URL(string: url) else { return } - _ = coordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil)) case .mention(_, _, let userInfo): guard let href = userInfo?["href"] as? String, let url = URL(string: href) else { return } - _ = coordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil)) case .hashtag(_, let hashtag, _): guard let viewModel = viewModel else { break } - let hashtagTimelineViewModel = HashtagTimelineViewModel(context: context, authenticationBox: viewModel.authenticationBox, hashtag: hashtag) - _ = coordinator.present(scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: nil, transition: .show) + let hashtagTimelineViewModel = HashtagTimelineViewModel(authenticationBox: viewModel.authenticationBox, hashtag: hashtag) + _ = self.sceneCoordinator?.present(scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: nil, transition: .show) case .email, .emoji: break } @@ -578,7 +569,7 @@ extension ProfileViewController { @objc private func settingBarButtonItemPressed(_ sender: UIBarButtonItem) { guard let setting = SettingService.shared.currentSetting.value else { return } - _ = coordinator.present(scene: .settings(setting: setting), from: self, transition: .none) + _ = self.sceneCoordinator?.present(scene: .settings(setting: setting), from: self, transition: .none) } @objc private func shareBarButtonItemPressed(_ sender: UIBarButtonItem) { @@ -588,7 +579,7 @@ extension ProfileViewController { dependency: self, account: viewModel.account ) - _ = self.coordinator.present( + _ = self.sceneCoordinator?.present( scene: .activityViewController( activityViewController: activityViewController, sourceView: nil, @@ -602,15 +593,15 @@ extension ProfileViewController { @objc private func favoriteBarButtonItemPressed(_ sender: UIBarButtonItem) { guard let viewModel = viewModel else { return } - let favoriteViewModel = FavoriteViewModel(context: context, authenticationBox: viewModel.authenticationBox) - _ = coordinator.present(scene: .favorite(viewModel: favoriteViewModel), from: self, transition: .show) + let favoriteViewModel = FavoriteViewModel(authenticationBox: viewModel.authenticationBox) + _ = self.sceneCoordinator?.present(scene: .favorite(viewModel: favoriteViewModel), from: self, transition: .show) } @objc private func bookmarkBarButtonItemPressed(_ sender: UIBarButtonItem) { guard let viewModel = viewModel else { return } - let bookmarkViewModel = BookmarkViewModel(context: context, authenticationBox: viewModel.authenticationBox) - _ = coordinator.present(scene: .bookmark(viewModel: bookmarkViewModel), from: self, transition: .show) + let bookmarkViewModel = BookmarkViewModel(authenticationBox: viewModel.authenticationBox) + _ = self.sceneCoordinator?.present(scene: .bookmark(viewModel: bookmarkViewModel), from: self, transition: .show) } @objc private func replyBarButtonItemPressed(_ sender: UIBarButtonItem) { @@ -619,20 +610,19 @@ extension ProfileViewController { let mention = "@" + viewModel.account.acct UITextChecker.learnWord(mention) let composeViewModel = ComposeViewModel( - context: context, authenticationBox: viewModel.authenticationBox, composeContext: .composeStatus, destination: .topLevel, initialContent: mention ) - _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) } @objc private func followedTagsItemPressed(_ sender: UIBarButtonItem) { guard let viewModel = viewModel else { return } - let followedTagsViewModel = FollowedTagsViewModel(context: context, authenticationBox: viewModel.authenticationBox) - _ = coordinator.present(scene: .followedTags(viewModel: followedTagsViewModel), from: self, transition: .show) + let followedTagsViewModel = FollowedTagsViewModel(authenticationBox: viewModel.authenticationBox) + _ = self.sceneCoordinator?.present(scene: .followedTags(viewModel: followedTagsViewModel), from: self, transition: .show) } @objc private func refreshControlValueChanged(_ sender: RefreshControl) { @@ -840,7 +830,7 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate { let alertController = UIAlertController(for: error, title: L10n.Common.Alerts.EditProfileFailure.title, preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) alertController.addAction(okAction) - _ = self.coordinator.present( + _ = self.sceneCoordinator?.present( scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil) @@ -900,7 +890,7 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate { alertController.addAction(unblockAction) let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel) alertController.addAction(cancelAction) - coordinator.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) + self.sceneCoordinator?.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) } else if relationship.domainBlocking { guard let domain = account.domain else { return } @@ -930,7 +920,7 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate { alertController.addAction(unblockAction) let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel) alertController.addAction(cancelAction) - coordinator.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) + self.sceneCoordinator?.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) } else if relationship.muting { let name = account.displayNameWithFallback @@ -950,7 +940,7 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate { alertController.addAction(unmuteAction) let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel) alertController.addAction(cancelAction) - coordinator.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) + self.sceneCoordinator?.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) } else { Task { [weak self] in guard let self else { return } diff --git a/Mastodon/Scene/Profile/Timeline/UserTimelineViewController.swift b/Mastodon/Scene/Profile/Timeline/UserTimelineViewController.swift index 3c89a528e..e64a49ab7 100644 --- a/Mastodon/Scene/Profile/Timeline/UserTimelineViewController.swift +++ b/Mastodon/Scene/Profile/Timeline/UserTimelineViewController.swift @@ -14,10 +14,7 @@ import TabBarPager import XLPagerTabStrip import MastodonCore -final class UserTimelineViewController: UIViewController, NeedsDependency, MediaPreviewableViewController, StatusReloadable { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class UserTimelineViewController: UIViewController, MediaPreviewableViewController, StatusReloadable { var disposeBag = Set() var viewModel: UserTimelineViewModel! diff --git a/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift b/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift index 43d4fccf3..5a74fb9e4 100644 --- a/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/Timeline/UserTimelineViewModel+Diffable.swift @@ -16,9 +16,7 @@ extension UserTimelineViewModel { ) { diffableDataSource = StatusSection.diffableDataSource( tableView: tableView, - context: context, configuration: StatusSection.Configuration( - context: context, authenticationBox: authenticationBox, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/Profile/UserList/FavoritedBy/FavoritedByViewController.swift b/Mastodon/Scene/Profile/UserList/FavoritedBy/FavoritedByViewController.swift index 9f8c980be..52f82d6bf 100644 --- a/Mastodon/Scene/Profile/UserList/FavoritedBy/FavoritedByViewController.swift +++ b/Mastodon/Scene/Profile/UserList/FavoritedBy/FavoritedByViewController.swift @@ -13,9 +13,7 @@ import MastodonLocalization import MastodonUI import CoreDataStack -final class FavoritedByViewController: UIViewController, NeedsDependency { - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class FavoritedByViewController: UIViewController { var disposeBag = Set() var viewModel: UserListViewModel! diff --git a/Mastodon/Scene/Profile/UserList/RebloggedBy/RebloggedByViewController.swift b/Mastodon/Scene/Profile/UserList/RebloggedBy/RebloggedByViewController.swift index a63800ac7..2448e7032 100644 --- a/Mastodon/Scene/Profile/UserList/RebloggedBy/RebloggedByViewController.swift +++ b/Mastodon/Scene/Profile/UserList/RebloggedBy/RebloggedByViewController.swift @@ -13,10 +13,7 @@ import MastodonLocalization import MastodonUI import CoreDataStack -final class RebloggedByViewController: UIViewController, NeedsDependency { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class RebloggedByViewController: UIViewController { var disposeBag = Set() var viewModel: UserListViewModel! diff --git a/Mastodon/Scene/Profile/UserList/UserListViewModel+Diffable.swift b/Mastodon/Scene/Profile/UserList/UserListViewModel+Diffable.swift index a0f483d8f..fb97385ba 100644 --- a/Mastodon/Scene/Profile/UserList/UserListViewModel+Diffable.swift +++ b/Mastodon/Scene/Profile/UserList/UserListViewModel+Diffable.swift @@ -19,7 +19,6 @@ extension UserListViewModel { ) { diffableDataSource = UserSection.diffableDataSource( tableView: tableView, - context: context, authenticationBox: authenticationBox, userTableViewCellDelegate: userTableViewCellDelegate ) diff --git a/Mastodon/Scene/Report/Report/ReportViewController.swift b/Mastodon/Scene/Report/Report/ReportViewController.swift index f9371f94c..ba1416be2 100644 --- a/Mastodon/Scene/Report/Report/ReportViewController.swift +++ b/Mastodon/Scene/Report/Report/ReportViewController.swift @@ -12,13 +12,10 @@ import MastodonAsset import MastodonCore import MastodonLocalization -class ReportViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { +class ReportViewController: UIViewController, ReportViewControllerAppearance { var disposeBag = Set() private var observations = Set() - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } let viewModel: ReportViewModel @@ -50,8 +47,6 @@ class ReportViewController: UIViewController, NeedsDependency, ReportViewControl viewModel.reportSupplementaryViewModel.delegate = self let reportReasonViewController = ReportReasonViewController(viewModel: viewModel.reportReasonViewModel) - reportReasonViewController.context = context - reportReasonViewController.coordinator = coordinator addChild(reportReasonViewController) reportReasonViewController.view.translatesAutoresizingMaskIntoConstraints = false @@ -80,25 +75,24 @@ extension ReportViewController: ReportReasonViewControllerDelegate { switch reason { case .dislike: let reportResultViewModel = ReportResultViewModel( - context: context, authenticationBox: viewModel.authenticationBox, account: viewModel.account, relationship: viewModel.relationship, isReported: false ) - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .reportResult(viewModel: reportResultViewModel), from: self, transition: .show ) case .violateRule: - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .reportServerRules(viewModel: viewModel.reportServerRulesViewModel), from: self, transition: .show ) case .spam, .other: - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .reportStatus(viewModel: viewModel.reportStatusViewModel), from: self, transition: .show @@ -114,7 +108,7 @@ extension ReportViewController: ReportServerRulesViewControllerDelegate { return } - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .reportStatus(viewModel: viewModel.reportStatusViewModel), from: self, transition: .show @@ -133,7 +127,7 @@ extension ReportViewController: ReportStatusViewControllerDelegate { } private func coordinateToReportSupplementary() { - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .reportSupplementary(viewModel: viewModel.reportSupplementaryViewModel), from: self, transition: .show @@ -157,14 +151,13 @@ extension ReportViewController: ReportSupplementaryViewControllerDelegate { let _ = try await viewModel.report() let reportResultViewModel = ReportResultViewModel( - context: context, authenticationBox: viewModel.authenticationBox, account: viewModel.account, relationship: viewModel.relationship, isReported: true ) - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .reportResult(viewModel: reportResultViewModel), from: self, transition: .show @@ -174,7 +167,7 @@ extension ReportViewController: ReportSupplementaryViewControllerDelegate { let alertController = UIAlertController(for: error, title: nil, preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) alertController.addAction(okAction) - _ = self.coordinator.present( + _ = self.sceneCoordinator?.present( scene: .alertController(alertController: alertController), from: nil, transition: .alertController(animated: true, completion: nil) diff --git a/Mastodon/Scene/Report/ReportReason/ReportReasonViewController.swift b/Mastodon/Scene/Report/ReportReason/ReportReasonViewController.swift index 2e89229ca..fb46bc34d 100644 --- a/Mastodon/Scene/Report/ReportReason/ReportReasonViewController.swift +++ b/Mastodon/Scene/Report/ReportReason/ReportReasonViewController.swift @@ -17,10 +17,7 @@ protocol ReportReasonViewControllerDelegate: AnyObject { func reportReasonViewController(_ viewController: ReportReasonViewController, nextButtonPressed button: UIButton) } -final class ReportReasonViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class ReportReasonViewController: UIViewController, ReportViewControllerAppearance { var disposeBag = Set() private var observations = Set() diff --git a/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift b/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift index 3ec0ba16f..7cd7b0544 100644 --- a/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift +++ b/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift @@ -12,13 +12,10 @@ import MastodonAsset import MastodonCore import MastodonLocalization -final class ReportResultViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { +final class ReportResultViewController: UIViewController, ReportViewControllerAppearance { var disposeBag = Set() private var observations = Set() - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } var viewModel: ReportResultViewModel! private(set) lazy var reportResultView = ReportResultView(viewModel: viewModel) diff --git a/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift b/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift index 7bce931cc..fcd1464fd 100644 --- a/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift +++ b/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift @@ -21,7 +21,6 @@ class ReportResultViewModel: ObservableObject { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let account: Mastodon.Entity.Account var relationship: Mastodon.Entity.Relationship @@ -46,13 +45,11 @@ class ReportResultViewModel: ObservableObject { let blockActionPublisher = PassthroughSubject() init( - context: AppContext, authenticationBox: MastodonAuthenticationBox, account: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship, isReported: Bool ) { - self.context = context self.authenticationBox = authenticationBox self.account = account self.relationship = relationship diff --git a/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesViewController.swift b/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesViewController.swift index 5d9f8ede8..66706a16e 100644 --- a/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesViewController.swift +++ b/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesViewController.swift @@ -17,10 +17,7 @@ protocol ReportServerRulesViewControllerDelegate: AnyObject { func reportServerRulesViewController(_ viewController: ReportServerRulesViewController, nextButtonPressed button: UIButton) } -final class ReportServerRulesViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class ReportServerRulesViewController: UIViewController, ReportViewControllerAppearance { var disposeBag = Set() private var observations = Set() diff --git a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift index e928c59cf..9838a7ccf 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift @@ -18,12 +18,9 @@ protocol ReportStatusViewControllerDelegate: AnyObject { func reportStatusViewController(_ viewController: ReportStatusViewController, nextButtonDidPressed button: UIButton) } -class ReportStatusViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { +class ReportStatusViewController: UIViewController, ReportViewControllerAppearance { var disposeBag = Set() private var observations = Set() - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } var viewModel: ReportStatusViewModel! diff --git a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift index 8292d69cf..586fa752e 100644 --- a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift +++ b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift @@ -17,14 +17,11 @@ protocol ReportSupplementaryViewControllerDelegate: AnyObject { func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, nextButtonDidPressed button: UIButton) } -final class ReportSupplementaryViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { +final class ReportSupplementaryViewController: UIViewController, ReportViewControllerAppearance { var disposeBag = Set() private var observations = Set() - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - var viewModel: ReportSupplementaryViewModel! { willSet { precondition(!isViewLoaded) } } // MAKK: - UI diff --git a/Mastodon/Scene/Root/ContentSplitViewController.swift b/Mastodon/Scene/Root/ContentSplitViewController.swift index bd27de574..cb0685993 100644 --- a/Mastodon/Scene/Root/ContentSplitViewController.swift +++ b/Mastodon/Scene/Root/ContentSplitViewController.swift @@ -15,31 +15,26 @@ protocol ContentSplitViewControllerDelegate: AnyObject { func contentSplitViewController(_ contentSplitViewController: ContentSplitViewController, sidebarViewController: SidebarViewController, didDoubleTapTab tab: Tab) } -final class ContentSplitViewController: UIViewController, NeedsDependency { +final class ContentSplitViewController: UIViewController { var disposeBag = Set() static let sidebarWidth: CGFloat = 89 - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - var authenticationBox: MastodonAuthenticationBox? weak var delegate: ContentSplitViewControllerDelegate? private(set) lazy var sidebarViewController: SidebarViewController = { let sidebarViewController = SidebarViewController() - sidebarViewController.context = context - sidebarViewController.coordinator = coordinator - sidebarViewController.viewModel = SidebarViewModel(context: context, authenticationBox: authenticationBox) + sidebarViewController.viewModel = SidebarViewModel(authenticationBox: authenticationBox) sidebarViewController.delegate = self return sidebarViewController }() @Published var currentSupplementaryTab: Tab = .home private(set) lazy var mainTabBarController: MainTabBarController = { - let mainTabBarController = MainTabBarController(context: self.context, coordinator: self.coordinator, authenticationBox: self.authenticationBox) + let mainTabBarController = MainTabBarController(authenticationBox: self.authenticationBox) if let homeTimelineViewController = mainTabBarController.viewController(of: HomeTimelineViewController.self) { homeTimelineViewController.viewModel?.displaySettingBarButtonItem = false } @@ -110,8 +105,8 @@ extension ContentSplitViewController: SidebarViewControllerDelegate { guard case let .tab(tab) = item, tab == .me else { return } guard let authenticationBox else { return } - let accountListViewModel = AccountListViewModel(context: context, authenticationBox: authenticationBox) - let accountListViewController = coordinator.present( + let accountListViewModel = AccountListViewModel(authenticationBox: authenticationBox) + let accountListViewController = self.sceneCoordinator?.present( scene: .accountList(viewModel: accountListViewModel), from: nil, transition: .popover(sourceView: sourceView) diff --git a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift index ec4900370..12c9a7ba3 100644 --- a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift @@ -18,9 +18,6 @@ class MainTabBarController: UITabBarController { public var disposeBag = Set() - weak var context: AppContext! - weak var coordinator: SceneCoordinator! - var authenticationBox: MastodonAuthenticationBox? private let largeContentViewerInteraction = UILargeContentViewerInteraction() @@ -50,44 +47,32 @@ class MainTabBarController: UITabBarController { private let feedbackGenerator = FeedbackGenerator.shared init( - context: AppContext, - coordinator: SceneCoordinator, authenticationBox: MastodonAuthenticationBox? ) { - self.context = context - self.coordinator = coordinator self.authenticationBox = authenticationBox homeTimelineViewController = HomeTimelineViewController() homeTimelineViewController.configureTabBarItem(with: .home) - homeTimelineViewController.context = context - homeTimelineViewController.coordinator = coordinator searchViewController = SearchViewController() searchViewController.configureTabBarItem(with: .search) - searchViewController.context = context - searchViewController.coordinator = coordinator composeViewController = UIViewController() composeViewController.configureTabBarItem(with: .compose) notificationViewController = NotificationViewController() notificationViewController.configureTabBarItem(with: .notifications) - notificationViewController.context = context - notificationViewController.coordinator = coordinator meProfileViewController = ProfileViewController() - meProfileViewController.context = context - meProfileViewController.coordinator = coordinator meProfileViewController.configureTabBarItem(with: .me) if let authenticationBox { - notificationViewController.viewModel = NotificationViewModel(context: context, authenticationBox: authenticationBox) - homeTimelineViewController.viewModel = HomeTimelineViewModel(context: context, authenticationBox: authenticationBox) - searchViewController.viewModel = SearchViewModel(context: context, authenticationBox: authenticationBox) + notificationViewController.viewModel = NotificationViewModel(context: AppContext.shared, authenticationBox: authenticationBox) + homeTimelineViewController.viewModel = HomeTimelineViewModel(authenticationBox: authenticationBox) + searchViewController.viewModel = SearchViewModel(authenticationBox: authenticationBox) if let account = authenticationBox.cachedAccount { - meProfileViewController.viewModel = ProfileViewModel(context: context, authenticationBox: authenticationBox, account: account, relationship: nil, me: account) + meProfileViewController.viewModel = ProfileViewModel(context: AppContext.shared, authenticationBox: authenticationBox, account: account, relationship: nil, me: account) } } @@ -113,7 +98,7 @@ extension MainTabBarController { if let profileView = (newValue as? UINavigationController)?.topViewController as? ProfileViewController{ guard let authenticationBox, let account = authenticationBox.cachedAccount else { return } - profileView.viewModel = ProfileViewModel(context: self.context, authenticationBox: authenticationBox, account: account, relationship: nil, me: account) + profileView.viewModel = ProfileViewModel(context: AppContext.shared, authenticationBox: authenticationBox, account: account, relationship: nil, me: account) } } } @@ -139,7 +124,7 @@ extension MainTabBarController { APIService.shared.error .receive(on: DispatchQueue.main) .sink { [weak self] error in - guard let self, let coordinator = self.coordinator else { return } + guard let self, let coordinator = self.sceneCoordinator else { return } switch error { case .implicit: break @@ -220,7 +205,7 @@ extension MainTabBarController { .store(in: &self.disposeBag) if let currentViewModel = self.meProfileViewController.viewModel, currentViewModel.account.id == account.id, !currentViewModel.isEditing { - self.meProfileViewController.viewModel = ProfileViewModel(context: self.context, authenticationBox: authenticationBox, account: account, relationship: nil, me: account) + self.meProfileViewController.viewModel = ProfileViewModel(context: AppContext.shared, authenticationBox: authenticationBox, account: account, relationship: nil, me: account) } } .store(in: &disposeBag) @@ -268,12 +253,11 @@ extension MainTabBarController { feedbackGenerator.generate(.impact(.medium)) guard let authenticationBox else { return } let composeViewModel = ComposeViewModel( - context: context, authenticationBox: authenticationBox, composeContext: .composeStatus, destination: .topLevel ) - _ = coordinator.present(scene: .compose(viewModel: composeViewModel), transition: .modal(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .compose(viewModel: composeViewModel), transition: .modal(animated: true, completion: nil)) } private func touchedTab(by sender: UIGestureRecognizer) -> Tab? { @@ -312,8 +296,8 @@ extension MainTabBarController { switch tab { case .me: guard let authenticationBox else { return } - let accountListViewModel = AccountListViewModel(context: context, authenticationBox: authenticationBox) - _ = coordinator.present(scene: .accountList(viewModel: accountListViewModel), from: self, transition: .formSheet) + let accountListViewModel = AccountListViewModel(authenticationBox: authenticationBox) + _ = self.sceneCoordinator?.present(scene: .accountList(viewModel: accountListViewModel), from: self, transition: .formSheet) default: break } @@ -558,25 +542,24 @@ extension MainTabBarController { @objc private func showFavoritesKeyCommandHandler(_ sender: UIKeyCommand) { guard let authenticationBox else { return } - let favoriteViewModel = FavoriteViewModel(context: context, authenticationBox: authenticationBox) - _ = coordinator.present(scene: .favorite(viewModel: favoriteViewModel), from: nil, transition: .show) + let favoriteViewModel = FavoriteViewModel(authenticationBox: authenticationBox) + _ = self.sceneCoordinator?.present(scene: .favorite(viewModel: favoriteViewModel), from: nil, transition: .show) } @objc private func openSettingsKeyCommandHandler(_ sender: UIKeyCommand) { guard let setting = SettingService.shared.currentSetting.value else { return } - _ = coordinator.present(scene: .settings(setting: setting), from: self, transition: .none) + _ = self.sceneCoordinator?.present(scene: .settings(setting: setting), from: self, transition: .none) } @objc private func composeNewPostKeyCommandHandler(_ sender: UIKeyCommand) { guard let authenticationBox else { return } let composeViewModel = ComposeViewModel( - context: context, authenticationBox: authenticationBox, composeContext: .composeStatus, destination: .topLevel ) - _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: nil, transition: .modal(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .compose(viewModel: composeViewModel), from: nil, transition: .modal(animated: true, completion: nil)) } } diff --git a/Mastodon/Scene/Root/RootSplitViewController.swift b/Mastodon/Scene/Root/RootSplitViewController.swift index 691cb3a83..32404f4f6 100644 --- a/Mastodon/Scene/Root/RootSplitViewController.swift +++ b/Mastodon/Scene/Root/RootSplitViewController.swift @@ -10,23 +10,18 @@ import Combine import CoreDataStack import MastodonCore -final class RootSplitViewController: UISplitViewController, NeedsDependency { +final class RootSplitViewController: UISplitViewController { var disposeBag = Set() static let sidebarWidth: CGFloat = 89 - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - var authenticationBox: MastodonAuthenticationBox? private var isPrimaryDisplay = false private(set) lazy var contentSplitViewController: ContentSplitViewController = { let contentSplitViewController = ContentSplitViewController() - contentSplitViewController.context = context - contentSplitViewController.coordinator = coordinator contentSplitViewController.authenticationBox = authenticationBox contentSplitViewController.delegate = self return contentSplitViewController @@ -34,22 +29,17 @@ final class RootSplitViewController: UISplitViewController, NeedsDependency { private(set) lazy var searchViewController: SearchViewController = { let searchViewController = SearchViewController() - searchViewController.context = context - searchViewController.coordinator = coordinator searchViewController.viewModel = .init( - context: context, authenticationBox: authenticationBox ) return searchViewController }() - lazy var compactMainTabBarViewController = MainTabBarController(context: context, coordinator: coordinator, authenticationBox: authenticationBox) + lazy var compactMainTabBarViewController = MainTabBarController(authenticationBox: authenticationBox) let separatorLine = UIView.separatorLine - init(context: AppContext, coordinator: SceneCoordinator, authenticationBox: MastodonAuthenticationBox?) { - self.context = context - self.coordinator = coordinator + init(authenticationBox: MastodonAuthenticationBox?) { self.authenticationBox = authenticationBox super.init(style: .doubleColumn) diff --git a/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift b/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift index 24f33fd64..b31701970 100644 --- a/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift +++ b/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift @@ -17,10 +17,8 @@ protocol SidebarViewControllerDelegate: AnyObject { func sidebarViewController(_ sidebarViewController: SidebarViewController, didDoubleTapItem item: SidebarViewModel.Item, sourceView: UIView) } -final class SidebarViewController: UIViewController, NeedsDependency { - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - +final class SidebarViewController: UIViewController { + var disposeBag = Set() var observations = Set() var viewModel: SidebarViewModel! @@ -200,7 +198,7 @@ extension SidebarViewController: UICollectionViewDelegate { case .setting: guard let setting = SettingService.shared.currentSetting.value else { return } - _ = coordinator.present(scene: .settings(setting: setting), from: self, transition: .none) + _ = self.sceneCoordinator?.present(scene: .settings(setting: setting), from: self, transition: .none) case .compose: assertionFailure() } @@ -212,12 +210,11 @@ extension SidebarViewController: UICollectionViewDelegate { switch item { case .compose: let composeViewModel = ComposeViewModel( - context: context, authenticationBox: authenticationBox, composeContext: .composeStatus, destination: .topLevel ) - _ = coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) + _ = self.sceneCoordinator?.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) default: assertionFailure() } diff --git a/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift b/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift index 48681981f..58f8761c8 100644 --- a/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift +++ b/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift @@ -20,7 +20,6 @@ final class SidebarViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox? @Published private var isSidebarDataSourceReady = false @Published private var isAvatarButtonDataReady = false @@ -35,8 +34,7 @@ final class SidebarViewModel { UIImage.SymbolConfiguration(weight: .bold) ) - init(context: AppContext, authenticationBox: MastodonAuthenticationBox?) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox?) { self.authenticationBox = authenticationBox Publishers.CombineLatest( diff --git a/Mastodon/Scene/Search/Search/SearchViewController.swift b/Mastodon/Scene/Search/Search/SearchViewController.swift index f0daca6f8..00ba3ba63 100644 --- a/Mastodon/Scene/Search/Search/SearchViewController.swift +++ b/Mastodon/Scene/Search/Search/SearchViewController.swift @@ -13,10 +13,7 @@ import MastodonCore import MastodonLocalization import Pageboy -final class SearchViewController: UIViewController, NeedsDependency { - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - +final class SearchViewController: UIViewController { var searchTransitionController = SearchTransitionController() var disposeBag = Set() @@ -30,17 +27,16 @@ final class SearchViewController: UIViewController, NeedsDependency { let searchBarTapPublisher = PassthroughSubject() private(set) lazy var discoveryViewController: DiscoveryViewController? = { - guard let authenticationBox = viewModel?.authenticationBox else { return nil } - let viewController = DiscoveryViewController() - viewController.context = context - viewController.coordinator = coordinator - viewController.viewModel = .init( - context: context, - coordinator: coordinator, - authenticationBox: authenticationBox - ) - viewController.delegate = self - return viewController + if let authenticationBox = viewModel?.authenticationBox { + let viewController = DiscoveryViewController() + viewController.viewModel = .init( + authenticationBox: authenticationBox + ) + viewController.delegate = self + return viewController + } else { + return nil + } }() let segmentedControl: UISegmentedControl @@ -142,7 +138,7 @@ final class SearchViewController: UIViewController, NeedsDependency { // FIXME: // use `.customPush(animated: false)` false to disable navigation bar animation for searchBar layout // but that should be a fade transition whe fixed size searchBar - _ = self.coordinator.present(scene: .searchDetail(viewModel: searchDetailViewModel), from: self, transition: .customPush(animated: false)) + _ = self.sceneCoordinator?.present(scene: .searchDetail(viewModel: searchDetailViewModel), from: self, transition: .customPush(animated: false)) } .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Search/Search/SearchViewModel.swift b/Mastodon/Scene/Search/Search/SearchViewModel.swift index 3e8f855ac..8cf855394 100644 --- a/Mastodon/Scene/Search/Search/SearchViewModel.swift +++ b/Mastodon/Scene/Search/Search/SearchViewModel.swift @@ -19,15 +19,13 @@ final class SearchViewModel: NSObject { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox? // output var diffableDataSource: UICollectionViewDiffableDataSource? @Published var hashtags: [Mastodon.Entity.Tag] = [] - init(context: AppContext, authenticationBox: MastodonAuthenticationBox?) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox?) { self.authenticationBox = authenticationBox super.init() } diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift index 7781445f6..783c8bfb9 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift @@ -12,20 +12,16 @@ protocol SearchResultOverviewCoordinatorDelegate: AnyObject { class SearchResultOverviewCoordinator: Coordinator { let overviewViewController: SearchResultsOverviewTableViewController - let sceneCoordinator: SceneCoordinator - let context: AppContext let authenticationBox: MastodonAuthenticationBox weak var delegate: SearchResultOverviewCoordinatorDelegate? var activeTask: Task? - init(appContext: AppContext, authenticationBox: MastodonAuthenticationBox, sceneCoordinator: SceneCoordinator) { - self.sceneCoordinator = sceneCoordinator - self.context = appContext + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox - overviewViewController = SearchResultsOverviewTableViewController(appContext: appContext, authenticationBox: authenticationBox, sceneCoordinator: sceneCoordinator) + overviewViewController = SearchResultsOverviewTableViewController(authenticationBox: authenticationBox) } func start() { @@ -36,9 +32,9 @@ class SearchResultOverviewCoordinator: Coordinator { extension SearchResultOverviewCoordinator: SearchResultsOverviewTableViewControllerDelegate { @MainActor func searchForPosts(_ viewController: SearchResultsOverviewTableViewController, withSearchText searchText: String) { - let searchResultViewModel = SearchResultViewModel(context: context, authenticationBox: authenticationBox, searchScope: .posts, searchText: searchText) + let searchResultViewModel = SearchResultViewModel(authenticationBox: authenticationBox, searchScope: .posts, searchText: searchText) - sceneCoordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) + viewController.sceneCoordinator?.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) } func showPosts(_ viewController: SearchResultsOverviewTableViewController, tag: Mastodon.Entity.Tag) { @@ -55,9 +51,9 @@ extension SearchResultOverviewCoordinator: SearchResultsOverviewTableViewControl @MainActor func searchForPeople(_ viewController: SearchResultsOverviewTableViewController, withName searchText: String) { - let searchResultViewModel = SearchResultViewModel(context: context, authenticationBox: authenticationBox, searchScope: .people, searchText: searchText) + let searchResultViewModel = SearchResultViewModel(authenticationBox: authenticationBox, searchScope: .people, searchText: searchText) - sceneCoordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) + viewController.sceneCoordinator?.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) } func goTo(_ viewController: SearchResultsOverviewTableViewController, urlString: String) { @@ -98,7 +94,7 @@ extension SearchResultOverviewCoordinator: SearchResultsOverviewTableViewControl guard let prefixedURL else { return } - await sceneCoordinator.present(scene: .safari(url: prefixedURL), transition: .safariPresent(animated: true)) + await viewController.sceneCoordinator?.present(scene: .safari(url: prefixedURL), transition: .safariPresent(animated: true)) } } } @@ -139,7 +135,7 @@ extension SearchResultOverviewCoordinator: SearchResultsOverviewTableViewControl let alertController = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) alertController.addAction(okAction) - sceneCoordinator.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) + viewController.sceneCoordinator?.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) } } } diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 0037b4967..fbd719045 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -15,10 +15,8 @@ protocol SearchResultsOverviewTableViewControllerDelegate: AnyObject { func searchForPerson(_ viewController: SearchResultsOverviewTableViewController, username: String, domain: String) } -class SearchResultsOverviewTableViewController: UIViewController, NeedsDependency, AuthContextProvider { +class SearchResultsOverviewTableViewController: UIViewController, AuthContextProvider { let authenticationBox: MastodonAuthenticationBox - var context: AppContext! - var coordinator: SceneCoordinator! private let tableView: UITableView var dataSource: UITableViewDiffableDataSource? @@ -27,11 +25,9 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc var activeTask: Task? - init(appContext: AppContext, authenticationBox: MastodonAuthenticationBox, sceneCoordinator: SceneCoordinator) { + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox - self.context = appContext - self.coordinator = sceneCoordinator tableView = UITableView(frame: .zero, style: .insetGrouped) tableView.keyboardDismissMode = .onDrag diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift index 3a396e374..9c7216d3a 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift @@ -21,15 +21,12 @@ final class CustomSearchController: UISearchController { // Fake search bar not works on iPad with UISplitViewController // check device and fallback to standard UISearchController -final class SearchDetailViewController: UIViewController, NeedsDependency { +final class SearchDetailViewController: UIViewController { var disposeBag = Set() var observations = Set() let searchResultOverviewCoordinator: SearchResultOverviewCoordinator - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - let isPhoneDevice: Bool = { return UIDevice.current.userInterfaceIdiom == .phone }() @@ -81,15 +78,11 @@ final class SearchDetailViewController: UIViewController, NeedsDependency { //MARK: - init - init(appContext: AppContext, sceneCoordinator: SceneCoordinator, authenticationBox: MastodonAuthenticationBox) { - self.context = appContext - self.coordinator = sceneCoordinator + init(authenticationBox: MastodonAuthenticationBox) { - self.searchResultOverviewCoordinator = SearchResultOverviewCoordinator(appContext: appContext, authenticationBox: authenticationBox, sceneCoordinator: sceneCoordinator) + self.searchResultOverviewCoordinator = SearchResultOverviewCoordinator(authenticationBox: authenticationBox) self.searchHistoryViewController = SearchHistoryViewController() - searchHistoryViewController.context = appContext - searchHistoryViewController.coordinator = sceneCoordinator - searchHistoryViewController.viewModel = SearchHistoryViewModel(context: appContext, authenticationBox: authenticationBox) + searchHistoryViewController.viewModel = SearchHistoryViewModel(authenticationBox: authenticationBox) super.init(nibName: nil, bundle: nil) @@ -262,8 +255,8 @@ extension SearchDetailViewController: UISearchBarDelegate { searchBar.resignFirstResponder() - let searchResultViewModel = SearchResultViewModel(context: context, authenticationBox: viewModel.authenticationBox, searchScope: .all, searchText: searchText) - coordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) + let searchResultViewModel = SearchResultViewModel(authenticationBox: viewModel.authenticationBox, searchScope: .all, searchText: searchText) + self.sceneCoordinator?.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) } func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift index 4565efc48..671101f83 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift @@ -25,7 +25,6 @@ extension SearchHistorySection { viewModel: SearchHistoryViewModel, collectionView: UICollectionView, authenticationBox: MastodonAuthenticationBox, - context: AppContext, configuration: Configuration ) -> UICollectionViewDiffableDataSource { diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift index 210f9d4eb..76e7b5942 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift @@ -11,10 +11,7 @@ import CoreDataStack import MastodonCore import MastodonUI -final class SearchHistoryViewController: UIViewController, NeedsDependency { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class SearchHistoryViewController: UIViewController { var disposeBag = Set() var viewModel: SearchHistoryViewModel! diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift index 699e76dcf..44f6110c6 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift @@ -17,7 +17,6 @@ extension SearchHistoryViewModel { viewModel: self, collectionView: collectionView, authenticationBox: authenticationBox, - context: context, configuration: SearchHistorySection.Configuration( searchHistorySectionHeaderCollectionReusableViewDelegate: searchHistorySectionHeaderCollectionReusableViewDelegate ) diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel.swift index 3474f9738..59bb75e03 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel.swift @@ -14,15 +14,13 @@ final class SearchHistoryViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox @Published public var items: [Persistence.SearchHistory.Item] // output var diffableDataSource: UICollectionViewDiffableDataSource? - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox self.items = (try? FileManager.default.searchItems(for: authenticationBox)) ?? [] } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift index b1c23ae97..8c016ff63 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift @@ -30,7 +30,6 @@ extension SearchResultSection { static func tableViewDiffableDataSource( tableView: UITableView, - context: AppContext, authenticationBox: MastodonAuthenticationBox, configuration: Configuration ) -> UITableViewDiffableDataSource { @@ -60,7 +59,6 @@ extension SearchResultSection { let displayItem = StatusTableViewCell.StatusTableViewCellViewModel.DisplayItem.status(status) let contentConcealModel = StatusView.ContentConcealViewModel(status: status, filterBox: StatusFilterService.shared.activeFilterBox, filterContext: nil) // no filters in search results configure( - context: context, tableView: tableView, cell: cell, viewModel: StatusTableViewCell.StatusTableViewCellViewModel(displayItem: displayItem, contentConcealModel: contentConcealModel), @@ -91,19 +89,16 @@ extension SearchResultSection { extension SearchResultSection { static func configure( - context: AppContext, tableView: UITableView, cell: StatusTableViewCell, viewModel: StatusTableViewCell.StatusTableViewCellViewModel, configuration: Configuration ) { StatusSection.setupStatusPollDataSource( - context: context, authenticationBox: configuration.authenticationBox, statusView: cell.statusView ) - cell.statusView.viewModel.context = context cell.statusView.viewModel.authenticationBox = configuration.authenticationBox cell.configure( diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift index 906acb9da..415eba46c 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift @@ -12,10 +12,7 @@ import MastodonCore import MastodonUI import MastodonAsset -final class SearchResultViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class SearchResultViewController: UIViewController, MediaPreviewableViewController { let mediaPreviewTransitionController = MediaPreviewTransitionController() diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift index ffc562567..839da1271 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift @@ -18,7 +18,6 @@ extension SearchResultViewModel { ) { diffableDataSource = SearchResultSection.tableViewDiffableDataSource( tableView: tableView, - context: context, authenticationBox: authenticationBox, configuration: .init( authenticationBox: authenticationBox, diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift index d9c8a8194..a1a85355b 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift @@ -17,7 +17,6 @@ final class SearchResultViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let searchScope: SearchScope let searchText: String @@ -46,8 +45,7 @@ final class SearchResultViewModel { let didDataSourceUpdate = PassthroughSubject() @MainActor - init(context: AppContext, authenticationBox: MastodonAuthenticationBox, searchScope: SearchScope = .all, searchText: String) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox, searchScope: SearchScope = .all, searchText: String) { self.authenticationBox = authenticationBox self.searchScope = searchScope self.searchText = searchText diff --git a/Mastodon/Scene/Settings/Server Details/AboutInstanceViewController.swift b/Mastodon/Scene/Settings/Server Details/AboutInstanceViewController.swift index d09a62df5..444f5c3fa 100644 --- a/Mastodon/Scene/Settings/Server Details/AboutInstanceViewController.swift +++ b/Mastodon/Scene/Settings/Server Details/AboutInstanceViewController.swift @@ -10,11 +10,9 @@ protocol AboutInstanceViewControllerDelegate: AnyObject { func sendEmailToAdmin(_ viewController: AboutInstanceViewController, emailAddress: String) } -class AboutInstanceViewController: UIViewController, NeedsDependency, AuthContextProvider { +class AboutInstanceViewController: UIViewController, AuthContextProvider { var authenticationBox: MastodonAuthenticationBox - var context: AppContext! - var coordinator: SceneCoordinator! weak var delegate: AboutInstanceViewControllerDelegate? var dataSource: AboutInstanceTableViewDataSource? @@ -25,11 +23,8 @@ class AboutInstanceViewController: UIViewController, NeedsDependency, AuthContex var instance: Mastodon.Entity.V2.Instance? - init(context: AppContext, authenticationBox: MastodonAuthenticationBox, coordinator: SceneCoordinator) { - - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox - self.coordinator = coordinator tableView = UITableView(frame: .zero, style: .insetGrouped) tableView.translatesAutoresizingMaskIntoConstraints = false diff --git a/Mastodon/Scene/Settings/Server Details/ServerDetailsViewController.swift b/Mastodon/Scene/Settings/Server Details/ServerDetailsViewController.swift index e746a18f6..58c3dc905 100644 --- a/Mastodon/Scene/Settings/Server Details/ServerDetailsViewController.swift +++ b/Mastodon/Scene/Settings/Server Details/ServerDetailsViewController.swift @@ -47,7 +47,7 @@ class ServerDetailsViewController: UIViewController { containerView = UIView() containerView.translatesAutoresizingMaskIntoConstraints = false - aboutInstanceViewController = AboutInstanceViewController(context: appContext, authenticationBox: authenticationBox, coordinator: sceneCoordinator) + aboutInstanceViewController = AboutInstanceViewController(authenticationBox: authenticationBox) instanceRulesViewController = InstanceRulesViewController() pageController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal) diff --git a/Mastodon/Scene/Settings/SettingsCoordinator.swift b/Mastodon/Scene/Settings/SettingsCoordinator.swift index 36529648c..8bb06e44e 100644 --- a/Mastodon/Scene/Settings/SettingsCoordinator.swift +++ b/Mastodon/Scene/Settings/SettingsCoordinator.swift @@ -126,7 +126,7 @@ extension SettingsCoordinator: SettingsViewControllerDelegate { await MainActor.run { [weak self] in guard let s = self, let donationCampaign = s.settingsViewController.donationCampaign else { return } - let donationFlow = NewDonationNavigationFlow(flowPresenter: viewController, campaign: donationCampaign, appContext: s.appContext, authenticationBox: s.authenticationBox, sceneCoordinator: s.sceneCoordinator) + let donationFlow = NewDonationNavigationFlow(flowPresenter: viewController, campaign: donationCampaign, authenticationBox: s.authenticationBox, sceneCoordinator: s.sceneCoordinator) s.navigationFlow = donationFlow donationFlow.presentFlow { [weak self] in self?.navigationFlow = nil @@ -301,7 +301,7 @@ extension SettingsCoordinator: MetaLabelDelegate { let url = URL(string: href) else { return } _ = sceneCoordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil)) case .hashtag(_, let hashtag, _): - let hashtagTimelineViewModel = HashtagTimelineViewModel(context: appContext, authenticationBox: authenticationBox, hashtag: hashtag) + let hashtagTimelineViewModel = HashtagTimelineViewModel(authenticationBox: authenticationBox, hashtag: hashtag) _ = sceneCoordinator.present(scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: nil, transition: .show) case .email(let email, _): if let emailUrl = URL(string: "mailto:\(email)"), UIApplication.shared.canOpenURL(emailUrl) { diff --git a/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift b/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift index fb88fc615..6ee6879ba 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift @@ -47,7 +47,7 @@ extension UserTableViewCell { } } -extension UserTableViewCellDelegate where Self: ViewControllerWithDependencies & AuthContextProvider { +extension UserTableViewCellDelegate where Self: UIViewController & AuthContextProvider { func userView(_ view: UserView, didTapButtonWith state: UserView.ButtonState, for account: Mastodon.Entity.Account, me: Mastodon.Entity.Account?) { Task { await MainActor.run { view.setButtonState(.loading) } diff --git a/Mastodon/Scene/SuggestionAccount/RecommendAccountSection.swift b/Mastodon/Scene/SuggestionAccount/RecommendAccountSection.swift index 2db687c24..b05847b1b 100644 --- a/Mastodon/Scene/SuggestionAccount/RecommendAccountSection.swift +++ b/Mastodon/Scene/SuggestionAccount/RecommendAccountSection.swift @@ -28,7 +28,6 @@ extension RecommendAccountSection { static func tableViewDiffableDataSource( tableView: UITableView, - context: AppContext, configuration: Configuration ) -> UITableViewDiffableDataSource { UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in diff --git a/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewController.swift b/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewController.swift index 8b299dc2b..025698b02 100644 --- a/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewController.swift +++ b/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewController.swift @@ -15,10 +15,7 @@ import MastodonCore import MastodonUI import MastodonLocalization -class SuggestionAccountViewController: UIViewController, NeedsDependency { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +class SuggestionAccountViewController: UIViewController { var disposeBag = Set() var viewModel: SuggestionAccountViewModel! @@ -127,7 +124,7 @@ extension SuggestionAccountViewController: SuggestionAccountTableViewFooterDeleg func followAll(_ footerView: SuggestionAccountTableViewFooter) { viewModel.followAllSuggestedAccounts(self, presentedOn: self.navigationController) { DispatchQueue.main.async { - self.coordinator.hideLoading(on: self.navigationController) + self.sceneCoordinator?.hideLoading(on: self.navigationController) self.dismiss(animated: true) } } diff --git a/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel.swift b/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel.swift index c7bbb2514..7e0e29e5c 100644 --- a/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel.swift +++ b/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel.swift @@ -20,7 +20,6 @@ final class SuggestionAccountViewModel: NSObject { weak var delegate: SuggestionAccountViewModelDelegate? // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox @Published var accounts: [Mastodon.Entity.V2.SuggestionAccount] var relationships: [Mastodon.Entity.Relationship] @@ -31,10 +30,8 @@ final class SuggestionAccountViewModel: NSObject { var tableViewDiffableDataSource: UITableViewDiffableDataSource? init( - context: AppContext, authenticationBox: MastodonAuthenticationBox ) { - self.context = context self.authenticationBox = authenticationBox accounts = [] @@ -80,7 +77,6 @@ final class SuggestionAccountViewModel: NSObject { ) { tableViewDiffableDataSource = RecommendAccountSection.tableViewDiffableDataSource( tableView: tableView, - context: context, configuration: RecommendAccountSection.Configuration( authenticationBox: authenticationBox, suggestionAccountTableViewCellDelegate: suggestionAccountTableViewCellDelegate @@ -110,12 +106,12 @@ final class SuggestionAccountViewModel: NSObject { .store(in: &disposeBag) } - func followAllSuggestedAccounts(_ dependency: ViewControllerWithDependencies & AuthContextProvider, presentedOn: UIViewController?, completion: (() -> Void)? = nil) { + func followAllSuggestedAccounts(_ dependency: UIViewController & AuthContextProvider, presentedOn: UIViewController?, completion: (() -> Void)? = nil) { let tmpAccounts = accounts.compactMap { $0.account } Task { - await dependency.coordinator.showLoading(on: presentedOn) + await dependency.sceneCoordinator?.showLoading(on: presentedOn) await withTaskGroup(of: Void.self, body: { taskGroup in for account in tmpAccounts { taskGroup.addTask { diff --git a/Mastodon/Scene/Thread/MastodonStatusThreadViewModel.swift b/Mastodon/Scene/Thread/MastodonStatusThreadViewModel.swift index bb62af8f2..e98a2ab8d 100644 --- a/Mastodon/Scene/Thread/MastodonStatusThreadViewModel.swift +++ b/Mastodon/Scene/Thread/MastodonStatusThreadViewModel.swift @@ -22,7 +22,6 @@ final class MastodonStatusThreadViewModel { var disposeBag = Set() // input - let context: AppContext let filterContext: Mastodon.Entity.FilterContext? @Published private(set) var deletedObjectIDs: Set = Set() @@ -33,8 +32,7 @@ final class MastodonStatusThreadViewModel { @Published var __descendants: [StatusItem] = [] @Published var descendants: [StatusItem] = [] - init(context: AppContext, filterContext: Mastodon.Entity.FilterContext?) { - self.context = context + init(filterContext: Mastodon.Entity.FilterContext?) { self.filterContext = filterContext Publishers.CombineLatest( diff --git a/Mastodon/Scene/Thread/RemoteThreadViewModel.swift b/Mastodon/Scene/Thread/RemoteThreadViewModel.swift index a9106f78e..0fc231989 100644 --- a/Mastodon/Scene/Thread/RemoteThreadViewModel.swift +++ b/Mastodon/Scene/Thread/RemoteThreadViewModel.swift @@ -13,12 +13,10 @@ import MastodonSDK final class RemoteThreadViewModel: ThreadViewModel { init( - context: AppContext, authenticationBox: MastodonAuthenticationBox, statusID: Mastodon.Entity.Status.ID ) { super.init( - context: context, authenticationBox: authenticationBox, optionalRoot: nil ) @@ -36,12 +34,10 @@ final class RemoteThreadViewModel: ThreadViewModel { } init( - context: AppContext, authenticationBox: MastodonAuthenticationBox, notificationID: Mastodon.Entity.Notification.ID ) { super.init( - context: context, authenticationBox: authenticationBox, optionalRoot: nil ) diff --git a/Mastodon/Scene/Thread/ThreadViewController.swift b/Mastodon/Scene/Thread/ThreadViewController.swift index bea87d9b3..42aea18e3 100644 --- a/Mastodon/Scene/Thread/ThreadViewController.swift +++ b/Mastodon/Scene/Thread/ThreadViewController.swift @@ -16,10 +16,7 @@ import MastodonUI import MastodonLocalization import MastodonSDK -final class ThreadViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } +final class ThreadViewController: UIViewController, MediaPreviewableViewController { var disposeBag = Set() var viewModel: ThreadViewModel! @@ -115,12 +112,11 @@ extension ThreadViewController { @objc private func replyBarButtonItemPressed(_ sender: UIBarButtonItem) { guard case let .root(threadContext) = viewModel.root else { return } let composeViewModel = ComposeViewModel( - context: context, authenticationBox: viewModel.authenticationBox, composeContext: .composeStatus, destination: .reply(parent: threadContext.status) ) - _ = coordinator.present( + _ = self.sceneCoordinator?.present( scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil) diff --git a/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift b/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift index 1c50ef442..2d6a28c85 100644 --- a/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift +++ b/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift @@ -22,9 +22,7 @@ extension ThreadViewModel { ) { diffableDataSource = StatusSection.diffableDataSource( tableView: tableView, - context: context, configuration: StatusSection.Configuration( - context: context, authenticationBox: authenticationBox, statusTableViewCellDelegate: statusTableViewCellDelegate, timelineMiddleLoaderTableViewCellDelegate: nil, diff --git a/Mastodon/Scene/Thread/ThreadViewModel.swift b/Mastodon/Scene/Thread/ThreadViewModel.swift index 54a2698e4..fe0118f17 100644 --- a/Mastodon/Scene/Thread/ThreadViewModel.swift +++ b/Mastodon/Scene/Thread/ThreadViewModel.swift @@ -23,7 +23,6 @@ class ThreadViewModel { var rootItemObserver: AnyCancellable? // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox let mastodonStatusThreadViewModel: MastodonStatusThreadViewModel @@ -50,14 +49,12 @@ class ThreadViewModel { @Published var navigationBarTitle: MastodonMetaContent? init( - context: AppContext, authenticationBox: MastodonAuthenticationBox, optionalRoot: StatusItem.Thread? ) { - self.context = context self.authenticationBox = authenticationBox self.root = optionalRoot - self.mastodonStatusThreadViewModel = MastodonStatusThreadViewModel(context: context, filterContext: .thread) + self.mastodonStatusThreadViewModel = MastodonStatusThreadViewModel(filterContext: .thread) // end init $root diff --git a/Mastodon/Supporting Files/SceneDelegate.swift b/Mastodon/Supporting Files/SceneDelegate.swift index bf9f07c1d..8d48f63f8 100644 --- a/Mastodon/Supporting Files/SceneDelegate.swift +++ b/Mastodon/Supporting Files/SceneDelegate.swift @@ -14,6 +14,19 @@ import MastodonUI import MastodonSDK class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + static private var delegates = [ ObjectIdentifier : SceneDelegate ]() + + static func assign(delegate: SceneDelegate, to windowScene: UIWindowScene) { + delegates[ObjectIdentifier(windowScene)] = delegate + } + + static func delegate(for view: UIView) -> SceneDelegate? { + guard let windowScene = view.window?.windowScene else { + return nil + } + return delegates[ObjectIdentifier(windowScene)] + } var disposeBag = Set() var observations = Set() @@ -46,6 +59,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { self.coordinator = sceneCoordinator sceneCoordinator.setup() + + SceneDelegate.assign(delegate: self, to: windowScene) + window.makeKeyAndVisible() if let urlContext = connectionOptions.urlContexts.first { @@ -170,7 +186,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { guard let statusOnMyInstance = try await APIService.shared.search(query: .init(q: incomingURL.absoluteString, resolve: true), authenticationBox: authenticationBox).value.statuses.first else { return } let threadViewModel = RemoteThreadViewModel( - context: AppContext.shared, authenticationBox: authenticationBox, statusID: statusOnMyInstance.id ) @@ -248,7 +263,6 @@ extension SceneDelegate { } else { if let authenticationBox = coordinator?.authenticationBox { let composeViewModel = ComposeViewModel( - context: AppContext.shared, authenticationBox: authenticationBox, composeContext: .composeStatus, destination: .topLevel @@ -321,7 +335,6 @@ extension SceneDelegate { let statusId = components[1] // View post from user let threadViewModel = RemoteThreadViewModel( - context: AppContext.shared, authenticationBox: authenticationBox, statusID: statusId ) diff --git a/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift b/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift index c7d3b124b..6ace64d5c 100644 --- a/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift +++ b/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift @@ -11,14 +11,12 @@ final public class FeedDataController { @Published public var records: [MastodonFeed] = [] - private let context: AppContext private let authenticationBox: MastodonAuthenticationBox private let kind: MastodonFeed.Kind private var subscriptions = Set() - public init(context: AppContext, authenticationBox: MastodonAuthenticationBox, kind: MastodonFeed.Kind) { - self.context = context + public init(authenticationBox: MastodonAuthenticationBox, kind: MastodonFeed.Kind) { self.authenticationBox = authenticationBox self.kind = kind diff --git a/MastodonSDK/Sources/MastodonUI/DataSource/CustomEmojiPickerSection+Diffable.swift b/MastodonSDK/Sources/MastodonUI/DataSource/CustomEmojiPickerSection+Diffable.swift index 27a7d466f..5b4717047 100644 --- a/MastodonSDK/Sources/MastodonUI/DataSource/CustomEmojiPickerSection+Diffable.swift +++ b/MastodonSDK/Sources/MastodonUI/DataSource/CustomEmojiPickerSection+Diffable.swift @@ -11,11 +11,9 @@ import MastodonCore extension CustomEmojiPickerSection { static func collectionViewDiffableDataSource( collectionView: UICollectionView, - authenticationBox: MastodonAuthenticationBox, - context: AppContext + authenticationBox: MastodonAuthenticationBox ) -> UICollectionViewDiffableDataSource { - let dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { [weak context] collectionView, indexPath, item -> UICollectionViewCell? in - guard let _ = context else { return nil } + let dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, item -> UICollectionViewCell? in switch item { case .emoji(let attribute): let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: CustomEmojiPickerItemCollectionViewCell.self), for: indexPath) as! CustomEmojiPickerItemCollectionViewCell diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/AutoComplete/AutoCompleteViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/AutoComplete/AutoCompleteViewModel.swift index fd8a2b905..44798f4f0 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/AutoComplete/AutoCompleteViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/AutoComplete/AutoCompleteViewModel.swift @@ -17,7 +17,6 @@ final class AutoCompleteViewModel { var disposeBag = Set() // input - let context: AppContext let authenticationBox: MastodonAuthenticationBox public let inputText = CurrentValueSubject("") // contains "@" or "#" prefix public let symbolBoundingRect = CurrentValueSubject(.zero) @@ -38,8 +37,7 @@ final class AutoCompleteViewModel { return stateMachine }() - init(context: AppContext, authenticationBox: MastodonAuthenticationBox) { - self.context = context + init(authenticationBox: MastodonAuthenticationBox) { self.authenticationBox = authenticationBox self.customEmojiViewModel = EmojiService.shared.dequeueCustomEmojiViewModel(for: authenticationBox.domain) // end init diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift index e36baeff5..11b5f5f0d 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift @@ -33,7 +33,7 @@ public final class ComposeContentViewController: UIViewController { // auto complete private(set) lazy var autoCompleteViewController: AutoCompleteViewController = { let viewController = AutoCompleteViewController() - viewController.viewModel = AutoCompleteViewModel(context: viewModel.context, authenticationBox: viewModel.authenticationBox) + viewController.viewModel = AutoCompleteViewModel(authenticationBox: viewModel.authenticationBox) viewController.delegate = self // viewController.viewModel.customEmojiViewModel.value = viewModel.customEmojiViewModel return viewController diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift index 0e2ee5856..f3ebd7785 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift @@ -99,8 +99,7 @@ extension ComposeContentViewModel { ) { let diffableDataSource = CustomEmojiPickerSection.collectionViewDiffableDataSource( collectionView: collectionView, - authenticationBox: authenticationBox, - context: context + authenticationBox: authenticationBox ) self.customEmojiPickerDiffableDataSource = diffableDataSource diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift index f993c5eff..e2bb267f2 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift @@ -33,7 +33,6 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { let composeContentTableViewCell = ComposeContentTableViewCell() // input - let context: AppContext let composeContext: ComposeContext let destination: Destination weak var delegate: ComposeContentViewModelDelegate? @@ -143,13 +142,11 @@ public final class ComposeContentViewModel: NSObject, ObservableObject { } public init( - context: AppContext, authenticationBox: MastodonAuthenticationBox, composeContext: ComposeContext, destination: Destination, initialContent: String ) { - self.context = context self.authenticationBox = authenticationBox self.destination = destination self.composeContext = composeContext diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index d67c2c3e1..45dcda856 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -25,7 +25,6 @@ extension StatusView { public var objects = Set() public var managedObjects = Set() - public var context: AppContext? public var authenticationBox: MastodonAuthenticationBox? public var originalStatus: MastodonStatus? { didSet { @@ -601,7 +600,7 @@ extension StatusView.ViewModel { let (isBookmark, isFavorite, isBoosted) = tupleTwo let (translatedFromLanguage, language) = tupleThree - guard let name = authorName?.string, let authorId = authorId, let context = self.context, let authenticationBox = self.authenticationBox else { + guard let name = authorName?.string, let authorId = authorId, let authenticationBox = self.authenticationBox else { statusView.authorView.menuButton.menu = nil return } diff --git a/ShareActionExtension/Scene/ShareViewController.swift b/ShareActionExtension/Scene/ShareViewController.swift index 1010204ce..93cd4b274 100644 --- a/ShareActionExtension/Scene/ShareViewController.swift +++ b/ShareActionExtension/Scene/ShareViewController.swift @@ -85,7 +85,6 @@ extension ShareViewController { } viewModel.authenticationBox = authenticationBox let composeContentViewModel = ComposeContentViewModel( - context: context, authenticationBox: authenticationBox, composeContext: .composeStatus, destination: .topLevel,