Fix pinned status issues

This commit is contained in:
Justin Mazzocchi 2020-09-26 18:23:56 -07:00
parent 098d439722
commit b1a87f86db
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
3 changed files with 29 additions and 12 deletions

View file

@ -28,6 +28,18 @@ public class AccountStatusesViewModel: StatusListViewModel {
.assign(to: &$accountViewModel)
}
public override var collectionItems: AnyPublisher<[[CollectionItem]], Never> {
// The pinned key is added to the info of collection items in the first section
// so a diffable data source can potentially render it in both sections
super.collectionItems
.map {
$0.enumerated().map {
$0 == 0 ? $1.map { .init(id: $0.id, kind: $0.kind, info: [.pinned: true]) } : $1
}
}
.eraseToAnyPublisher()
}
public override var navigationEvents: AnyPublisher<NavigationEvent, Never> {
$accountViewModel.compactMap { $0 }
.flatMap(\.events)
@ -50,10 +62,6 @@ public class AccountStatusesViewModel: StatusListViewModel {
super.request(maxID: maxID, minID: minID)
}
override func isPinned(status: Status) -> Bool {
collection == .statuses && items.first?.contains(CollectionItem(id: status.id, kind: .status)) ?? false
}
public override var title: AnyPublisher<String?, Never> {
$accountViewModel.map { $0?.accountName }.eraseToAnyPublisher()
}

View file

@ -3,6 +3,13 @@
public struct CollectionItem: Hashable {
public let id: String
public let kind: Kind
public let info: [InfoKey: AnyHashable]
init(id: String, kind: Kind, info: [InfoKey: AnyHashable]? = nil) {
self.id = id
self.kind = kind
self.info = info ?? [InfoKey: AnyHashable]()
}
}
public extension CollectionItem {
@ -10,4 +17,8 @@ public extension CollectionItem {
case status
case account
}
enum InfoKey {
case pinned
}
}

View file

@ -41,6 +41,8 @@ public class StatusListViewModel: ObservableObject {
.store(in: &cancellables)
}
public var collectionItems: AnyPublisher<[[CollectionItem]], Never> { $items.eraseToAnyPublisher() }
public var navigationEvents: AnyPublisher<NavigationEvent, Never> { navigationEventsSubject.eraseToAnyPublisher() }
public var title: AnyPublisher<String?, Never> { Just(statusListService.title).eraseToAnyPublisher() }
@ -55,13 +57,9 @@ public class StatusListViewModel: ObservableObject {
.sink { _ in }
.store(in: &cancellables)
}
func isPinned(status: Status) -> Bool { false }
}
extension StatusListViewModel: CollectionViewModel {
public var collectionItems: AnyPublisher<[[CollectionItem]], Never> { $items.eraseToAnyPublisher() }
public var alertItems: AnyPublisher<AlertItem, Never> { $alertItem.compactMap { $0 }.eraseToAnyPublisher() }
public var loading: AnyPublisher<Bool, Never> { loadingSubject.eraseToAnyPublisher() }
@ -93,7 +91,7 @@ extension StatusListViewModel: CollectionViewModel {
public func viewModel(item: CollectionItem) -> Any? {
switch item.kind {
case .status:
return statusViewModel(id: item.id)
return statusViewModel(item: item)
default:
return nil
}
@ -111,8 +109,8 @@ private extension StatusListViewModel {
var contextParentID: String? { statusListService.contextParentID }
func statusViewModel(id: String) -> StatusViewModel? {
guard let status = statuses[id] else { return nil }
func statusViewModel(item: CollectionItem) -> StatusViewModel? {
guard let status = statuses[item.id] else { return nil }
var statusViewModel: StatusViewModel
@ -136,7 +134,7 @@ private extension StatusListViewModel {
}
statusViewModel.isContextParent = status.id == statusListService.contextParentID
statusViewModel.isPinned = isPinned(status: status)
statusViewModel.isPinned = item.info[.pinned] != nil
statusViewModel.isReplyInContext = isReplyInContext(status: status)
statusViewModel.hasReplyFollowing = hasReplyFollowing(status: status)