Improve loading UX in the home timeline
Changelog-Changed: Improved loading UX in the home timeline Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
@@ -41,7 +41,7 @@ enum HomeResubFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HomeModel: ContactsDelegate {
|
class HomeModel: ContactsDelegate, ObservableObject {
|
||||||
// The maximum amount of contacts placed on a home feed subscription filter.
|
// The maximum amount of contacts placed on a home feed subscription filter.
|
||||||
// If the user has more contacts, chunking or other techniques will be used to avoid sending huge filters
|
// If the user has more contacts, chunking or other techniques will be used to avoid sending huge filters
|
||||||
let MAX_CONTACTS_ON_FILTER = 500
|
let MAX_CONTACTS_ON_FILTER = 500
|
||||||
@@ -71,7 +71,7 @@ class HomeModel: ContactsDelegate {
|
|||||||
var dmsHandlerTask: Task<Void, Never>?
|
var dmsHandlerTask: Task<Void, Never>?
|
||||||
var nwcHandlerTask: Task<Void, Never>?
|
var nwcHandlerTask: Task<Void, Never>?
|
||||||
|
|
||||||
var loading: Bool = false
|
@Published var loading: Bool = true
|
||||||
|
|
||||||
var signal = SignalModel()
|
var signal = SignalModel()
|
||||||
|
|
||||||
@@ -658,6 +658,9 @@ class HomeModel: ContactsDelegate {
|
|||||||
|
|
||||||
self.homeHandlerTask?.cancel()
|
self.homeHandlerTask?.cancel()
|
||||||
self.homeHandlerTask = Task {
|
self.homeHandlerTask = Task {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.loading = true
|
||||||
|
}
|
||||||
for await item in damus_state.nostrNetwork.reader.subscribe(filters: home_filters) {
|
for await item in damus_state.nostrNetwork.reader.subscribe(filters: home_filters) {
|
||||||
switch item {
|
switch item {
|
||||||
case .event(let borrow):
|
case .event(let borrow):
|
||||||
@@ -669,6 +672,9 @@ class HomeModel: ContactsDelegate {
|
|||||||
await self.process_event(ev: event, context: .home)
|
await self.process_event(ev: event, context: .home)
|
||||||
case .eose:
|
case .eose:
|
||||||
guard let txn = NdbTxn(ndb: damus_state.ndb) else { return }
|
guard let txn = NdbTxn(ndb: damus_state.ndb) else { return }
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.loading = false
|
||||||
|
}
|
||||||
load_profiles(context: "home", load: .from_events(events.events), damus_state: damus_state, txn: txn)
|
load_profiles(context: "home", load: .from_events(events.events), damus_state: damus_state, txn: txn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import SwiftUI
|
|||||||
struct PostingTimelineView: View {
|
struct PostingTimelineView: View {
|
||||||
|
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
var home: HomeModel
|
@ObservedObject var home: HomeModel
|
||||||
@State var search: String = ""
|
@State var search: String = ""
|
||||||
@State var results: [NostrEvent] = []
|
@State var results: [NostrEvent] = []
|
||||||
@State var initialOffset: CGFloat?
|
@State var initialOffset: CGFloat?
|
||||||
@@ -25,6 +25,14 @@ struct PostingTimelineView: View {
|
|||||||
@State var headerHeight: CGFloat = 0
|
@State var headerHeight: CGFloat = 0
|
||||||
@Binding var headerOffset: CGFloat
|
@Binding var headerOffset: CGFloat
|
||||||
@SceneStorage("PostingTimelineView.filter_state") var filter_state : FilterState = .posts_and_replies
|
@SceneStorage("PostingTimelineView.filter_state") var filter_state : FilterState = .posts_and_replies
|
||||||
|
|
||||||
|
var loading: Binding<Bool> {
|
||||||
|
Binding(get: {
|
||||||
|
return home.loading
|
||||||
|
}, set: {
|
||||||
|
home.loading = $0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func content_filter(_ fstate: FilterState) -> ((NostrEvent) -> Bool) {
|
func content_filter(_ fstate: FilterState) -> ((NostrEvent) -> Bool) {
|
||||||
var filters = ContentFilters.defaults(damus_state: damus_state)
|
var filters = ContentFilters.defaults(damus_state: damus_state)
|
||||||
@@ -33,7 +41,7 @@ struct PostingTimelineView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func contentTimelineView(filter: (@escaping (NostrEvent) -> Bool)) -> some View {
|
func contentTimelineView(filter: (@escaping (NostrEvent) -> Bool)) -> some View {
|
||||||
TimelineView<AnyView>(events: home.events, loading: .constant(false), headerHeight: $headerHeight, headerOffset: $headerOffset, damus: damus_state, show_friend_icon: false, filter: filter)
|
TimelineView<AnyView>(events: home.events, loading: self.loading, headerHeight: $headerHeight, headerOffset: $headerOffset, damus: damus_state, show_friend_icon: false, filter: filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HeaderView()->some View {
|
func HeaderView()->some View {
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ struct TimelineView<Content: View>: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.coordinateSpace(name: "scroll")
|
.coordinateSpace(name: "scroll")
|
||||||
|
.disabled(self.loading)
|
||||||
.onReceive(handle_notify(.scroll_to_top)) { () in
|
.onReceive(handle_notify(.scroll_to_top)) { () in
|
||||||
events.flush()
|
events.flush()
|
||||||
self.events.set_should_queue(false)
|
self.events.set_should_queue(false)
|
||||||
|
|||||||
Reference in New Issue
Block a user