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 }