-
-
Notifications
You must be signed in to change notification settings - Fork 297
Expand file tree
/
Copy pathMastodonPickServerViewModel+Diffable.swift
More file actions
123 lines (105 loc) · 5.69 KB
/
MastodonPickServerViewModel+Diffable.swift
File metadata and controls
123 lines (105 loc) · 5.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//
// MastodonPickServerViewController+Diffable.swift
// Mastodon
//
// Created by Cirno MainasuK on 2021/3/5.
//
import UIKit
import Combine
import MastodonSDK
extension MastodonPickServerViewModel {
func setupDiffableDataSource(
for tableView: UITableView,
dependency: NeedsDependency,
pickServerServerSectionTableHeaderViewDelegate: PickServerServerSectionTableHeaderViewDelegate
) {
// set section header
serverSectionHeaderView.diffableDataSource = CategoryPickerSection.collectionViewDiffableDataSource(
for: serverSectionHeaderView.collectionView,
dependency: dependency,
viewModel: self
)
var sectionHeaderSnapshot = NSDiffableDataSourceSnapshot<CategoryPickerSection, CategoryPickerItem>()
sectionHeaderSnapshot.appendSections([.main])
sectionHeaderSnapshot.appendItems(categoryPickerItems, toSection: .main)
serverSectionHeaderView.delegate = pickServerServerSectionTableHeaderViewDelegate
serverSectionHeaderView.diffableDataSource?.apply(sectionHeaderSnapshot, animatingDifferences: false) { [weak self] in
guard let self = self else { return }
guard let indexPath = self.serverSectionHeaderView.diffableDataSource?.indexPath(for: .category(category: .init(category: Mastodon.Entity.Category.Kind.general.rawValue, serversCount: 0))) else { return }
self.serverSectionHeaderView.collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .right)
let firstIndex = IndexPath(item: 0, section: 0)
self.serverSectionHeaderView.collectionView.scrollToItem(at: firstIndex, at: .left, animated: false)
}
// set tableView
diffableDataSource = PickServerSection.tableViewDiffableDataSource(
for: tableView,
dependency: dependency
)
var snapshot = NSDiffableDataSourceSnapshot<PickServerSection, PickServerItem>()
snapshot.appendSections([.header, .servers])
diffableDataSource?.apply(snapshot, animatingDifferences: false, completion: nil)
loadIndexedServerStateMachine.enter(LoadIndexedServerState.Loading.self)
Publishers.CombineLatest3(
filteredIndexedServers,
selectCategoryItem,
unindexedServers
)
.receive(on: DispatchQueue.main)
.sink(receiveValue: { [weak self] indexedServers, selectCategoryItem, unindexedServers in
guard let self = self else { return }
guard let diffableDataSource = self.diffableDataSource else { return }
let oldSnapshot = diffableDataSource.snapshot()
var oldSnapshotServerItemAttributeDict: [String : PickServerItem.ServerItemAttribute] = [:]
for item in oldSnapshot.itemIdentifiers {
guard case let .server(server, attribute) = item else { continue }
oldSnapshotServerItemAttributeDict[server.domain] = attribute
}
var snapshot = NSDiffableDataSourceSnapshot<PickServerSection, PickServerItem>()
snapshot.appendSections([.header, .servers])
// TODO: handle filter
var serverItems: [PickServerItem] = []
if let indexedServers {
if indexedServers.didIgnoreCategory,
indexedServers.servers.isNotEmpty,
case .category(let category) = selectCategoryItem {
serverItems.append(.message(attribute: .categoryIgnored(category: category.category)))
}
for server in indexedServers.servers {
let attribute = oldSnapshotServerItemAttributeDict[server.domain] ?? PickServerItem.ServerItemAttribute(isLast: false, isExpand: false)
attribute.isLast.value = false
let item = PickServerItem.server(server: server, attribute: attribute)
guard !serverItems.contains(item) else { continue }
serverItems.append(item)
}
}
if let unindexedServers = unindexedServers {
if !unindexedServers.isEmpty {
for server in unindexedServers {
let attribute = oldSnapshotServerItemAttributeDict[server.domain] ?? PickServerItem.ServerItemAttribute(isLast: false, isExpand: false)
attribute.isLast.value = false
let item = PickServerItem.server(server: server, attribute: attribute)
guard !serverItems.contains(item) else { continue }
serverItems.append(item)
}
} else {
if (indexedServers?.servers.isEmpty ?? true),
!self.isLoadingIndexedServers.value {
serverItems.append(.loader(attribute: PickServerItem.LoaderItemAttribute(isLast: false, isEmptyResult: true)))
}
}
} else {
serverItems.append(.loader(attribute: PickServerItem.LoaderItemAttribute(isLast: false, isEmptyResult: false)))
}
if case let .server(_, attribute) = serverItems.last {
attribute.isLast.value = true
}
if case let .loader(attribute) = serverItems.last {
attribute.isLast = true
}
snapshot.appendItems(serverItems, toSection: .servers)
diffableDataSource.defaultRowAnimation = .fade
diffableDataSource.apply(snapshot, animatingDifferences: true, completion: nil)
})
.store(in: &disposeBag)
}
}