mastodon-app-ufficiale-ipho.../Mastodon/Scene/SuggestionAccount/SuggestionAccountViewModel....

156 lines
5.4 KiB
Swift
Raw Normal View History

2021-04-21 08:46:31 +02:00
//
// SuggestionAccountViewModel.swift
// Mastodon
//
// Created by sxiaojian on 2021/4/21.
//
import Combine
import MastodonSDK
2022-10-08 07:43:06 +02:00
import MastodonCore
2021-04-21 08:46:31 +02:00
import UIKit
protocol SuggestionAccountViewModelDelegate: AnyObject {
2021-04-22 04:11:19 +02:00
var homeTimelineNeedRefresh: PassthroughSubject<Void, Never> { get }
}
2021-04-22 04:29:53 +02:00
2021-04-21 08:46:31 +02:00
final class SuggestionAccountViewModel: NSObject {
var disposeBag = Set<AnyCancellable>()
weak var delegate: SuggestionAccountViewModelDelegate?
2021-04-21 08:46:31 +02:00
// input
let context: AppContext
let authContext: AuthContext
@Published var accounts: [Mastodon.Entity.V2.SuggestionAccount] = []
var relationships: [Mastodon.Entity.Relationship] = []
var viewWillAppear = PassthroughSubject<Void, Never>()
// output
var tableViewDiffableDataSource: UITableViewDiffableDataSource<RecommendAccountSection, RecommendAccountItem>?
@Published var records = [Mastodon.Entity.Account]()
init(
context: AppContext,
authContext: AuthContext
) {
2021-04-21 08:46:31 +02:00
self.context = context
self.authContext = authContext
// )
super.init()
2023-11-13 15:48:45 +01:00
updateSuggestions()
}
func updateSuggestions() {
Task {
var users: [Mastodon.Entity.Account] = []
var suggestedAccounts = [Mastodon.Entity.V2.SuggestionAccount]()
2021-04-21 11:58:56 +02:00
do {
let response = try await context.apiService.suggestionAccountV2(
2023-05-12 22:07:37 +02:00
query: .init(limit: 5),
authenticationBox: authContext.mastodonAuthenticationBox
)
suggestedAccounts = response.value
guard suggestedAccounts.isNotEmpty else { return }
let accounts = suggestedAccounts.compactMap { $0.account }
let relationships = try await context.apiService.relationship(
forAccounts: accounts,
authenticationBox: authContext.mastodonAuthenticationBox
).value
// users = response.value.map { $0 }
self.relationships = relationships
self.accounts = suggestedAccounts
2021-04-21 11:58:56 +02:00
} catch {
self.relationships = []
self.accounts = []
2021-04-21 11:58:56 +02:00
}
guard users.isNotEmpty else { return }
records = users
2021-04-21 11:58:56 +02:00
}
2022-02-16 10:25:55 +01:00
// fetch relationship
$records
2022-02-16 10:25:55 +01:00
.removeDuplicates()
.sink { [weak self] records in
guard let self else { return }
2022-02-16 10:25:55 +01:00
Task {
_ = try await self.context.apiService.relationship(
2022-02-16 10:25:55 +01:00
records: records,
authenticationBox: self.authContext.mastodonAuthenticationBox
2022-02-16 10:25:55 +01:00
)
}
}
.store(in: &disposeBag)
2021-04-21 11:58:56 +02:00
}
func setupDiffableDataSource(
tableView: UITableView,
suggestionAccountTableViewCellDelegate: SuggestionAccountTableViewCellDelegate
) {
tableViewDiffableDataSource = RecommendAccountSection.tableViewDiffableDataSource(
tableView: tableView,
context: context,
configuration: RecommendAccountSection.Configuration(
authContext: authContext,
suggestionAccountTableViewCellDelegate: suggestionAccountTableViewCellDelegate
)
)
$accounts
.receive(on: DispatchQueue.main)
.sink { [weak self] suggestedAccounts in
guard let self, let tableViewDiffableDataSource = self.tableViewDiffableDataSource else { return }
let accounts = suggestedAccounts.compactMap { $0.account }
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)
}
var snapshot = NSDiffableDataSourceSnapshot<RecommendAccountSection, RecommendAccountItem>()
snapshot.appendSections([.main])
let items: [RecommendAccountItem] = accountsWithRelationship.map { RecommendAccountItem.account($0.account, relationship: $0.relationship) }
snapshot.appendItems(items, toSection: .main)
tableViewDiffableDataSource.applySnapshotUsingReloadData(snapshot)
}
.store(in: &disposeBag)
}
2023-11-13 15:48:45 +01:00
func followAllSuggestedAccounts(_ dependency: NeedsDependency & AuthContextProvider, presentedOn: UIViewController?, completion: (() -> Void)? = nil) {
let tmpAccounts = accounts.compactMap { $0.account }
2023-05-23 12:55:24 +02:00
Task {
2023-11-13 15:48:45 +01:00
await dependency.coordinator.showLoading(on: presentedOn)
2023-05-23 12:55:24 +02:00
await withTaskGroup(of: Void.self, body: { taskGroup in
// for user in records {
for account in tmpAccounts {
taskGroup.addTask {
try? await DataSourceFacade.responseToUserViewButtonAction(
dependency: dependency,
user: account,
buttonState: .follow
)
}
2023-05-23 12:55:24 +02:00
}
// }
2023-05-23 12:55:24 +02:00
})
2023-05-23 13:13:34 +02:00
delegate?.homeTimelineNeedRefresh.send()
2023-05-23 12:55:24 +02:00
completion?()
}
}
2021-04-21 08:46:31 +02:00
}