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:
Sean Goldin 2023-02-01 23:39:03 -06:00 committed by GitHub
parent 3e320e4b6d
commit 10946fef10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 6 deletions

View file

@ -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
}

View file

@ -83,6 +83,7 @@ public struct StatusRowView: View {
.contextMenu {
contextMenu
}
.listRowBackground(viewModel.shouldHighlightRow ? theme.secondaryBackgroundColor : theme.primaryBackgroundColor)
.swipeActions(edge: .trailing) {
trailinSwipeActions
}

View file

@ -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,

View file

@ -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)