From 4478672c109d2a1e7227996067723447c20ee835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=E2=80=99Aquino?= Date: Wed, 3 Sep 2025 11:37:43 -0700 Subject: [PATCH] Fix occasional stale timeline issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changelog-Changed: Added UX hint to make it easier to load new notes Signed-off-by: Daniel D’Aquino --- .../FollowPack/Views/FollowPackTimeline.swift | 2 +- .../Timeline/Views/InnerTimelineView.swift | 20 +++++++++++++++++++ .../Timeline/Views/TimelineView.swift | 11 ++++------ damus/Shared/Utilities/EventHolder.swift | 4 ++-- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/damus/Features/FollowPack/Views/FollowPackTimeline.swift b/damus/Features/FollowPack/Views/FollowPackTimeline.swift index 294c2321..ce4dfe82 100644 --- a/damus/Features/FollowPack/Views/FollowPackTimeline.swift +++ b/damus/Features/FollowPack/Views/FollowPackTimeline.swift @@ -66,7 +66,7 @@ struct FollowPackTimelineView: View { .coordinateSpace(name: "scroll") .onReceive(handle_notify(.scroll_to_top)) { () in events.flush() - self.events.should_queue = false + self.events.set_should_queue(false) scroll_to_event(scroller: scroller, id: "startblock", delay: 0.0, animate: true, anchor: .top) } } diff --git a/damus/Features/Timeline/Views/InnerTimelineView.swift b/damus/Features/Timeline/Views/InnerTimelineView.swift index 0e572f8f..49e83296 100644 --- a/damus/Features/Timeline/Views/InnerTimelineView.swift +++ b/damus/Features/Timeline/Views/InnerTimelineView.swift @@ -29,6 +29,26 @@ struct InnerTimelineView: View { var body: some View { LazyVStack(spacing: 0) { + let incomingEvents = events.incoming.filter({ filter($0) }) + if incomingEvents.count > 0 { + Button( + action: { + notify(.scroll_to_top) + }, + label: { + HStack(spacing: 6) { + CondensedProfilePicturesView(state: state, pubkeys: incomingEvents.map({ $0.pubkey }), maxPictures: 3) + Text("Load new content", comment: "Button to load new notes in the timeline") + .bold() + } + .padding(.horizontal, 20) + .padding(.vertical, 10) + } + ) + .buttonStyle(NeutralButtonStyle(cornerRadius: 50)) + .padding(.vertical, 10) + } + let events = self.events.events if events.isEmpty { EmptyTimelineView() diff --git a/damus/Features/Timeline/Views/TimelineView.swift b/damus/Features/Timeline/Views/TimelineView.swift index 8edff654..5ad84008 100644 --- a/damus/Features/Timeline/Views/TimelineView.swift +++ b/damus/Features/Timeline/Views/TimelineView.swift @@ -97,7 +97,7 @@ struct TimelineView: View { .coordinateSpace(name: "scroll") .onReceive(handle_notify(.scroll_to_top)) { () in events.flush() - self.events.should_queue = false + self.events.set_should_queue(false) scroll_to_event(scroller: scroller, id: "startblock", delay: 0.0, animate: true, anchor: .top) } } @@ -122,11 +122,8 @@ protocol ScrollQueue { func handle_scroll_queue(_ proxy: GeometryProxy, queue: ScrollQueue) { let offset = -proxy.frame(in: .named("scroll")).origin.y - guard offset >= 0 else { - return - } - let val = offset > 0 - if queue.should_queue != val { - queue.set_should_queue(val) + let new_should_queue = offset > 0 + if queue.should_queue != new_should_queue { + queue.set_should_queue(new_should_queue) } } diff --git a/damus/Shared/Utilities/EventHolder.swift b/damus/Shared/Utilities/EventHolder.swift index 868144ae..cd615f33 100644 --- a/damus/Shared/Utilities/EventHolder.swift +++ b/damus/Shared/Utilities/EventHolder.swift @@ -11,8 +11,8 @@ import Foundation class EventHolder: ObservableObject, ScrollQueue { private var has_event = Set() @Published var events: [NostrEvent] - var incoming: [NostrEvent] - var should_queue = false + @Published var incoming: [NostrEvent] + private(set) var should_queue = false var on_queue: ((NostrEvent) -> Void)? func set_should_queue(_ val: Bool) {