Fix context bugs

This commit is contained in:
Justin Mazzocchi 2020-08-23 21:34:19 -07:00
parent f340569295
commit 650e6b2991
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
5 changed files with 33 additions and 18 deletions

View file

@ -3,6 +3,7 @@
import Foundation
enum StatusEndpoint {
case status(id: String)
case favourite(id: String)
case unfavourite(id: String)
}
@ -16,6 +17,8 @@ extension StatusEndpoint: MastodonEndpoint {
var pathComponentsInContext: [String] {
switch self {
case let .status(id):
return [id]
case let .favourite(id):
return [id, "favourite"]
case let .unfavourite(id):
@ -25,6 +28,8 @@ extension StatusEndpoint: MastodonEndpoint {
var method: HTTPMethod {
switch self {
case .status:
return .get
case .favourite, .unfavourite:
return .post
}

View file

@ -6,7 +6,7 @@ import Combine
struct ContextService {
let statusSections: AnyPublisher<[[Status]], Error>
private var status: Status
private let status: Status
private let context = CurrentValueSubject<MastodonContext, Never>(MastodonContext(ancestors: [], descendants: []))
private let networkClient: MastodonClient
private let contentDatabase: ContentDatabase
@ -32,7 +32,7 @@ struct ContextService {
}
extension ContextService: StatusListService {
var contextParent: Status? { status }
var contextParentID: String? { status.id }
func isReplyInContext(status: Status) -> Bool {
let flatContext = flattenedContext()
@ -44,7 +44,7 @@ extension ContextService: StatusListService {
let previousStatus = flatContext[index - 1]
return previousStatus.id != contextParent?.id && status.inReplyToId == previousStatus.id
return previousStatus.id != contextParentID && status.inReplyToId == previousStatus.id
}
func hasReplyFollowing(status: Status) -> Bool {
@ -57,14 +57,18 @@ extension ContextService: StatusListService {
let nextStatus = flatContext[index + 1]
return status.id != contextParent?.id && nextStatus.inReplyToId == status.id
return status.id != contextParentID && nextStatus.inReplyToId == status.id
}
func request(maxID: String?, minID: String?) -> AnyPublisher<Void, Error> {
networkClient.request(ContextEndpoint.context(id: status.id))
.handleEvents(receiveOutput: context.send)
.map { ($0.ancestors + $0.descendants, collection) }
.flatMap(contentDatabase.insert(statuses:collection:))
Publishers.Merge(
networkClient.request(StatusEndpoint.status(id: status.id))
.map { ([$0], collection) }
.flatMap(contentDatabase.insert(statuses:collection:)),
networkClient.request(ContextEndpoint.context(id: status.id))
.handleEvents(receiveOutput: context.send)
.map { ($0.ancestors + $0.descendants, collection) }
.flatMap(contentDatabase.insert(statuses:collection:)))
.eraseToAnyPublisher()
}

View file

@ -5,7 +5,7 @@ import Combine
protocol StatusListService {
var statusSections: AnyPublisher<[[Status]], Error> { get }
var contextParent: Status? { get }
var contextParentID: String? { get }
func isPinned(status: Status) -> Bool
func isReplyInContext(status: Status) -> Bool
func hasReplyFollowing(status: Status) -> Bool
@ -15,7 +15,7 @@ protocol StatusListService {
}
extension StatusListService {
var contextParent: Status? { nil }
var contextParentID: String? { nil }
func isPinned(status: Status) -> Bool { false }

View file

@ -26,7 +26,7 @@ class StatusesViewModel: ObservableObject {
}
extension StatusesViewModel {
var contextParent: Status? { statusListService.contextParent }
var contextParentID: String? { statusListService.contextParentID }
func request(maxID: String? = nil, minID: String? = nil) {
statusListService.request(maxID: maxID, minID: minID)
@ -51,7 +51,7 @@ extension StatusesViewModel {
.sink {})
}
statusViewModel.isContextParent = status == contextParent
statusViewModel.isContextParent = status.id == contextParentID
statusViewModel.isPinned = statusListService.isPinned(status: status)
statusViewModel.isReplyInContext = statusListService.isReplyInContext(status: status)
statusViewModel.hasReplyFollowing = statusListService.hasReplyFollowing(status: status)
@ -69,8 +69,8 @@ private extension StatusesViewModel {
maintainScrollPositionOfStatusID = nil // clear old value
// Maintain scroll position of parent after initial load of context
if let contextParent = contextParent, statusSections == [[], [contextParent], []] {
maintainScrollPositionOfStatusID = contextParent.id
if let contextParentID = contextParentID, statusSections.reduce([], +).map(\.id) == [contextParentID] {
maintainScrollPositionOfStatusID = contextParentID
}
}

View file

@ -101,7 +101,7 @@ class StatusListViewController: UITableViewController {
}
override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
viewModel.statusSections[indexPath.section][indexPath.row] != viewModel.contextParent
viewModel.statusSections[indexPath.section][indexPath.row].id != viewModel.contextParentID
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
@ -123,11 +123,17 @@ extension StatusListViewController: StatusTableViewCellDelegate {
private extension StatusListViewController {
func indexPath(statusID: String) -> IndexPath? {
guard let status = viewModel.statusSections.reduce([], +).first(where: { $0.id == statusID }) else {
return nil
for section in 0..<dataSource.numberOfSections(in: tableView) {
for row in 0..<dataSource.tableView(tableView, numberOfRowsInSection: section) {
let indexPath = IndexPath(row: row, section: section)
if dataSource.itemIdentifier(for: indexPath)?.id == statusID {
return indexPath
}
}
}
return dataSource.indexPath(for: status)
return nil
}
func share(url: URL) {