Merge branch 'develop' into remove_status
This commit is contained in:
commit
1dfcf407e1
|
@ -293,8 +293,6 @@
|
|||
DB4FFC2C269EC39600D62E92 /* SearchTransitionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4FFC2A269EC39600D62E92 /* SearchTransitionController.swift */; };
|
||||
DB5B549A2833A60400DEF8B2 /* FamiliarFollowersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */; };
|
||||
DB5B549D2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */; };
|
||||
DB5B549F2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */; };
|
||||
DB5B54A12833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */; };
|
||||
DB5B54A32833BD1A00DEF8B2 /* UserListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */; };
|
||||
DB5B54A62833BE0000DEF8B2 /* UserListViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A52833BE0000DEF8B2 /* UserListViewModel+State.swift */; };
|
||||
DB5B54A82833BFA500DEF8B2 /* FavoritedByViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A72833BFA500DEF8B2 /* FavoritedByViewController.swift */; };
|
||||
|
@ -1005,8 +1003,6 @@
|
|||
DB519B17281BCC2F00F0C99D /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Intents.stringsdict; sourceTree = "<group>"; };
|
||||
DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FamiliarFollowersViewController.swift; sourceTree = "<group>"; };
|
||||
DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FamiliarFollowersViewModel.swift; sourceTree = "<group>"; };
|
||||
DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FamiliarFollowersViewModel+Diffable.swift"; sourceTree = "<group>"; };
|
||||
DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FamiliarFollowersViewController+DataSourceProvider.swift"; sourceTree = "<group>"; };
|
||||
DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserListViewModel.swift; sourceTree = "<group>"; };
|
||||
DB5B54A52833BE0000DEF8B2 /* UserListViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserListViewModel+State.swift"; sourceTree = "<group>"; };
|
||||
DB5B54A72833BFA500DEF8B2 /* FavoritedByViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritedByViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -2286,9 +2282,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */,
|
||||
DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */,
|
||||
DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */,
|
||||
DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */,
|
||||
);
|
||||
path = FamiliarFollowers;
|
||||
sourceTree = "<group>";
|
||||
|
@ -3718,7 +3712,6 @@
|
|||
0FAA101C25E10E760017CCDE /* UIFont.swift in Sources */,
|
||||
2D38F1D525CD465300561493 /* HomeTimelineViewController.swift in Sources */,
|
||||
DB6180E926391BDF0018D199 /* MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift in Sources */,
|
||||
DB5B549F2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift in Sources */,
|
||||
DB6B351E2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift in Sources */,
|
||||
DB8F7076279E954700E1225B /* DataSourceFacade+Follow.swift in Sources */,
|
||||
DB63F7542799491600455B82 /* DataSourceFacade+SearchHistory.swift in Sources */,
|
||||
|
@ -3755,7 +3748,6 @@
|
|||
D8E5C349296DB8A3007E76A7 /* StatusEditHistoryViewController.swift in Sources */,
|
||||
DBE0822425CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift in Sources */,
|
||||
D8318A882A4468D300C0FB73 /* NotificationSettingsViewController.swift in Sources */,
|
||||
DB5B54A12833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift in Sources */,
|
||||
2D82B9FF25E7863200E36F0F /* OnboardingViewControllerAppearance.swift in Sources */,
|
||||
DB025B78278D606A002F581E /* StatusItem.swift in Sources */,
|
||||
D82BD7532ABC44C2009A374A /* Coordinator.swift in Sources */,
|
||||
|
|
|
@ -462,9 +462,7 @@ private extension SceneCoordinator {
|
|||
let followingListViewController = FollowingListViewController(viewModel: viewModel, coordinator: self, context: appContext)
|
||||
viewController = followingListViewController
|
||||
case .familiarFollowers(let viewModel):
|
||||
let _viewController = FamiliarFollowersViewController()
|
||||
_viewController.viewModel = viewModel
|
||||
viewController = _viewController
|
||||
viewController = FamiliarFollowersViewController(viewModel: viewModel, context: appContext, coordinator: self)
|
||||
case .rebloggedBy(let viewModel):
|
||||
let _viewController = RebloggedByViewController()
|
||||
_viewController.viewModel = viewModel
|
||||
|
|
|
@ -9,6 +9,7 @@ import UIKit
|
|||
import Combine
|
||||
import MastodonUI
|
||||
import MastodonCore
|
||||
import MastodonSDK
|
||||
|
||||
final class DiscoveryForYouViewController: UIViewController, NeedsDependency, MediaPreviewableViewController {
|
||||
|
||||
|
@ -136,20 +137,34 @@ extension DiscoveryForYouViewController: ProfileCardTableViewCellDelegate {
|
|||
guard let indexPath = tableView.indexPath(for: cell) else { return }
|
||||
guard case let .account(account, _) = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { return }
|
||||
|
||||
let userID = account.id
|
||||
let _familiarFollowers = viewModel.familiarFollowers.first(where: { $0.id == userID })
|
||||
guard let familiarFollowers = _familiarFollowers else {
|
||||
assertionFailure()
|
||||
return
|
||||
coordinator.showLoading()
|
||||
|
||||
Task { [weak self] in
|
||||
|
||||
guard let self else { return }
|
||||
do {
|
||||
let userID = account.id
|
||||
let familiarFollowers = viewModel.familiarFollowers.first(where: { $0.id == userID })?.accounts ?? []
|
||||
let relationships = try await context.apiService.relationship(forAccounts: familiarFollowers, authenticationBox: authContext.mastodonAuthenticationBox).value
|
||||
|
||||
coordinator.hideLoading()
|
||||
|
||||
let familiarFollowersViewModel = FamiliarFollowersViewModel(
|
||||
context: context,
|
||||
authContext: authContext,
|
||||
accounts: familiarFollowers,
|
||||
relationships: relationships
|
||||
)
|
||||
|
||||
_ = coordinator.present(
|
||||
scene: .familiarFollowers(viewModel: familiarFollowersViewModel),
|
||||
from: self,
|
||||
transition: .show
|
||||
)
|
||||
} catch {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
let familiarFollowersViewModel = FamiliarFollowersViewModel(context: context, authContext: authContext)
|
||||
familiarFollowersViewModel.familiarFollowers = familiarFollowers
|
||||
_ = coordinator.present(
|
||||
scene: .familiarFollowers(viewModel: familiarFollowersViewModel),
|
||||
from: self,
|
||||
transition: .show
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,4 +172,3 @@ extension DiscoveryForYouViewController: ProfileCardTableViewCellDelegate {
|
|||
extension DiscoveryForYouViewController: ScrollViewContainer {
|
||||
var scrollView: UIScrollView { tableView }
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ final class DiscoveryForYouViewModel {
|
|||
@Published var familiarFollowers: [Mastodon.Entity.FamiliarFollowers] = []
|
||||
@Published var isFetching = false
|
||||
@Published var accounts: [Mastodon.Entity.Account]
|
||||
var relationships: [Mastodon.Entity.Relationship?]
|
||||
var relationships: [Mastodon.Entity.Relationship]
|
||||
|
||||
// output
|
||||
var diffableDataSource: UITableViewDiffableDataSource<DiscoverySection, DiscoveryItem>?
|
||||
|
@ -72,7 +72,7 @@ extension DiscoveryForYouViewModel {
|
|||
snapshot.appendSections([.forYou])
|
||||
|
||||
let items = self.accounts.map { account in
|
||||
let relationship = relationships.first { $0?.id == account.id } ?? nil
|
||||
let relationship = relationships.first { $0.id == account.id } ?? nil
|
||||
|
||||
return DiscoveryItem.account(account, relationship: relationship)
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// FamiliarFollowersViewController+DataSourceProvider.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by MainasuK on 2022-5-17.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MastodonSDK
|
||||
|
||||
extension FamiliarFollowersViewController: DataSourceProvider {
|
||||
func item(from source: DataSourceItem.Source) async -> DataSourceItem? {
|
||||
var _indexPath = source.indexPath
|
||||
if _indexPath == nil, let cell = source.tableViewCell {
|
||||
_indexPath = await self.indexPath(for: cell)
|
||||
}
|
||||
guard let indexPath = _indexPath else { return nil }
|
||||
|
||||
guard let item = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch item {
|
||||
case .user(let record):
|
||||
return .user(record: record)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus) {
|
||||
assertionFailure("Implement not required in this class")
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func indexPath(for cell: UITableViewCell) async -> IndexPath? {
|
||||
return tableView.indexPath(for: cell)
|
||||
}
|
||||
}
|
|
@ -10,40 +10,36 @@ import Combine
|
|||
import MastodonCore
|
||||
import MastodonLocalization
|
||||
import MastodonUI
|
||||
import CoreDataStack
|
||||
import MastodonSDK
|
||||
|
||||
final class FamiliarFollowersViewController: UIViewController, NeedsDependency {
|
||||
|
||||
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
||||
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
||||
|
||||
var disposeBag = Set<AnyCancellable>()
|
||||
var viewModel: FamiliarFollowersViewModel!
|
||||
|
||||
lazy var tableView: UITableView = {
|
||||
let tableView = UITableView()
|
||||
weak var context: AppContext!
|
||||
weak var coordinator: SceneCoordinator!
|
||||
let viewModel: FamiliarFollowersViewModel
|
||||
|
||||
let tableView: UITableView
|
||||
|
||||
init(viewModel: FamiliarFollowersViewModel, context: AppContext, coordinator: SceneCoordinator) {
|
||||
self.viewModel = viewModel
|
||||
self.context = context
|
||||
self.coordinator = coordinator
|
||||
|
||||
tableView = UITableView()
|
||||
tableView.rowHeight = UITableView.automaticDimension
|
||||
tableView.separatorStyle = .none
|
||||
tableView.backgroundColor = .clear
|
||||
return tableView
|
||||
}()
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension FamiliarFollowersViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
title = L10n.Scene.Familiarfollowers.title
|
||||
|
||||
|
||||
view.backgroundColor = .secondarySystemBackground
|
||||
|
||||
|
||||
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(tableView)
|
||||
tableView.pinToParent()
|
||||
|
||||
|
||||
tableView.delegate = self
|
||||
viewModel.setupDiffableDataSource(
|
||||
tableView: tableView,
|
||||
|
@ -51,10 +47,13 @@ extension FamiliarFollowersViewController {
|
|||
)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
tableView.deselectRow(with: transitionCoordinator, animated: animated)
|
||||
viewModel.viewWillAppear()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -81,3 +80,36 @@ extension FamiliarFollowersViewController: UITableViewDelegate, AutoGenerateTabl
|
|||
|
||||
// MARK: - UserTableViewCellDelegate
|
||||
extension FamiliarFollowersViewController: UserTableViewCellDelegate {}
|
||||
|
||||
//MARK: - DataSourceProvider
|
||||
extension FamiliarFollowersViewController: DataSourceProvider {
|
||||
func item(from source: DataSourceItem.Source) async -> DataSourceItem? {
|
||||
var _indexPath = source.indexPath
|
||||
if _indexPath == nil, let cell = source.tableViewCell {
|
||||
_indexPath = await self.indexPath(for: cell)
|
||||
}
|
||||
guard let indexPath = _indexPath else { return nil }
|
||||
|
||||
guard let item = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch item {
|
||||
case .account(let account, relationship: let relationship):
|
||||
return .account(account: account, relationship: relationship)
|
||||
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus) {
|
||||
assertionFailure("Implement not required in this class")
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func indexPath(for cell: UITableViewCell) async -> IndexPath? {
|
||||
return tableView.indexPath(for: cell)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// FamiliarFollowersViewModel+Diffable.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by MainasuK on 2022-5-17.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
|
||||
extension FamiliarFollowersViewModel {
|
||||
func setupDiffableDataSource(
|
||||
tableView: UITableView,
|
||||
userTableViewCellDelegate: UserTableViewCellDelegate?
|
||||
) {
|
||||
diffableDataSource = UserSection.diffableDataSource(
|
||||
tableView: tableView,
|
||||
context: context,
|
||||
authContext: authContext,
|
||||
userTableViewCellDelegate: userTableViewCellDelegate
|
||||
)
|
||||
|
||||
userFetchedResultsController.$records
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] records 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) }
|
||||
snapshot.appendItems(items, toSection: .main)
|
||||
|
||||
diffableDataSource.apply(snapshot, animatingDifferences: false)
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
}
|
|
@ -6,41 +6,54 @@
|
|||
//
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
import MastodonCore
|
||||
import MastodonSDK
|
||||
import CoreDataStack
|
||||
|
||||
final class FamiliarFollowersViewModel {
|
||||
var disposeBag = Set<AnyCancellable>()
|
||||
|
||||
// input
|
||||
let context: AppContext
|
||||
let authContext: AuthContext
|
||||
let userFetchedResultsController: UserFetchedResultsController
|
||||
|
||||
@Published var familiarFollowers: Mastodon.Entity.FamiliarFollowers?
|
||||
|
||||
var accounts: [Mastodon.Entity.Account]
|
||||
var relationships: [Mastodon.Entity.Relationship]
|
||||
|
||||
// output
|
||||
var diffableDataSource: UITableViewDiffableDataSource<UserSection, UserItem>?
|
||||
|
||||
init(context: AppContext, authContext: AuthContext) {
|
||||
init(context: AppContext, authContext: AuthContext, accounts: [Mastodon.Entity.Account], relationships: [Mastodon.Entity.Relationship]) {
|
||||
self.context = context
|
||||
self.authContext = authContext
|
||||
self.userFetchedResultsController = UserFetchedResultsController(
|
||||
managedObjectContext: context.managedObjectContext,
|
||||
domain: authContext.mastodonAuthenticationBox.domain,
|
||||
additionalPredicate: nil
|
||||
)
|
||||
// end init
|
||||
|
||||
$familiarFollowers
|
||||
.map { familiarFollowers -> [MastodonUser.ID] in
|
||||
guard let familiarFollowers = familiarFollowers else { return [] }
|
||||
return familiarFollowers.accounts.map { $0.id }
|
||||
}
|
||||
.assign(to: \.userIDs, on: userFetchedResultsController)
|
||||
.store(in: &disposeBag)
|
||||
self.accounts = accounts
|
||||
self.relationships = relationships
|
||||
}
|
||||
|
||||
func setupDiffableDataSource(
|
||||
tableView: UITableView,
|
||||
userTableViewCellDelegate: UserTableViewCellDelegate?
|
||||
) {
|
||||
diffableDataSource = UserSection.diffableDataSource(
|
||||
tableView: tableView,
|
||||
context: context,
|
||||
authContext: authContext,
|
||||
userTableViewCellDelegate: userTableViewCellDelegate
|
||||
)
|
||||
}
|
||||
|
||||
func viewWillAppear() {
|
||||
guard let diffableDataSource else { return }
|
||||
|
||||
var snapshot = NSDiffableDataSourceSnapshot<UserSection, UserItem>()
|
||||
snapshot.appendSections([.main])
|
||||
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)
|
||||
|
||||
diffableDataSource.apply(snapshot, animatingDifferences: false)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue