fix: refresh block state when view will appear

This commit is contained in:
sunxiaojian 2021-04-23 10:25:08 +08:00
parent 67f813a946
commit 61a26fbe66
3 changed files with 47 additions and 28 deletions

View File

@ -40,7 +40,7 @@ extension RecommendAccountSection {
guard let viewModel = viewModel else { return nil }
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SuggestionAccountTableViewCell.self)) as! SuggestionAccountTableViewCell
let user = managedObjectContext.object(with: objectID) as! MastodonUser
let isSelected = viewModel.selectedAccounts.contains(objectID)
let isSelected = viewModel.selectedAccounts.value.contains(objectID)
cell.delegate = delegate
cell.config(with: user, isSelected: isSelected)
return cell

View File

@ -110,8 +110,7 @@ extension SuggestionAccountViewController {
super.viewWillLayoutSubviews()
let avatarImageViewHeight: Double = 56
let avatarImageViewCount = Int(floor((Double(view.frame.width) - 20) / (avatarImageViewHeight + 15)))
viewModel.headerPlaceholderCount = avatarImageViewCount
viewModel.applySelectedCollectionViewDataSource(accounts: [])
viewModel.headerPlaceholderCount.value = avatarImageViewCount
}
func setupHeader(accounts: [NSManagedObjectID]) {
@ -179,7 +178,7 @@ extension SuggestionAccountViewController: UITableViewDelegate {
extension SuggestionAccountViewController: SuggestionAccountTableViewCellDelegate {
func accountButtonPressed(objectID: NSManagedObjectID, cell: SuggestionAccountTableViewCell) {
let selected = !viewModel.selectedAccounts.contains(objectID)
let selected = !viewModel.selectedAccounts.value.contains(objectID)
cell.startAnimating()
viewModel.followAction(objectID: objectID)?
.sink(receiveCompletion: { [weak self] completion in
@ -189,13 +188,14 @@ extension SuggestionAccountViewController: SuggestionAccountTableViewCellDelegat
case .failure(let error):
os_log("%{public}s[%{public}ld], %{public}s: follow failed. %s", (#file as NSString).lastPathComponent, #line, #function, error.localizedDescription)
case .finished:
var selectedAccounts = self.viewModel.selectedAccounts.value
if selected {
self.viewModel.selectedAccounts.append(objectID)
selectedAccounts.append(objectID)
} else {
self.viewModel.selectedAccounts.removeAll { $0 == objectID }
selectedAccounts.removeAll { $0 == objectID }
}
cell.button.isSelected = selected
self.viewModel.selectedAccountsDidChange.send()
self.viewModel.selectedAccounts.value = selectedAccounts
}
}, receiveValue: { _ in
})
@ -206,7 +206,7 @@ extension SuggestionAccountViewController: SuggestionAccountTableViewCellDelegat
extension SuggestionAccountViewController {
@objc func doneButtonDidClick(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
if viewModel.selectedAccounts.count > 0 {
if viewModel.selectedAccounts.value.count > 0 {
viewModel.delegate?.homeTimelineNeedRefresh.send()
}
}

View File

@ -27,11 +27,13 @@ final class SuggestionAccountViewModel: NSObject {
weak var delegate: SuggestionAccountViewModelDelegate?
// output
let accounts = CurrentValueSubject<[NSManagedObjectID], Never>([])
var selectedAccounts = [NSManagedObjectID]()
let selectedAccountsDidChange = PassthroughSubject<Void, Never>()
var headerPlaceholderCount: Int?
var selectedAccounts = CurrentValueSubject<[NSManagedObjectID], Never>([])
var headerPlaceholderCount = CurrentValueSubject<Int?, Never>(nil)
var suggestionAccountsFallback = PassthroughSubject<Void, Never>()
var viewWillAppear = PassthroughSubject<Void, Never>()
var diffableDataSource: UITableViewDiffableDataSource<RecommendAccountSection, NSManagedObjectID>? {
didSet(value) {
if !accounts.value.isEmpty {
@ -47,11 +49,22 @@ final class SuggestionAccountViewModel: NSObject {
super.init()
self.accounts
.receive(on: DispatchQueue.main)
.sink { [weak self] accounts in
Publishers.CombineLatest(self.accounts,self.selectedAccounts)
.sink { [weak self] accounts,selectedAccounts in
self?.applyTableViewDataSource(accounts: accounts)
self?.applySelectedCollectionViewDataSource(accounts: [])
self?.applySelectedCollectionViewDataSource(accounts: selectedAccounts)
}
.store(in: &disposeBag)
Publishers.CombineLatest(self.selectedAccounts,self.headerPlaceholderCount)
.sink { [weak self] selectedAccount,count in
self?.applySelectedCollectionViewDataSource(accounts: selectedAccount)
}
.store(in: &disposeBag)
viewWillAppear
.sink { [weak self] _ in
self?.checkAccountsFollowState()
}
.store(in: &disposeBag)
@ -59,14 +72,6 @@ final class SuggestionAccountViewModel: NSObject {
self.accounts.value = accounts
}
selectedAccountsDidChange
.sink { [weak self] _ in
guard let self = self else { return }
self.applyTableViewDataSource(accounts: self.accounts.value)
self.applySelectedCollectionViewDataSource(accounts: self.selectedAccounts)
}
.store(in: &disposeBag)
context.authenticationService.activeMastodonAuthentication
.sink { [weak self] activeMastodonAuthentication in
guard let self = self else { return }
@ -136,7 +141,7 @@ final class SuggestionAccountViewModel: NSObject {
}
func applySelectedCollectionViewDataSource(accounts: [NSManagedObjectID]) {
guard let count = headerPlaceholderCount else { return }
guard let count = headerPlaceholderCount.value else { return }
guard let dataSource = collectionDiffableDataSource else { return }
var snapshot = NSDiffableDataSourceSnapshot<SelectedAccountSection, SelectedAccountItem>()
snapshot.appendSections([.main])
@ -192,12 +197,26 @@ final class SuggestionAccountViewModel: NSObject {
guard let currentMastodonUser = currentMastodonUser.value else {
return
}
let users = accounts.value.compactMap { context.managedObjectContext.object(with: $0) as? MastodonUser }
let users: [MastodonUser] = accounts.value.compactMap {
guard let user = context.managedObjectContext.object(with: $0) as? MastodonUser else {
return nil
}
let isBlock = user.blockingBy.flatMap { $0.contains(currentMastodonUser) } ?? false
let isDomainBlock = user.domainBlockingBy.flatMap { $0.contains(currentMastodonUser) } ?? false
if isBlock || isDomainBlock {
return nil
} else {
return user
}
}
accounts.value = users.map(\.objectID)
let followingUsers = users.filter { user -> Bool in
let isFollowing = user.followingBy.flatMap { $0.contains(currentMastodonUser) } ?? false
return isFollowing
let isPending = user.followRequestedBy.flatMap { $0.contains(currentMastodonUser) } ?? false
return isFollowing || isPending
}.map(\.objectID)
selectedAccounts = followingUsers
selectedAccountsDidChange.send()
selectedAccounts.value = followingUsers
}
}