damus

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

commit 2c4c392b76d9ad92b28e71d6d578bdb42c2ac3de
parent 1d1804c1035beb70713cd9e6db27f22183d9e841
Author: William Casarin <jb55@jb55.com>
Date:   Sat,  8 Oct 2022 16:03:57 -0700

search hashtags, profiles, notes

Changelog-Added: Search hashtags, profiles, events
Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mdamus.xcodeproj/project.pbxproj | 8++++----
Mdamus/ContentView.swift | 26++++++++++----------------
Mdamus/Models/ThreadModel.swift | 14++------------
Mdamus/Views/SearchResultsView.swift | 92++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 103 insertions(+), 37 deletions(-)

diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj @@ -844,7 +844,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = damus/damus.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\""; DEVELOPMENT_TEAM = XK7H4JAB3D; ENABLE_PREVIEWS = YES; @@ -864,7 +864,7 @@ "$(inherited)", "$(PROJECT_DIR)", ); - MARKETING_VERSION = 0.1.3; + MARKETING_VERSION = 0.1.4; PRODUCT_BUNDLE_IDENTIFIER = com.jb55.damus2; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -880,7 +880,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = damus/damus.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\""; DEVELOPMENT_TEAM = XK7H4JAB3D; ENABLE_PREVIEWS = YES; @@ -900,7 +900,7 @@ "$(inherited)", "$(PROJECT_DIR)", ); - MARKETING_VERSION = 0.1.3; + MARKETING_VERSION = 0.1.4; PRODUCT_BUNDLE_IDENTIFIER = com.jb55.damus2; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/damus/ContentView.swift b/damus/ContentView.swift @@ -73,23 +73,17 @@ struct ContentView: View { let sub_id = UUID().description var LoadingContainer: some View { - VStack { - HStack(alignment: .center) { - Spacer() - - if home.signal.signal != home.signal.max_signal { - Text("\(home.signal.signal)/\(home.signal.max_signal)") - .font(.callout) - .foregroundColor(.gray) - } - - NavigationLink(destination: ConfigView(state: damus_state!)) { - Label("", systemImage: "gear") - } - .buttonStyle(PlainButtonStyle()) + HStack(alignment: .center) { + if home.signal.signal != home.signal.max_signal { + Text("\(home.signal.signal)/\(home.signal.max_signal)") + .font(.callout) + .foregroundColor(.gray) } - - Spacer() + + NavigationLink(destination: ConfigView(state: damus_state!)) { + Label("", systemImage: "gear") + } + .buttonStyle(PlainButtonStyle()) } } diff --git a/damus/Models/ThreadModel.swift b/damus/Models/ThreadModel.swift @@ -30,8 +30,6 @@ enum InitialEvent { /// manages the lifetime of a thread class ThreadModel: ObservableObject { - let kind: Int - @Published var initial_event: InitialEvent @Published var events: [NostrEvent] = [] @Published var event_map: [String: Int] = [:] @@ -61,19 +59,11 @@ class ThreadModel: ObservableObject { init(evid: String, damus_state: DamusState) { self.damus_state = damus_state self.initial_event = .event_id(evid) - self.kind = NostrKind.text.rawValue } init(event: NostrEvent, damus_state: DamusState) { self.damus_state = damus_state self.initial_event = .event(event) - self.kind = NostrKind.text.rawValue - } - - init(event: NostrEvent, damus_state: DamusState, kind: Int) { - self.damus_state = damus_state - self.initial_event = .event(event) - self.kind = kind } func unsubscribe() { @@ -129,10 +119,10 @@ class ThreadModel: ObservableObject { events_filter.limit = 100 events_filter.ids?.append(ev.id) case .event_id(let evid): - events_filter.ids = [evid] - events_filter.limit = 100 ref_events.referenced_ids = [evid] ref_events.limit = 50 + events_filter.ids = [evid] + events_filter.limit = 100 } //likes_filter.ids = ref_events.referenced_ids! diff --git a/damus/Views/SearchResultsView.swift b/damus/Views/SearchResultsView.swift @@ -7,10 +7,18 @@ import SwiftUI +enum Search { + case profiles([(String, Profile)]) + case hashtag(String) + case profile(String) + case note(String) + case hex(String) +} + struct SearchResultsView: View { let damus_state: DamusState @Binding var search: String - @State var results: [(String, Profile)] = [] + @State var result: Search? = nil func ProfileSearchResult(pk: String, res: Profile) -> some View { FollowUserView(target: .pubkey(pk), damus_state: damus_state) @@ -18,17 +26,90 @@ struct SearchResultsView: View { var MainContent: some View { ScrollView { - LazyVStack { - ForEach(results, id: \.0) { prof in - ProfileSearchResult(pk: prof.0, res: prof.1) + Group { + switch result { + case .profiles(let results): + LazyVStack { + ForEach(results, id: \.0) { prof in + ProfileSearchResult(pk: prof.0, res: prof.1) + } + } + case .hashtag(let ht): + let search_model = SearchModel(pool: damus_state.pool, search: .filter_hashtag([ht])) + let dst = SearchView(appstate: damus_state, search: search_model) + NavigationLink(destination: dst) { + Text("Search hashtag: #\(ht)") + } + case .profile(let prof): + let decoded = try? bech32_decode(prof) + let hex = hex_encode(decoded!.data) + let prof_model = ProfileModel(pubkey: hex, damus: damus_state) + let f = FollowersModel(damus_state: damus_state, target: prof) + let dst = ProfileView(damus_state: damus_state, profile: prof_model, followers: f) + NavigationLink(destination: dst) { + Text("Goto profile \(prof)") + } + case .hex(let h): + let prof_model = ProfileModel(pubkey: h, damus: damus_state) + let f = FollowersModel(damus_state: damus_state, target: h) + let prof_view = ProfileView(damus_state: damus_state, profile: prof_model, followers: f) + let thread_model = ThreadModel(evid: h, damus_state: damus_state) + let ev_view = ThreadView(thread: thread_model, damus: damus_state, is_chatroom: false) + VStack(spacing: 50) { + NavigationLink(destination: prof_view) { + Text("Goto profile \(h)") + } + NavigationLink(destination: ev_view) { + Text("Goto post \(h)") + } + } + case .note(let nid): + let decoded = try? bech32_decode(nid) + let hex = hex_encode(decoded!.data) + let thread_model = ThreadModel(evid: hex, damus_state: damus_state) + let ev_view = ThreadView(thread: thread_model, damus: damus_state, is_chatroom: false) + NavigationLink(destination: ev_view) { + Text("Goto post \(nid)") + } + case .none: + Text("none") } } } } func search_changed(_ new: String) { + guard new.count != 0 else { + return + } + + if new.first! == "#" { + let ht = String(new.dropFirst()) + self.result = .hashtag(ht) + return + } + + if let _ = hex_decode(new), new.count == 64 { + self.result = .hex(new) + return + } + + if new.starts(with: "npub") { + if let _ = try? bech32_decode(new) { + self.result = .profile(new) + return + } + } + + if new.starts(with: "note") { + if let _ = try? bech32_decode(new) { + self.result = .note(new) + return + } + } + let profs = damus_state.profiles.profiles.enumerated() - self.results = profs.reduce(into: []) { acc, els in + let results: [(String, Profile)] = profs.reduce(into: []) { acc, els in let pk = els.element.key let prof = els.element.value.profile let lowname = prof.name.map { $0.lowercased() } @@ -43,6 +124,7 @@ struct SearchResultsView: View { } } + self.result = .profiles(results) } var body: some View {