damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | LICENSE

commit cb463c6da99bfca9cb4979081f7a2e97f32dea7e
parent 090385d3da19b7a7eafadd1c15f65a03feb9d403
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 23 Apr 2022 18:21:45 -0700

a bunch more usability improvements

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mdamus/ContentView.swift | 11++++++++---
Mdamus/Models/ThreadModel.swift | 32++++++++++++++++++++++++++++----
Mdamus/Nostr/NostrEvent.swift | 14++++++++++++++
Mdamus/Notifications.swift | 12++++++++++++
Mdamus/Views/ChatView.swift | 2+-
Mdamus/Views/ThreadView.swift | 4++++
Mdamus/Views/TimelineView.swift | 36++++++++++++++++++++++--------------
7 files changed, 89 insertions(+), 22 deletions(-)

diff --git a/damus/ContentView.swift b/damus/ContentView.swift @@ -213,7 +213,6 @@ struct ContentView: View { self.pool?.send(.event(ev)) } .onReceive(NotificationCenter.default.publisher(for: .post)) { obj in - let post_res = obj.object as! NostrPostResult switch post_res { case .post(let post): @@ -256,13 +255,19 @@ struct ContentView: View { } func switch_timeline(_ timeline: Timeline) { - if timeline != .notifications { + if timeline == self.selected_timeline { + NotificationCenter.default.post(name: .scroll_to_top, object: nil) + return + } + + if (timeline != .notifications && self.selected_timeline == .notifications) || timeline == .notifications { new_notifications = false } self.selected_timeline = timeline + NotificationCenter.default.post(name: .switched_timeline, object: timeline) //self.selected_timeline = timeline } - + func add_relay(_ pool: RelayPool, _ relay: String) { //add_rw_relay(pool, "wss://nostr-pub.wellorder.net") add_rw_relay(pool, relay) diff --git a/damus/Models/ThreadModel.swift b/damus/Models/ThreadModel.swift @@ -36,11 +36,35 @@ class ThreadModel: ObservableObject { self.replies.replies.removeAll() } + func should_resubscribe(_ ev_b: NostrEvent) -> Bool { + if self.events.count == 0 { + return true + } + + guard let ev_a = self.event else { + return true + } + + if ev_b.is_root_event() { + return false + } + + // rough heuristic to save us from resubscribing all the time + return ev_b.count_ids() != ev_a.count_ids() + } + func set_active_event(_ ev: NostrEvent) { - unsubscribe() - self.event = ev - add_event(ev) - subscribe(ev) + if should_resubscribe(ev) { + unsubscribe() + self.event = ev + add_event(ev) + subscribe(ev) + } else { + self.event = ev + if events.count == 0 { + add_event(ev) + } + } } private func subscribe(_ ev: NostrEvent) { diff --git a/damus/Nostr/NostrEvent.swift b/damus/Nostr/NostrEvent.swift @@ -179,6 +179,20 @@ class NostrEvent: Codable, Identifiable, CustomStringConvertible { return (ns, c) } + public func count_ids() -> Int { + return count_refs("e") + } + + public func count_refs(_ type: String) -> Int { + var count: Int = 0 + for tag in tags { + if tag.count >= 2 && tag[0] == "e" { + count += 1 + } + } + return count + } + public var referenced_pubkeys: [ReferencedId] { return get_referenced_ids(key: "p") } diff --git a/damus/Notifications.swift b/damus/Notifications.swift @@ -26,6 +26,18 @@ extension Notification.Name { } extension Notification.Name { + static var switched_timeline: Notification.Name { + return Notification.Name("switched_timeline") + } +} + +extension Notification.Name { + static var scroll_to_top: Notification.Name { + return Notification.Name("scroll_to_to") + } +} + +extension Notification.Name { static var broadcast_event: Notification.Name { return Notification.Name("broadcast event") } diff --git a/damus/Views/ChatView.swift b/damus/Views/ChatView.swift @@ -148,7 +148,7 @@ struct ChatView: View { .contentShape(Rectangle()) .id(event.id) .frame(minHeight: just_started ? PFP_SIZE : 0) - //.padding([.bottom], next_ev == nil ? 2 : 0) + .padding([.bottom], next_ev == nil ? 30 : 0) //.border(Color.green) } diff --git a/damus/Views/ThreadView.swift b/damus/Views/ThreadView.swift @@ -13,6 +13,7 @@ struct ThreadView: View { @EnvironmentObject var profiles: Profiles @EnvironmentObject var thread: ThreadModel + @Environment(\.dismiss) var dismiss var body: some View { Group { @@ -35,6 +36,9 @@ struct ThreadView: View { } */ } + .onReceive(NotificationCenter.default.publisher(for: .switched_timeline)) { n in + dismiss() + } .onReceive(NotificationCenter.default.publisher(for: .toggle_thread_view)) { _ in is_chatroom = !is_chatroom //print("is_chatroom: \(is_chatroom)") diff --git a/damus/Views/TimelineView.swift b/damus/Views/TimelineView.swift @@ -26,22 +26,30 @@ struct TimelineView: View { } var MainContent: some View { - ScrollView { - LazyVStack { - ForEach(events, id: \.id) { (ev: NostrEvent) in - /* - let evdet = EventDetailView(thread: ThreadModel(event: ev, pool: pool)) - .navigationBarTitle("Thread") - .padding([.leading, .trailing], 6) - .environmentObject(profiles) - */ - - EventView(event: ev, highlight: .none, has_action_bar: true) - .onTapGesture { - NotificationCenter.default.post(name: .open_thread, object: ev) - } + ScrollViewReader { scroller in + ScrollView { + LazyVStack { + ForEach(events, id: \.id) { (ev: NostrEvent) in + /* + let evdet = EventDetailView(thread: ThreadModel(event: ev, pool: pool)) + .navigationBarTitle("Thread") + .padding([.leading, .trailing], 6) + .environmentObject(profiles) + */ + + EventView(event: ev, highlight: .none, has_action_bar: true) + .onTapGesture { + NotificationCenter.default.post(name: .open_thread, object: ev) + } + } } } + .onReceive(NotificationCenter.default.publisher(for: .scroll_to_top)) { _ in + guard let event = events.first else { + return + } + scroll_to_event(scroller: scroller, id: event.id, delay: 0.0, animate: true) + } } } }