damus

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

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 }