The user is able to search for naddr, nprofile & nevent bech32 entities. Additionally, these entities and others are able to have prefixes such as damus:nostr: and damus.io links. Closes: https://github.com/damus-io/damus/issues/1841 Closes: https://github.com/damus-io/damus/issues/1650 Changelog-Added: Add ability to search for naddr, nprofiles, nevents Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G Signed-off-by: kernelkind <kernelkind@gmail.com> Reviewed-by: William Casarin <jb55@jb55.com> Signed-off-by: William Casarin <jb55@jb55.com>
144 lines
4.5 KiB
Swift
144 lines
4.5 KiB
Swift
//
|
|
// SearchingEventView.swift
|
|
// damus
|
|
//
|
|
// Created by William Casarin on 2023-03-05.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
enum SearchState {
|
|
case searching
|
|
case found(NostrEvent)
|
|
case found_profile(Pubkey)
|
|
case not_found
|
|
}
|
|
|
|
enum SearchType: Equatable {
|
|
case event(NoteId)
|
|
case profile(Pubkey)
|
|
case nip05(String)
|
|
case naddr(NAddr)
|
|
}
|
|
|
|
@MainActor
|
|
struct SearchingEventView: View {
|
|
let state: DamusState
|
|
let search_type: SearchType
|
|
|
|
@State var search_state: SearchState = .searching
|
|
|
|
var search_name: String {
|
|
switch search_type {
|
|
case .nip05:
|
|
return "Nostr Address"
|
|
case .profile:
|
|
return "Profile"
|
|
case .event:
|
|
return "Note"
|
|
case .naddr:
|
|
return "Naddr"
|
|
}
|
|
}
|
|
|
|
func handle_search(search: SearchType) {
|
|
self.search_state = .searching
|
|
|
|
switch search {
|
|
case .nip05(let nip05):
|
|
if let pk = state.profiles.nip05_pubkey[nip05] {
|
|
if state.profiles.lookup_key_by_pubkey(pk) != nil {
|
|
self.search_state = .found_profile(pk)
|
|
}
|
|
} else {
|
|
Task {
|
|
guard let nip05 = NIP05.parse(nip05) else {
|
|
Task { @MainActor in
|
|
self.search_state = .not_found
|
|
}
|
|
return
|
|
}
|
|
guard let nip05_resp = await fetch_nip05(nip05: nip05) else {
|
|
Task { @MainActor in
|
|
self.search_state = .not_found
|
|
}
|
|
return
|
|
}
|
|
|
|
Task { @MainActor in
|
|
guard let pk = nip05_resp.names[nip05.username] else {
|
|
self.search_state = .not_found
|
|
return
|
|
}
|
|
|
|
self.search_state = .found_profile(pk)
|
|
}
|
|
}
|
|
}
|
|
|
|
case .event(let note_id):
|
|
find_event(state: state, query: .event(evid: note_id)) { res in
|
|
guard case .event(let ev) = res else {
|
|
self.search_state = .not_found
|
|
return
|
|
}
|
|
self.search_state = .found(ev)
|
|
}
|
|
case .profile(let pubkey):
|
|
find_event(state: state, query: .profile(pubkey: pubkey)) { res in
|
|
guard case .profile(let pubkey) = res else {
|
|
self.search_state = .not_found
|
|
return
|
|
}
|
|
self.search_state = .found_profile(pubkey)
|
|
}
|
|
case .naddr(let naddr):
|
|
naddrLookup(damus_state: state, naddr: naddr) { res in
|
|
guard let res = res else {
|
|
self.search_state = .not_found
|
|
return
|
|
}
|
|
self.search_state = .found(res)
|
|
}
|
|
}
|
|
}
|
|
|
|
var body: some View {
|
|
Group {
|
|
switch search_state {
|
|
case .searching:
|
|
HStack(spacing: 10) {
|
|
Text("Looking for \(search_name)...", comment: "Label that appears when searching for note or profile")
|
|
ProgressView()
|
|
.progressViewStyle(.circular)
|
|
}
|
|
case .found(let ev):
|
|
NavigationLink(value: Route.Thread(thread: ThreadModel(event: ev, damus_state: state))) {
|
|
EventView(damus: state, event: ev)
|
|
}
|
|
.buttonStyle(PlainButtonStyle())
|
|
case .found_profile(let pk):
|
|
NavigationLink(value: Route.ProfileByKey(pubkey: pk)) {
|
|
FollowUserView(target: .pubkey(pk), damus_state: state)
|
|
}
|
|
.buttonStyle(PlainButtonStyle())
|
|
case .not_found:
|
|
Text("\(search_name) not found", comment: "When a note or profile is not found when searching for it via its note id")
|
|
}
|
|
}
|
|
.onChange(of: search_type, debounceTime: 0.5) { stype in
|
|
handle_search(search: stype)
|
|
}
|
|
.onAppear {
|
|
handle_search(search: search_type)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct SearchingEventView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
let state = test_damus_state
|
|
SearchingEventView(state: state, search_type: .event(test_note.id))
|
|
}
|
|
}
|