From 11bab5e337db4d388de89a7c7c5e6a37cf1e9021 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 22 May 2023 16:14:06 +0200 Subject: [PATCH] Make button-state work (IOS-157) Reason for button-state not working/updating feels like to be a weird combination of Combine, UIKit, Snapshots, CoreData and me being stupid and not getting a hang on it. --- Mastodon.xcodeproj/project.pbxproj | 4 -- .../RecommendAccountSection.swift | 11 +++-- .../SuggestionAccountViewModel+Diffable.swift | 41 ------------------- .../SuggestionAccountViewModel.swift | 31 +++++++++++++- ...estionAccountTableViewCell+ViewModel.swift | 8 ++-- .../SuggestionAccountTableViewCell.swift | 34 +++++---------- 6 files changed, 50 insertions(+), 79 deletions(-) delete mode 100644 Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel+Diffable.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index ed6afbc58..7179d5f87 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -415,7 +415,6 @@ DBB45B5927B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5827B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift */; }; DBB45B5B27B3A109002DC5A7 /* MediaPreviewTransitionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5A27B3A109002DC5A7 /* MediaPreviewTransitionViewController.swift */; }; DBB45B6027B50A4F002DC5A7 /* RecommendAccountItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5F27B50A4F002DC5A7 /* RecommendAccountItem.swift */; }; - DBB45B6227B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B6127B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift */; }; DBB525212611EBD6002F1F29 /* ProfilePagingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB525202611EBD6002F1F29 /* ProfilePagingViewController.swift */; }; DBB525302611EBF3002F1F29 /* ProfilePagingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB5252F2611EBF3002F1F29 /* ProfilePagingViewModel.swift */; }; DBB525362611ECEB002F1F29 /* UserTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB525352611ECEB002F1F29 /* UserTimelineViewController.swift */; }; @@ -1132,7 +1131,6 @@ DBB45B5827B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPreviewVideoViewModel.swift; sourceTree = ""; }; DBB45B5A27B3A109002DC5A7 /* MediaPreviewTransitionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPreviewTransitionViewController.swift; sourceTree = ""; }; DBB45B5F27B50A4F002DC5A7 /* RecommendAccountItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendAccountItem.swift; sourceTree = ""; }; - DBB45B6127B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SuggestionAccountViewModel+Diffable.swift"; sourceTree = ""; }; DBB525202611EBD6002F1F29 /* ProfilePagingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePagingViewController.swift; sourceTree = ""; }; DBB5252F2611EBF3002F1F29 /* ProfilePagingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePagingViewModel.swift; sourceTree = ""; }; DBB525352611ECEB002F1F29 /* UserTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserTimelineViewController.swift; sourceTree = ""; }; @@ -1673,7 +1671,6 @@ DBB45B5F27B50A4F002DC5A7 /* RecommendAccountItem.swift */, 2DAC9E37262FC2320062E1A6 /* SuggestionAccountViewController.swift */, 2DAC9E3D262FC2400062E1A6 /* SuggestionAccountViewModel.swift */, - DBB45B6127B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift */, 2DAC9E43262FC9DE0062E1A6 /* TableView-Components */, ); path = SuggestionAccount; @@ -3602,7 +3599,6 @@ DBDFF1952805561700557A48 /* DiscoveryPostsViewModel+Diffable.swift in Sources */, DB03A795272A981400EE37C5 /* ContentSplitViewController.swift in Sources */, DBDFF19C28055BD600557A48 /* DiscoveryViewModel.swift in Sources */, - DBB45B6227B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift in Sources */, DBB3BA2A26A81C020004F2D4 /* FLAnimatedImageView.swift in Sources */, DB3E6FF32806D97400B035AE /* DiscoveryNewsViewModel+State.swift in Sources */, DB6746ED278F45F0008A6B94 /* AutoGenerateProtocolRelayDelegate.swift in Sources */, diff --git a/Mastodon/Scene/SuggestionAccount/RecommendAccountSection.swift b/Mastodon/Scene/SuggestionAccount/RecommendAccountSection.swift index 70c2a5077..c3f477a96 100644 --- a/Mastodon/Scene/SuggestionAccount/RecommendAccountSection.swift +++ b/Mastodon/Scene/SuggestionAccount/RecommendAccountSection.swift @@ -39,14 +39,13 @@ extension RecommendAccountSection { context.managedObjectContext.performAndWait { guard let user = record.object(in: context.managedObjectContext) else { return } cell.configure(viewModel: - SuggestionAccountTableViewCell.ViewModel(user: user, - followedUsers: configuration.authContext.mastodonAuthenticationBox.inMemoryCache.$followingUserIds.eraseToAnyPublisher(), - blockedUsers: configuration.authContext.mastodonAuthenticationBox.inMemoryCache.$blockedUserIds.eraseToAnyPublisher(), - followRequestedUsers: configuration.authContext.mastodonAuthenticationBox.inMemoryCache.$followRequestedUserIDs.eraseToAnyPublisher()) + SuggestionAccountTableViewCell.ViewModel( + user: user, + followedUsers: configuration.authContext.mastodonAuthenticationBox.inMemoryCache.followingUserIds, + blockedUsers: configuration.authContext.mastodonAuthenticationBox.inMemoryCache.blockedUserIds, + followRequestedUsers: configuration.authContext.mastodonAuthenticationBox.inMemoryCache.followRequestedUserIDs) ) } - - } return cell } diff --git a/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel+Diffable.swift b/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel+Diffable.swift deleted file mode 100644 index b90240d66..000000000 --- a/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel+Diffable.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// SuggestionAccountViewModel+Diffable.swift -// Mastodon -// -// Created by MainasuK on 2022-2-10. -// - -import UIKit - -extension SuggestionAccountViewModel { - - func setupDiffableDataSource( - tableView: UITableView, - suggestionAccountTableViewCellDelegate: SuggestionAccountTableViewCellDelegate - ) { - tableViewDiffableDataSource = RecommendAccountSection.tableViewDiffableDataSource( - tableView: tableView, - context: context, - configuration: RecommendAccountSection.Configuration( - authContext: authContext, - suggestionAccountTableViewCellDelegate: suggestionAccountTableViewCellDelegate - ) - ) - - userFetchedResultsController.$records - .removeDuplicates() - .receive(on: DispatchQueue.main) - .sink { [weak self] records in - guard let self = self else { return } - guard let tableViewDiffableDataSource = self.tableViewDiffableDataSource else { return } - - var snapshot = NSDiffableDataSourceSnapshot() - snapshot.appendSections([.main]) - let items: [RecommendAccountItem] = records.map { RecommendAccountItem.account($0) } - snapshot.appendItems(items, toSection: .main) - - tableViewDiffableDataSource.applySnapshotUsingReloadData(snapshot, completion: nil) - } - .store(in: &disposeBag) - } -} diff --git a/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel.swift b/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel.swift index 64ab6189b..038ee887d 100644 --- a/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel.swift +++ b/Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel.swift @@ -85,7 +85,36 @@ final class SuggestionAccountViewModel: NSObject { .store(in: &disposeBag) } - func followAllSuggestedAccounts(_ dependency: NeedsDependency & AuthContextProvider ) { + func setupDiffableDataSource( + tableView: UITableView, + suggestionAccountTableViewCellDelegate: SuggestionAccountTableViewCellDelegate + ) { + tableViewDiffableDataSource = RecommendAccountSection.tableViewDiffableDataSource( + tableView: tableView, + context: context, + configuration: RecommendAccountSection.Configuration( + authContext: authContext, + suggestionAccountTableViewCellDelegate: suggestionAccountTableViewCellDelegate + ) + ) + + userFetchedResultsController.$records + .receive(on: DispatchQueue.main) + .sink { [weak self] records in + guard let self = self else { return } + guard let tableViewDiffableDataSource = self.tableViewDiffableDataSource else { return } + + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main]) + let items: [RecommendAccountItem] = records.map { RecommendAccountItem.account($0) } + snapshot.appendItems(items, toSection: .main) + + tableViewDiffableDataSource.applySnapshotUsingReloadData(snapshot) + } + .store(in: &disposeBag) + } + + func followAllSuggestedAccounts(_ dependency: NeedsDependency & AuthContextProvider) { let userRecords = userFetchedResultsController.records.compactMap { $0.object(in: dependency.context.managedObjectContext)?.asRecord diff --git a/Mastodon/Scene/SuggestionAccount/TableView-Components/SuggestionAccountTableViewCell+ViewModel.swift b/Mastodon/Scene/SuggestionAccount/TableView-Components/SuggestionAccountTableViewCell+ViewModel.swift index 937cb2262..1b4fcb34c 100644 --- a/Mastodon/Scene/SuggestionAccount/TableView-Components/SuggestionAccountTableViewCell+ViewModel.swift +++ b/Mastodon/Scene/SuggestionAccount/TableView-Components/SuggestionAccountTableViewCell+ViewModel.swift @@ -8,11 +8,11 @@ extension SuggestionAccountTableViewCell { final class ViewModel { let user: MastodonUser - let followedUsers: AnyPublisher<[String], Never> - let blockedUsers: AnyPublisher<[String], Never> - let followRequestedUsers: AnyPublisher<[String], Never> + let followedUsers: [String] + let blockedUsers: [String] + let followRequestedUsers: [String] - init(user: MastodonUser, followedUsers: AnyPublisher<[String], Never>, blockedUsers: AnyPublisher<[String], Never>, followRequestedUsers: AnyPublisher<[String], Never>) { + init(user: MastodonUser, followedUsers: [String], blockedUsers: [String], followRequestedUsers: [String]) { self.user = user self.followedUsers = followedUsers self.followRequestedUsers = followRequestedUsers diff --git a/Mastodon/Scene/SuggestionAccount/TableView-Components/SuggestionAccountTableViewCell.swift b/Mastodon/Scene/SuggestionAccount/TableView-Components/SuggestionAccountTableViewCell.swift index 3c0e334b9..a1c78eca6 100644 --- a/Mastodon/Scene/SuggestionAccount/TableView-Components/SuggestionAccountTableViewCell.swift +++ b/Mastodon/Scene/SuggestionAccount/TableView-Components/SuggestionAccountTableViewCell.swift @@ -82,30 +82,18 @@ final class SuggestionAccountTableViewCell: UITableViewCell { func configure(viewModel: SuggestionAccountTableViewCell.ViewModel) { userView.configure(user: viewModel.user, delegate: delegate) - Publishers.CombineLatest3( - viewModel.followedUsers, - viewModel.followRequestedUsers, - viewModel.blockedUsers - ) - .receive(on: DispatchQueue.main) - .sink { [weak self] followed, requested, blocked in - - guard let self else { return } - - if blocked.contains(viewModel.user.id) { - self.userView.setButtonState(.blocked) - } else if followed.contains(viewModel.user.id) { - self.userView.setButtonState(.unfollow) - } else if requested.contains(viewModel.user.id) { - self.userView.setButtonState(.pending) - } else if viewModel.user.locked { - self.userView.setButtonState(.request) - } else { - self.userView.setButtonState(.follow) - } + if viewModel.blockedUsers.contains(viewModel.user.id) { + self.userView.setButtonState(.blocked) + } else if viewModel.followedUsers.contains(viewModel.user.id) { + self.userView.setButtonState(.unfollow) + } else if viewModel.followRequestedUsers.contains(viewModel.user.id) { + self.userView.setButtonState(.pending) + } else if viewModel.user.locked { + self.userView.setButtonState(.request) + } else { + self.userView.setButtonState(.follow) } - .store(in: &disposeBag) - + let metaContent: MetaContent = { do { let mastodonContent = MastodonContent(content: viewModel.user.note ?? "", emojis: viewModel.user.emojis.asDictionary)