SearchingEventView.swift (4611B)
1 // 2 // SearchingEventView.swift 3 // damus 4 // 5 // Created by William Casarin on 2023-03-05. 6 // 7 8 import SwiftUI 9 10 enum SearchState { 11 case searching 12 case found(NostrEvent) 13 case found_profile(Pubkey) 14 case not_found 15 } 16 17 enum SearchType: Equatable { 18 case event(NoteId) 19 case profile(Pubkey) 20 case nip05(String) 21 case naddr(NAddr) 22 } 23 24 @MainActor 25 struct SearchingEventView: View { 26 let state: DamusState 27 let search_type: SearchType 28 29 @State var search_state: SearchState = .searching 30 31 var search_name: String { 32 switch search_type { 33 case .nip05: 34 return "Nostr Address" 35 case .profile: 36 return "Profile" 37 case .event: 38 return "Note" 39 case .naddr: 40 return "Naddr" 41 } 42 } 43 44 func handle_search(search: SearchType) { 45 self.search_state = .searching 46 47 switch search { 48 case .nip05(let nip05): 49 if let pk = state.profiles.nip05_pubkey[nip05] { 50 if state.profiles.lookup_key_by_pubkey(pk) != nil { 51 self.search_state = .found_profile(pk) 52 } 53 } else { 54 Task { 55 guard let nip05 = NIP05.parse(nip05) else { 56 Task { @MainActor in 57 self.search_state = .not_found 58 } 59 return 60 } 61 guard let nip05_resp = await fetch_nip05(nip05: nip05) else { 62 Task { @MainActor in 63 self.search_state = .not_found 64 } 65 return 66 } 67 68 Task { @MainActor in 69 guard let pk = nip05_resp.names[nip05.username] else { 70 self.search_state = .not_found 71 return 72 } 73 74 self.search_state = .found_profile(pk) 75 } 76 } 77 } 78 79 case .event(let note_id): 80 find_event(state: state, query: .event(evid: note_id)) { res in 81 guard case .event(let ev) = res else { 82 self.search_state = .not_found 83 return 84 } 85 self.search_state = .found(ev) 86 } 87 case .profile(let pubkey): 88 find_event(state: state, query: .profile(pubkey: pubkey)) { res in 89 guard case .profile(let pubkey) = res else { 90 self.search_state = .not_found 91 return 92 } 93 self.search_state = .found_profile(pubkey) 94 } 95 case .naddr(let naddr): 96 naddrLookup(damus_state: state, naddr: naddr) { res in 97 guard let res = res else { 98 self.search_state = .not_found 99 return 100 } 101 self.search_state = .found(res) 102 } 103 } 104 } 105 106 var body: some View { 107 Group { 108 switch search_state { 109 case .searching: 110 HStack(spacing: 10) { 111 Text("Looking for \(search_name)...", comment: "Label that appears when searching for note or profile") 112 ProgressView() 113 .progressViewStyle(.circular) 114 } 115 case .found(let ev): 116 NavigationLink(value: Route.Thread(thread: ThreadModel(event: ev, damus_state: state))) { 117 EventView(damus: state, event: ev) 118 } 119 .buttonStyle(PlainButtonStyle()) 120 case .found_profile(let pk): 121 NavigationLink(value: Route.ProfileByKey(pubkey: pk)) { 122 FollowUserView(target: .pubkey(pk), damus_state: state) 123 } 124 .buttonStyle(PlainButtonStyle()) 125 case .not_found: 126 Text("\(search_name) not found", comment: "When a note or profile is not found when searching for it via its note id") 127 } 128 } 129 .onChange(of: search_type, debounceTime: 0.5) { stype in 130 handle_search(search: stype) 131 } 132 .onAppear { 133 handle_search(search: search_type) 134 } 135 } 136 } 137 138 struct SearchingEventView_Previews: PreviewProvider { 139 static var previews: some View { 140 let state = test_damus_state 141 SearchingEventView(state: state, search_type: .event(test_note.id)) 142 } 143 }