damus

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

EventLoaderView.swift (2384B)


      1 //
      2 //  EventLoaderView.swift
      3 //  damus
      4 //
      5 //  Created by Daniel D’Aquino on 2023-09-27.
      6 //
      7 
      8 import SwiftUI
      9 
     10 /// This view handles the loading logic for Nostr events, so that you can easily use views that require `NostrEvent`, even if you only have a `NoteId`
     11 struct EventLoaderView<Content: View>: View {
     12     let damus_state: DamusState
     13     let event_id: NoteId
     14     @State var event: NostrEvent?
     15     @State var subscription_uuid: String = UUID().description
     16     let content: (NostrEvent) -> Content
     17     
     18     init(damus_state: DamusState, event_id: NoteId, @ViewBuilder content: @escaping (NostrEvent) -> Content) {
     19         self.damus_state = damus_state
     20         self.event_id = event_id
     21         self.content = content
     22         let event = damus_state.events.lookup(event_id)
     23         _event = State(initialValue: event)
     24     }
     25     
     26     func unsubscribe() {
     27         damus_state.pool.unsubscribe(sub_id: subscription_uuid)
     28     }
     29     
     30     func subscribe(filters: [NostrFilter]) {
     31         damus_state.pool.register_handler(sub_id: subscription_uuid, handler: handle_event)
     32         damus_state.pool.send(.subscribe(.init(filters: filters, sub_id: subscription_uuid)))
     33     }
     34 
     35     func handle_event(relay_id: RelayURL, ev: NostrConnectionEvent) {
     36         guard case .nostr_event(let nostr_response) = ev else {
     37             return
     38         }
     39         
     40         guard case .event(let id, let nostr_event) = nostr_response else {
     41             return
     42         }
     43         
     44         guard id == subscription_uuid else {
     45             return
     46         }
     47         
     48         if event != nil {
     49             return
     50         }
     51         
     52         event = nostr_event
     53         
     54         unsubscribe()
     55     }
     56     
     57     func load() {
     58         subscribe(filters: [
     59             NostrFilter(ids: [self.event_id], limit: 1)
     60         ])
     61     }
     62     
     63     var body: some View {
     64         VStack {
     65             if let event {
     66                 self.content(event)
     67             } else {
     68                 ProgressView().padding()
     69             }
     70         }
     71         .onAppear {
     72             guard event == nil else {
     73                 return
     74             }
     75             self.load()
     76         }
     77     }
     78 }
     79 
     80 
     81 struct EventLoaderView_Previews: PreviewProvider {
     82     static var previews: some View {
     83         EventLoaderView(damus_state: test_damus_state, event_id: test_note.id) { event in
     84             EventView(damus: test_damus_state, event: event)
     85         }
     86     }
     87 }