Migrate UserList to use Accounts (IOS-192)
This commit is contained in:
parent
f51d5b7fe2
commit
3abb80a5df
|
@ -7,8 +7,6 @@
|
|||
|
||||
import Foundation
|
||||
import Combine
|
||||
import CoreData
|
||||
import CoreDataStack
|
||||
import GameplayKit
|
||||
import MastodonSDK
|
||||
import MastodonCore
|
||||
|
|
|
@ -21,10 +21,10 @@ extension FavoritedByViewController: DataSourceProvider {
|
|||
}
|
||||
|
||||
switch item {
|
||||
case .user(let record):
|
||||
return .user(record: record)
|
||||
default:
|
||||
return nil
|
||||
case .user(_), .bottomHeader(_), .bottomLoader:
|
||||
return nil
|
||||
case .account(let account, let relationship):
|
||||
return .account(account: account, relationship: relationship)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,12 +20,12 @@ extension RebloggedByViewController: DataSourceProvider {
|
|||
guard let item = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
switch item {
|
||||
case .user(let record):
|
||||
return .user(record: record)
|
||||
default:
|
||||
return nil
|
||||
case .user(_), .bottomHeader(_), .bottomLoader:
|
||||
return nil
|
||||
case .account(let account, let relationship):
|
||||
return .account(account: account, relationship: relationship)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import UIKit
|
|||
import MastodonAsset
|
||||
import MastodonLocalization
|
||||
import Combine
|
||||
import MastodonSDK
|
||||
|
||||
extension UserListViewModel {
|
||||
@MainActor
|
||||
|
@ -33,15 +34,23 @@ extension UserListViewModel {
|
|||
// trigger initial loading
|
||||
stateMachine.enter(UserListViewModel.State.Reloading.self)
|
||||
|
||||
userFetchedResultsController.$records
|
||||
$accounts
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] records in
|
||||
.sink { [weak self] accounts in
|
||||
guard let self = self else { return }
|
||||
guard let diffableDataSource = self.diffableDataSource else { return }
|
||||
|
||||
var snapshot = NSDiffableDataSourceSnapshot<UserSection, UserItem>()
|
||||
|
||||
snapshot.appendSections([.main])
|
||||
let items = records.map { UserItem.user(record: $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 {
|
||||
|
|
|
@ -30,7 +30,7 @@ extension UserListViewModel {
|
|||
extension UserListViewModel.State {
|
||||
class Initial: UserListViewModel.State {
|
||||
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
|
||||
guard let _ = viewModel else { return false }
|
||||
guard viewModel != nil else { return false }
|
||||
switch stateClass {
|
||||
case is Reloading.Type:
|
||||
return true
|
||||
|
@ -52,10 +52,10 @@ extension UserListViewModel.State {
|
|||
|
||||
override func didEnter(from previousState: GKState?) {
|
||||
super.didEnter(from: previousState)
|
||||
guard let viewModel = viewModel, let stateMachine = stateMachine else { return }
|
||||
guard let viewModel, let stateMachine else { return }
|
||||
|
||||
// reset
|
||||
viewModel.userFetchedResultsController.userIDs = []
|
||||
viewModel.accounts = []
|
||||
|
||||
stateMachine.enter(Loading.self)
|
||||
}
|
||||
|
@ -74,8 +74,8 @@ extension UserListViewModel.State {
|
|||
|
||||
override func didEnter(from previousState: GKState?) {
|
||||
super.didEnter(from: previousState)
|
||||
guard let _ = viewModel, let stateMachine = stateMachine else { return }
|
||||
|
||||
guard viewModel != nil, let stateMachine else { return }
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
|
||||
stateMachine.enter(Loading.self)
|
||||
}
|
||||
|
@ -117,10 +117,11 @@ extension UserListViewModel.State {
|
|||
maxID = nil
|
||||
}
|
||||
|
||||
guard let viewModel = viewModel else { return }
|
||||
guard let viewModel else { return }
|
||||
|
||||
let maxID = self.maxID
|
||||
|
||||
let authenticationBox = viewModel.authContext.mastodonAuthenticationBox
|
||||
|
||||
Task {
|
||||
do {
|
||||
let response: Mastodon.Response.Content<[Mastodon.Entity.Account]>
|
||||
|
@ -129,24 +130,45 @@ extension UserListViewModel.State {
|
|||
response = try await viewModel.context.apiService.favoritedBy(
|
||||
status: status,
|
||||
query: .init(maxID: maxID, limit: nil),
|
||||
authenticationBox: viewModel.authContext.mastodonAuthenticationBox
|
||||
authenticationBox: authenticationBox
|
||||
)
|
||||
case .rebloggedBy(let status):
|
||||
response = try await viewModel.context.apiService.rebloggedBy(
|
||||
status: status,
|
||||
query: .init(maxID: maxID, limit: nil),
|
||||
authenticationBox: viewModel.authContext.mastodonAuthenticationBox
|
||||
authenticationBox: authenticationBox
|
||||
)
|
||||
}
|
||||
|
||||
if response.value.isEmpty {
|
||||
await enter(state: NoMore.self)
|
||||
|
||||
viewModel.accounts = []
|
||||
viewModel.relationships = []
|
||||
return
|
||||
}
|
||||
|
||||
let newRelationships = try await viewModel.context.apiService.relationship(
|
||||
forAccounts: response.value,
|
||||
authenticationBox: authenticationBox
|
||||
)
|
||||
|
||||
var hasNewAppend = false
|
||||
var userIDs = viewModel.userFetchedResultsController.userIDs
|
||||
for user in response.value {
|
||||
guard !userIDs.contains(user.id) else { continue }
|
||||
userIDs.append(user.id)
|
||||
var accounts = viewModel.accounts
|
||||
for account in response.value {
|
||||
guard !accounts.contains(account) else { continue }
|
||||
|
||||
accounts.append(account)
|
||||
hasNewAppend = true
|
||||
}
|
||||
|
||||
|
||||
var relationships = viewModel.relationships
|
||||
|
||||
for relationship in newRelationships.value {
|
||||
guard relationships.contains(relationship) == false else { continue }
|
||||
relationships.append(relationship)
|
||||
}
|
||||
|
||||
let maxID = response.link?.maxID
|
||||
|
||||
if hasNewAppend, maxID != nil {
|
||||
|
@ -155,8 +177,9 @@ extension UserListViewModel.State {
|
|||
await enter(state: NoMore.self)
|
||||
}
|
||||
self.maxID = maxID
|
||||
viewModel.userFetchedResultsController.userIDs = userIDs
|
||||
|
||||
viewModel.relationships = relationships
|
||||
viewModel.accounts = accounts
|
||||
|
||||
} catch {
|
||||
await enter(state: Fail.self)
|
||||
}
|
||||
|
@ -177,9 +200,9 @@ extension UserListViewModel.State {
|
|||
override func didEnter(from previousState: GKState?) {
|
||||
super.didEnter(from: previousState)
|
||||
|
||||
guard let viewModel = viewModel else { return }
|
||||
guard let viewModel else { return }
|
||||
// trigger reload
|
||||
viewModel.userFetchedResultsController.userIDs = viewModel.userFetchedResultsController.userIDs
|
||||
viewModel.accounts = viewModel.accounts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ final class UserListViewModel {
|
|||
let context: AppContext
|
||||
let authContext: AuthContext
|
||||
let kind: Kind
|
||||
let userFetchedResultsController: UserFetchedResultsController
|
||||
@Published var accounts: [Mastodon.Entity.Account]
|
||||
@Published var relationships: [Mastodon.Entity.Relationship]
|
||||
let listBatchFetchViewModel = ListBatchFetchViewModel()
|
||||
|
||||
// output
|
||||
|
@ -44,12 +45,8 @@ final class UserListViewModel {
|
|||
self.context = context
|
||||
self.authContext = authContext
|
||||
self.kind = kind
|
||||
self.userFetchedResultsController = UserFetchedResultsController(
|
||||
managedObjectContext: context.managedObjectContext,
|
||||
domain: authContext.mastodonAuthenticationBox.domain,
|
||||
additionalPredicate: nil
|
||||
)
|
||||
// end init
|
||||
self.accounts = []
|
||||
self.relationships = []
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue