Don't Ddos servers for fetching each relatinoship individually
This commit is contained in:
parent
fa34df26df
commit
19d67d6dab
|
@ -12,7 +12,7 @@ import MastodonSDK
|
|||
|
||||
enum UserItem: Hashable {
|
||||
case user(record: ManagedObjectRecord<MastodonUser>)
|
||||
case account(account: Mastodon.Entity.Account)
|
||||
case account(account: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?)
|
||||
case bottomLoader
|
||||
case bottomHeader(text: String)
|
||||
}
|
||||
|
|
|
@ -31,39 +31,11 @@ extension UserSection {
|
|||
|
||||
return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in
|
||||
switch item {
|
||||
case .account(let account):
|
||||
case .account(let account, let relationship):
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: UserTableViewCell.self), for: indexPath) as! UserTableViewCell
|
||||
cell.configure(tableView: tableView, account: account, delegate: userTableViewCellDelegate)
|
||||
|
||||
cell.userView.setButtonState(.loading)
|
||||
Task {
|
||||
do {
|
||||
|
||||
guard let relationship = try await context.apiService.relationship(forAccounts: [account], authenticationBox: authContext.mastodonAuthenticationBox).value.first else {
|
||||
return await MainActor.run {
|
||||
cell.userView.setButtonState(.none)
|
||||
}
|
||||
}
|
||||
|
||||
let buttonState: UserView.ButtonState
|
||||
if relationship.following {
|
||||
buttonState = .unfollow
|
||||
} else if relationship.blocking || (relationship.domainBlocking ?? false) {
|
||||
buttonState = .blocked
|
||||
} else if relationship.requested ?? false {
|
||||
buttonState = .pending
|
||||
} else {
|
||||
buttonState = .follow
|
||||
}
|
||||
|
||||
await MainActor.run {
|
||||
cell.userView.setButtonState(buttonState)
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
cell.userView.setButtonState(.none)
|
||||
}
|
||||
}
|
||||
}
|
||||
cell.configure(tableView: tableView, account: account, relationship: relationship, delegate: userTableViewCellDelegate)
|
||||
|
||||
return cell
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import UIKit
|
|||
import MastodonAsset
|
||||
import MastodonCore
|
||||
import MastodonLocalization
|
||||
import MastodonSDK
|
||||
|
||||
extension FollowingListViewModel {
|
||||
func setupDiffableDataSource(
|
||||
|
@ -37,7 +38,14 @@ extension FollowingListViewModel {
|
|||
|
||||
var snapshot = NSDiffableDataSourceSnapshot<UserSection, UserItem>()
|
||||
snapshot.appendSections([.main])
|
||||
let items = accounts.map { UserItem.account(account: $0) }
|
||||
|
||||
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)
|
||||
|
||||
if let currentState = self.stateMachine.currentState {
|
||||
|
|
|
@ -126,24 +126,34 @@ extension FollowingListViewModel.State {
|
|||
|
||||
Task {
|
||||
do {
|
||||
let response = try await viewModel.context.apiService.following(
|
||||
let accountResponse = try await viewModel.context.apiService.following(
|
||||
userID: userID,
|
||||
maxID: maxID,
|
||||
authenticationBox: viewModel.authContext.mastodonAuthenticationBox
|
||||
)
|
||||
|
||||
|
||||
var hasNewAppend = false
|
||||
|
||||
|
||||
let newRelationships = try await viewModel.context.apiService.relationship(forAccounts: accountResponse.value, authenticationBox: viewModel.authContext.mastodonAuthenticationBox)
|
||||
|
||||
var accounts = viewModel.accounts
|
||||
|
||||
for user in response.value {
|
||||
|
||||
for user in accountResponse.value {
|
||||
guard accounts.contains(user) == false else { continue }
|
||||
accounts.append(user)
|
||||
hasNewAppend = true
|
||||
}
|
||||
|
||||
var relationships = viewModel.relationships
|
||||
|
||||
for relationship in newRelationships.value {
|
||||
guard relationships.contains(relationship) == false else { continue }
|
||||
relationships.append(relationship)
|
||||
}
|
||||
|
||||
let maxID = accountResponse.link?.maxID
|
||||
|
||||
let maxID = response.link?.maxID
|
||||
|
||||
if hasNewAppend, maxID != nil {
|
||||
await enter(state: Idle.self)
|
||||
} else {
|
||||
|
@ -151,6 +161,7 @@ extension FollowingListViewModel.State {
|
|||
}
|
||||
|
||||
viewModel.accounts = accounts
|
||||
viewModel.relationships = relationships
|
||||
self.maxID = maxID
|
||||
} catch {
|
||||
await enter(state: Fail.self)
|
||||
|
|
|
@ -21,6 +21,8 @@ final class FollowingListViewModel {
|
|||
let context: AppContext
|
||||
let authContext: AuthContext
|
||||
@Published var accounts: [Mastodon.Entity.Account]
|
||||
@Published var relationships: [Mastodon.Entity.Relationship]
|
||||
|
||||
let listBatchFetchViewModel: ListBatchFetchViewModel
|
||||
|
||||
@Published var domain: String?
|
||||
|
@ -52,6 +54,7 @@ final class FollowingListViewModel {
|
|||
self.domain = domain
|
||||
self.userID = userID
|
||||
self.accounts = []
|
||||
self.relationships = []
|
||||
self.listBatchFetchViewModel = ListBatchFetchViewModel()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,28 @@ extension UserTableViewCell {
|
|||
me: MastodonUser? = nil,
|
||||
tableView: UITableView,
|
||||
account: Mastodon.Entity.Account,
|
||||
relationship: Mastodon.Entity.Relationship?,
|
||||
delegate: UserTableViewCellDelegate?
|
||||
) {
|
||||
//TODO: Implement
|
||||
userView.configure(with: account)
|
||||
|
||||
let buttonState: UserView.ButtonState
|
||||
if let relationship {
|
||||
if relationship.following {
|
||||
buttonState = .unfollow
|
||||
} else if relationship.blocking || (relationship.domainBlocking ?? false) {
|
||||
buttonState = .blocked
|
||||
} else if relationship.requested ?? false {
|
||||
buttonState = .pending
|
||||
} else {
|
||||
buttonState = .follow
|
||||
}
|
||||
} else {
|
||||
buttonState = .none
|
||||
}
|
||||
|
||||
userView.setButtonState(buttonState)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ extension Mastodon.Entity {
|
|||
/// 2021/1/29
|
||||
/// # Reference
|
||||
/// [Document](https://docs.joinmastodon.org/entities/relationship/)
|
||||
public struct Relationship: Codable, Sendable {
|
||||
public struct Relationship: Codable, Sendable, Equatable, Hashable {
|
||||
public typealias ID = String
|
||||
|
||||
public let id: ID
|
||||
|
|
Loading…
Reference in New Issue