Timeline highlight mentions (#595)
* Introduce fetchPages * Set up highlighting * Implement highlighting stage 1 * Implement highlighting stage 2 * Implement highlighting. * Fix merge * Add protocol * Remove debug prints
This commit is contained in:
parent
3e320e4b6d
commit
10946fef10
|
@ -54,11 +54,17 @@ public protocol AnyStatus {
|
|||
var language: String? { get }
|
||||
}
|
||||
|
||||
public struct Status: AnyStatus, Decodable, Identifiable, Equatable, Hashable {
|
||||
protocol StatusUI {
|
||||
var uiShouldHighlight: Bool? { get set }
|
||||
}
|
||||
|
||||
public struct Status: AnyStatus, Decodable, Identifiable, Equatable, Hashable, StatusUI {
|
||||
public var viewId: String {
|
||||
id + createdAt + (editedAt ?? "")
|
||||
}
|
||||
|
||||
public var uiShouldHighlight: Bool?
|
||||
|
||||
public static func == (lhs: Status, rhs: Status) -> Bool {
|
||||
lhs.id == rhs.id
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ public struct StatusRowView: View {
|
|||
.contextMenu {
|
||||
contextMenu
|
||||
}
|
||||
.listRowBackground(viewModel.shouldHighlightRow ? theme.secondaryBackgroundColor : theme.primaryBackgroundColor)
|
||||
.swipeActions(edge: .trailing) {
|
||||
trailinSwipeActions
|
||||
}
|
||||
|
|
|
@ -36,6 +36,10 @@ public class StatusRowViewModel: ObservableObject {
|
|||
status.reblog?.filtered?.first ?? status.filtered?.first
|
||||
}
|
||||
|
||||
var shouldHighlightRow: Bool {
|
||||
status.uiShouldHighlight != nil
|
||||
}
|
||||
|
||||
var client: Client?
|
||||
|
||||
public init(status: Status,
|
||||
|
|
|
@ -22,7 +22,12 @@ class TimelineViewModel: ObservableObject {
|
|||
private var canStreamEvents: Bool = true
|
||||
|
||||
let pendingStatusesObserver: PendingStatusesObserver = .init()
|
||||
let cache: TimelineCache = .shared
|
||||
|
||||
private var accountId: String? {
|
||||
CurrentAccount.shared.account?.id
|
||||
}
|
||||
|
||||
private let cache: TimelineCache = .shared
|
||||
|
||||
@Published var scrollToStatus: String?
|
||||
|
||||
|
@ -57,7 +62,7 @@ class TimelineViewModel: ObservableObject {
|
|||
client?.server ?? "Error"
|
||||
}
|
||||
|
||||
func fetchTag(id: String) async {
|
||||
private func fetchTag(id: String) async {
|
||||
guard let client else { return }
|
||||
do {
|
||||
tag = try await client.get(endpoint: Tags.tag(id: id))
|
||||
|
@ -71,7 +76,13 @@ class TimelineViewModel: ObservableObject {
|
|||
!statuses.contains(where: { $0.id == event.status.id })
|
||||
{
|
||||
pendingStatusesObserver.pendingStatuses.insert(event.status.id, at: 0)
|
||||
statuses.insert(event.status, at: 0)
|
||||
var newStatus = event.status
|
||||
if let accountId {
|
||||
if newStatus.mentions.first(where: { $0.id == accountId }) != nil {
|
||||
newStatus.uiShouldHighlight = true
|
||||
}
|
||||
}
|
||||
statuses.insert(newStatus, at: 0)
|
||||
Task {
|
||||
await cacheHome()
|
||||
}
|
||||
|
@ -153,7 +164,7 @@ extension TimelineViewModel: StatusesFetcher {
|
|||
minId: nil,
|
||||
offset: statuses.count))
|
||||
|
||||
|
||||
updateMentionsToBeHighlighted(&statuses)
|
||||
ReblogCache.shared.removeDuplicateReblogs(&statuses)
|
||||
|
||||
await cacheHome()
|
||||
|
@ -238,6 +249,7 @@ extension TimelineViewModel: StatusesFetcher {
|
|||
{
|
||||
pagesLoaded += 1
|
||||
|
||||
updateMentionsToBeHighlighted(&newStatuses)
|
||||
ReblogCache.shared.removeDuplicateReblogs(&newStatuses)
|
||||
|
||||
allStatuses.insert(contentsOf: newStatuses, at: 0)
|
||||
|
@ -259,16 +271,28 @@ extension TimelineViewModel: StatusesFetcher {
|
|||
minId: nil,
|
||||
offset: statuses.count))
|
||||
|
||||
|
||||
updateMentionsToBeHighlighted(&newStatuses)
|
||||
ReblogCache.shared.removeDuplicateReblogs(&newStatuses)
|
||||
|
||||
|
||||
statuses.append(contentsOf: newStatuses)
|
||||
|
||||
statusesState = .display(statuses: statuses, nextPageState: .hasNextPage)
|
||||
} catch {
|
||||
statusesState = .error(error: error)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateMentionsToBeHighlighted(_ statuses: inout [Status]) {
|
||||
if !statuses.isEmpty, let accountId {
|
||||
for i in statuses.indices {
|
||||
if statuses[i].mentions.first(where: { $0.id == accountId }) != nil {
|
||||
statuses[i].uiShouldHighlight = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func statusDidAppear(status: Status) {
|
||||
pendingStatusesObserver.removeStatus(status: status)
|
||||
visibileStatusesIds.insert(status.id)
|
||||
|
|
Loading…
Reference in New Issue