diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 58de81668..924225de8 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -293,7 +293,6 @@ DB4FFC2C269EC39600D62E92 /* SearchTransitionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4FFC2A269EC39600D62E92 /* SearchTransitionController.swift */; }; DB5B549A2833A60400DEF8B2 /* FamiliarFollowersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */; }; DB5B549D2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */; }; - DB5B549F2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */; }; DB5B54A12833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */; }; DB5B54A32833BD1A00DEF8B2 /* UserListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */; }; DB5B54A62833BE0000DEF8B2 /* UserListViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A52833BE0000DEF8B2 /* UserListViewModel+State.swift */; }; @@ -1005,7 +1004,6 @@ DB519B17281BCC2F00F0C99D /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Intents.stringsdict; sourceTree = ""; }; DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FamiliarFollowersViewController.swift; sourceTree = ""; }; DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FamiliarFollowersViewModel.swift; sourceTree = ""; }; - DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FamiliarFollowersViewModel+Diffable.swift"; sourceTree = ""; }; DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FamiliarFollowersViewController+DataSourceProvider.swift"; sourceTree = ""; }; DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserListViewModel.swift; sourceTree = ""; }; DB5B54A52833BE0000DEF8B2 /* UserListViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserListViewModel+State.swift"; sourceTree = ""; }; @@ -2288,7 +2286,6 @@ DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */, DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */, DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */, - DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */, ); path = FamiliarFollowers; sourceTree = ""; @@ -3718,7 +3715,6 @@ 0FAA101C25E10E760017CCDE /* UIFont.swift in Sources */, 2D38F1D525CD465300561493 /* HomeTimelineViewController.swift in Sources */, DB6180E926391BDF0018D199 /* MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift in Sources */, - DB5B549F2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift in Sources */, DB6B351E2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift in Sources */, DB8F7076279E954700E1225B /* DataSourceFacade+Follow.swift in Sources */, DB63F7542799491600455B82 /* DataSourceFacade+SearchHistory.swift in Sources */, diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index ef15ce6e4..4a01c4ea5 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -462,9 +462,7 @@ private extension SceneCoordinator { let followingListViewController = FollowingListViewController(viewModel: viewModel, coordinator: self, context: appContext) viewController = followingListViewController case .familiarFollowers(let viewModel): - let _viewController = FamiliarFollowersViewController() - _viewController.viewModel = viewModel - viewController = _viewController + viewController = FamiliarFollowersViewController(viewModel: viewModel, context: appContext, coordinator: self) case .rebloggedBy(let viewModel): let _viewController = RebloggedByViewController() _viewController.viewModel = viewModel diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift index 4d43e319a..a6b6720af 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift @@ -143,8 +143,8 @@ extension DiscoveryForYouViewController: ProfileCardTableViewCellDelegate { return } - let familiarFollowersViewModel = FamiliarFollowersViewModel(context: context, authContext: authContext) - familiarFollowersViewModel.familiarFollowers = familiarFollowers + let familiarFollowersViewModel = FamiliarFollowersViewModel(context: context, authContext: authContext, accounts: viewModel.accounts, relationships: viewModel.relationships) + _ = coordinator.present( scene: .familiarFollowers(viewModel: familiarFollowersViewModel), from: self, diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift index 4f0f730f4..0f118d0cf 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift @@ -23,7 +23,7 @@ final class DiscoveryForYouViewModel { @Published var familiarFollowers: [Mastodon.Entity.FamiliarFollowers] = [] @Published var isFetching = false @Published var accounts: [Mastodon.Entity.Account] - var relationships: [Mastodon.Entity.Relationship?] + var relationships: [Mastodon.Entity.Relationship] // output var diffableDataSource: UITableViewDiffableDataSource? @@ -72,7 +72,7 @@ extension DiscoveryForYouViewModel { snapshot.appendSections([.forYou]) let items = self.accounts.map { account in - let relationship = relationships.first { $0?.id == account.id } ?? nil + let relationship = relationships.first { $0.id == account.id } ?? nil return DiscoveryItem.account(account, relationship: relationship) } diff --git a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift index 59de6d880..cae1cc741 100644 --- a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift +++ b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift @@ -14,36 +14,34 @@ import CoreDataStack final class FamiliarFollowersViewController: UIViewController, NeedsDependency { - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } - weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - + weak var context: AppContext! + weak var coordinator: SceneCoordinator! + var disposeBag = Set() - var viewModel: FamiliarFollowersViewModel! + var viewModel: FamiliarFollowersViewModel - lazy var tableView: UITableView = { - let tableView = UITableView() + let tableView: UITableView + + init(viewModel: FamiliarFollowersViewModel, context: AppContext, coordinator: SceneCoordinator) { + self.viewModel = viewModel + self.context = context + self.coordinator = coordinator + + tableView = UITableView() tableView.rowHeight = UITableView.automaticDimension tableView.separatorStyle = .none tableView.backgroundColor = .clear - return tableView - }() - - -} -extension FamiliarFollowersViewController { - - override func viewDidLoad() { - super.viewDidLoad() - + super.init(nibName: nil, bundle: nil) + title = L10n.Scene.Familiarfollowers.title - + view.backgroundColor = .secondarySystemBackground - + tableView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(tableView) tableView.pinToParent() - + tableView.delegate = self viewModel.setupDiffableDataSource( tableView: tableView, @@ -51,10 +49,13 @@ extension FamiliarFollowersViewController { ) } + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) tableView.deselectRow(with: transitionCoordinator, animated: animated) + viewModel.viewWillAppear() } } diff --git a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel+Diffable.swift b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel+Diffable.swift deleted file mode 100644 index 291a6b3ff..000000000 --- a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel+Diffable.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// FamiliarFollowersViewModel+Diffable.swift -// Mastodon -// -// Created by MainasuK on 2022-5-17. -// - -import UIKit -import Combine - -extension FamiliarFollowersViewModel { - func setupDiffableDataSource( - tableView: UITableView, - userTableViewCellDelegate: UserTableViewCellDelegate? - ) { - diffableDataSource = UserSection.diffableDataSource( - tableView: tableView, - context: context, - authContext: authContext, - userTableViewCellDelegate: userTableViewCellDelegate - ) - - userFetchedResultsController.$records - .receive(on: DispatchQueue.main) - .sink { [weak self] records in - guard let self = self else { return } - guard let diffableDataSource = self.diffableDataSource else { return } - - var snapshot = NSDiffableDataSourceSnapshot() - snapshot.appendSections([.main]) - let items = records.map { UserItem.user(record: $0) } - snapshot.appendItems(items, toSection: .main) - - diffableDataSource.apply(snapshot, animatingDifferences: false) - } - .store(in: &disposeBag) - } - -} diff --git a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift index 3e4a17e5e..3b936deef 100644 --- a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift +++ b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift @@ -6,41 +6,54 @@ // import UIKit -import Combine import MastodonCore import MastodonSDK -import CoreDataStack final class FamiliarFollowersViewModel { - var disposeBag = Set() - - // input let context: AppContext let authContext: AuthContext - let userFetchedResultsController: UserFetchedResultsController - @Published var familiarFollowers: Mastodon.Entity.FamiliarFollowers? - + var accounts: [Mastodon.Entity.Account] + var relationships: [Mastodon.Entity.Relationship] + // output var diffableDataSource: UITableViewDiffableDataSource? - init(context: AppContext, authContext: AuthContext) { + init(context: AppContext, authContext: AuthContext, accounts: [Mastodon.Entity.Account], relationships: [Mastodon.Entity.Relationship]) { self.context = context self.authContext = authContext - self.userFetchedResultsController = UserFetchedResultsController( - managedObjectContext: context.managedObjectContext, - domain: authContext.mastodonAuthenticationBox.domain, - additionalPredicate: nil - ) - // end init - - $familiarFollowers - .map { familiarFollowers -> [MastodonUser.ID] in - guard let familiarFollowers = familiarFollowers else { return [] } - return familiarFollowers.accounts.map { $0.id } - } - .assign(to: \.userIDs, on: userFetchedResultsController) - .store(in: &disposeBag) + self.accounts = accounts + self.relationships = relationships + } + + func setupDiffableDataSource( + tableView: UITableView, + userTableViewCellDelegate: UserTableViewCellDelegate? + ) { + diffableDataSource = UserSection.diffableDataSource( + tableView: tableView, + context: context, + authContext: authContext, + userTableViewCellDelegate: userTableViewCellDelegate + ) + } + + func viewWillAppear() { + guard let diffableDataSource else { return } + + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main]) + let accountsWithRelationship: [(account: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?)] = accounts.compactMap { account in + guard let relationship = self.relationships.first(where: {$0.id == account.id }) else { return (account: account, relationship: nil)} + + return (account: account, relationship: relationship) + } + + let items = accountsWithRelationship.map { UserItem.account(account: $0.account, relationship: $0.relationship) } + + snapshot.appendItems(items, toSection: .main) + + diffableDataSource.apply(snapshot, animatingDifferences: false) + } - }