Skip to content

Commit

Permalink
Merge pull request mastodon#1196 from mastodon/ios-214-refactor-userlist
Browse files Browse the repository at this point in the history
Use accounts on FavoritedBy/RetootedBy-screens (IOS-214)
  • Loading branch information
zeitschlag authored Jan 3, 2024
2 parents 01eff2b + 695d317 commit 2119c9d
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 193 deletions.
6 changes: 3 additions & 3 deletions Mastodon.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2309,7 +2309,7 @@
path = FamiliarFollowers;
sourceTree = "<group>";
};
DB5B54A42833BD1D00DEF8B2 /* UserLIst */ = {
DB5B54A42833BD1D00DEF8B2 /* UserList */ = {
isa = PBXGroup;
children = (
DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */,
Expand All @@ -2318,7 +2318,7 @@
DB5B54A92833BFAC00DEF8B2 /* FavoritedBy */,
DB5B54AC2833C12D00DEF8B2 /* RebloggedBy */,
);
path = UserLIst;
path = UserList;
sourceTree = "<group>";
};
DB5B54A92833BFAC00DEF8B2 /* FavoritedBy */ = {
Expand Down Expand Up @@ -2778,7 +2778,7 @@
DB6B74F0272FB55400C70B6E /* Follower */,
DB5B7296273112B400081888 /* Following */,
DB5B549B2833A60600DEF8B2 /* FamiliarFollowers */,
DB5B54A42833BD1D00DEF8B2 /* UserLIst */,
DB5B54A42833BD1D00DEF8B2 /* UserList */,
DBFEEC97279BDC6A004F81DD /* About */,
DB9D6BFE25E4F5940051B173 /* ProfileViewController.swift */,
DBB5255D2611F07A002F1F29 /* ProfileViewModel.swift */,
Expand Down
1 change: 0 additions & 1 deletion Mastodon/Diffable/User/UserItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import CoreDataStack
import MastodonSDK

enum UserItem: Hashable {
case user(record: ManagedObjectRecord<MastodonUser>)
case account(account: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?)
case bottomLoader
case bottomHeader(text: String)
Expand Down
41 changes: 0 additions & 41 deletions Mastodon/Diffable/User/UserSection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,6 @@ extension UserSection {
delegate: userTableViewCellDelegate
)

return cell

case .user(let record):
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: UserTableViewCell.self), for: indexPath) as! UserTableViewCell
context.managedObjectContext.performAndWait {
guard let user = record.object(in: context.managedObjectContext) else { return }
configure(
context: context,
authContext: authContext,
tableView: tableView,
cell: cell,
viewModel: UserTableViewCell.ViewModel(
user: user,
followedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followingUserIds.eraseToAnyPublisher(),
blockedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$blockedUserIds.eraseToAnyPublisher(),
followRequestedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followRequestedUserIDs.eraseToAnyPublisher()
),
userTableViewCellDelegate: userTableViewCellDelegate
)
}

return cell
case .bottomLoader:
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self), for: indexPath) as! TimelineBottomLoaderTableViewCell
Expand All @@ -82,23 +61,3 @@ extension UserSection {
}
}
}

extension UserSection {

static func configure(
context: AppContext,
authContext: AuthContext,
tableView: UITableView,
cell: UserTableViewCell,
viewModel: UserTableViewCell.ViewModel,
userTableViewCellDelegate: UserTableViewCellDelegate?
) {
cell.configure(
me: authContext.mastodonAuthenticationBox.authentication.user(in: context.managedObjectContext),
tableView: tableView,
viewModel: viewModel,
delegate: userTableViewCellDelegate
)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ extension FavoritedByViewController: DataSourceProvider {
}

switch item {
case .user(let record):
return .user(record: record)
default:
return nil
case .account(let account, let relationship):
return .account(account: account, relationship: relationship)
case .bottomHeader(_), .bottomLoader:
return nil
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ extension RebloggedByViewController: DataSourceProvider {
}

switch item {
case .user(let record):
return .user(record: record)
default:
return nil
case .account(let account, let relationship):
return .account(account: account, relationship: relationship)
case .bottomHeader(_), .bottomLoader:
return nil
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import UIKit
import MastodonAsset
import MastodonLocalization
import Combine
import MastodonSDK

extension UserListViewModel {
@MainActor
Expand All @@ -33,17 +34,24 @@ extension UserListViewModel {
// trigger initial loading
stateMachine.enter(UserListViewModel.State.Reloading.self)

userFetchedResultsController.$records
$accounts
.receive(on: DispatchQueue.main)
.sink { [weak self] records in
guard let self = self else { return }
.sink { [weak self] accounts in
guard let 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 {
switch currentState {
case is State.Initial, is State.Idle, is State.Reloading, is State.Loading, is State.Fail:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ 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 = []
viewModel.relationships = []

stateMachine.enter(Loading.self)
}
}
Expand Down Expand Up @@ -123,40 +124,61 @@ extension UserListViewModel.State {

Task {
do {
let response: Mastodon.Response.Content<[Mastodon.Entity.Account]>
let accountResponse: Mastodon.Response.Content<[Mastodon.Entity.Account]>
switch viewModel.kind {
case .favoritedBy(let status):
response = try await viewModel.context.apiService.favoritedBy(
accountResponse = try await viewModel.context.apiService.favoritedBy(
status: status,
query: .init(maxID: maxID, limit: nil),
authenticationBox: viewModel.authContext.mastodonAuthenticationBox
)
case .rebloggedBy(let status):
response = try await viewModel.context.apiService.rebloggedBy(
accountResponse = try await viewModel.context.apiService.rebloggedBy(
status: status,
query: .init(maxID: maxID, limit: nil),
authenticationBox: viewModel.authContext.mastodonAuthenticationBox
)
}

if accountResponse.value.isEmpty {
await enter(state: NoMore.self)

viewModel.accounts = []
viewModel.relationships = []
return
}

var hasNewAppend = false
var userIDs = viewModel.userFetchedResultsController.userIDs
for user in response.value {
guard !userIDs.contains(user.id) else { continue }
userIDs.append(user.id)

let newRelationships = try await viewModel.context.apiService.relationship(forAccounts: accountResponse.value, authenticationBox: viewModel.authContext.mastodonAuthenticationBox)

var accounts = viewModel.accounts

for user in accountResponse.value {
guard accounts.contains(user) == false else { continue }
accounts.append(user)
hasNewAppend = true
}

let maxID = response.link?.maxID


var relationships = viewModel.relationships

for relationship in newRelationships.value {
guard relationships.contains(relationship) == false else { continue }
relationships.append(relationship)
}

let maxID = accountResponse.link?.maxID

if hasNewAppend, maxID != nil {
await enter(state: Idle.self)
} else {
await enter(state: NoMore.self)
}

viewModel.accounts = accounts
viewModel.relationships = relationships
self.maxID = maxID
viewModel.userFetchedResultsController.userIDs = userIDs


} catch {
await enter(state: Fail.self)
}
Expand All @@ -177,9 +199,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
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Combine
import CoreDataStack
import GameplayKit
import MastodonCore
import MastodonSDK

final class UserListViewModel {
var disposeBag = Set<AnyCancellable>()
Expand All @@ -18,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
Expand All @@ -43,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 = []
}
}

Expand Down
Loading

0 comments on commit 2119c9d

Please sign in to comment.