mastodon-app-ufficiale-ipho.../Mastodon/Scene/Profile/FollowedTags/FollowedTagsViewModel.swift

113 lines
3.5 KiB
Swift
Raw Normal View History

2022-11-25 13:07:28 +01:00
//
// FollowedTagsViewModel.swift
// Mastodon
//
// Created by Marcus Kida on 23.11.22.
//
import UIKit
import MastodonSDK
import MastodonCore
import Combine
2022-11-25 13:07:28 +01:00
final class FollowedTagsViewModel: NSObject {
private var disposeBag = [AnyCancellable]()
private(set) var followedTags: [Mastodon.Entity.Tag] = []
2022-11-25 13:07:28 +01:00
private weak var tableView: UITableView?
var diffableDataSource: UITableViewDiffableDataSource<Section, Item>?
2022-11-25 13:07:28 +01:00
// input
let context: AppContext
let authContext: AuthContext
@Published var records = [Mastodon.Entity.Tag]()
// output
let presentHashtagTimeline = PassthroughSubject<HashtagTimelineViewModel, Never>()
2023-11-10 13:52:49 +01:00
2022-11-25 13:07:28 +01:00
init(context: AppContext, authContext: AuthContext) {
self.context = context
self.authContext = authContext
2022-11-25 13:07:28 +01:00
super.init()
$records
2022-11-25 13:07:28 +01:00
.receive(on: DispatchQueue.main)
.sink { [weak self] records in
guard let self = self else { return }
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.main])
snapshot.appendItems(records.map {.hashtag($0) })
2022-12-17 21:57:17 +01:00
self.diffableDataSource?.apply(snapshot, animatingDifferences: true)
2022-11-25 13:07:28 +01:00
}
.store(in: &disposeBag)
}
}
extension FollowedTagsViewModel {
func setupTableView(_ tableView: UITableView) {
setupDiffableDataSource(tableView: tableView)
2022-11-25 13:07:28 +01:00
fetchFollowedTags()
2022-11-25 13:07:28 +01:00
}
2023-11-10 13:28:37 +01:00
func fetchFollowedTags(completion: (() -> Void)? = nil ) {
Task { @MainActor in
2023-11-10 13:52:49 +01:00
do {
followedTags = try await context.apiService.getFollowedTags(
domain: authContext.mastodonAuthenticationBox.domain,
query: Mastodon.API.Account.FollowedTagsQuery(limit: nil),
authenticationBox: authContext.mastodonAuthenticationBox
).value
2023-11-10 13:52:49 +01:00
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.main])
let items = followedTags.compactMap { Item.hashtag($0) }
snapshot.appendItems(items, toSection: .main)
2023-11-10 13:52:49 +01:00
await diffableDataSource?.apply(snapshot)
} catch {}
2023-11-10 13:28:37 +01:00
completion?()
2022-11-25 13:07:28 +01:00
}
}
func followOrUnfollow(_ tag: Mastodon.Entity.Tag) {
2022-11-25 13:07:28 +01:00
Task { @MainActor in
switch tag.following {
case .none:
break
case .some(true):
2022-11-25 13:07:28 +01:00
_ = try? await context.apiService.unfollowTag(
for: tag.name,
authenticationBox: authContext.mastodonAuthenticationBox
)
case .some(false):
2022-11-25 13:07:28 +01:00
_ = try? await context.apiService.followTag(
for: tag.name,
authenticationBox: authContext.mastodonAuthenticationBox
)
}
fetchFollowedTags()
2022-11-25 13:07:28 +01:00
}
}
}
extension FollowedTagsViewModel: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let object = records[indexPath.row]
let hashtagTimelineViewModel = HashtagTimelineViewModel(
context: self.context,
authContext: self.authContext,
hashtag: object.name
)
presentHashtagTimeline.send(hashtagTimelineViewModel)
2022-11-25 13:07:28 +01:00
}
}