damus

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

RelayDetailView.swift (8111B)


      1 //
      2 //  RelayDetailView.swift
      3 //  damus
      4 //
      5 //  Created by Joel Klabo on 2/1/23.
      6 //
      7 
      8 import SwiftUI
      9 
     10 struct RelayDetailView: View {
     11     let state: DamusState
     12     let relay: RelayURL
     13     let nip11: RelayMetadata?
     14 
     15     @ObservedObject var log: RelayLog
     16 
     17     @Environment(\.dismiss) var dismiss
     18 
     19     init(state: DamusState, relay: RelayURL, nip11: RelayMetadata?) {
     20         self.state = state
     21         self.relay = relay
     22         self.nip11 = nip11
     23         
     24         log = state.relay_model_cache.model(with_relay_id: relay)?.log ?? RelayLog()
     25     }
     26     
     27     func check_connection() -> Bool {
     28         for relay in state.pool.relays {
     29             if relay.id == self.relay {
     30                 return true
     31             }
     32         }
     33         return false
     34     }
     35 
     36     func RemoveRelayButton(_ keypair: FullKeypair) -> some View {
     37         Button(action: {
     38             guard let ev = state.contacts.event else {
     39                 return
     40             }
     41 
     42             let descriptors = state.pool.our_descriptors
     43             guard let new_ev = remove_relay( ev: ev, current_relays: descriptors, keypair: keypair, relay: relay) else {
     44                 return
     45             }
     46 
     47             process_contact_event(state: state, ev: new_ev)
     48             state.postbox.send(new_ev)
     49             
     50             if let relay_metadata = make_relay_metadata(relays: state.pool.our_descriptors, keypair: keypair) {
     51                 state.postbox.send(relay_metadata)
     52             }
     53             dismiss()
     54         }) {
     55             HStack {
     56                 Text("Disconnect", comment: "Button to disconnect from the relay.")
     57                     .fontWeight(.semibold)
     58             }
     59             .frame(minWidth: 300, maxWidth: .infinity, alignment: .center)
     60         }
     61         .buttonStyle(NeutralButtonShape.rounded.style)
     62     }
     63     
     64     func ConnectRelayButton(_ keypair: FullKeypair) -> some View {
     65         Button(action: {
     66             guard let ev_before_add = state.contacts.event else {
     67                 return
     68             }
     69             guard let ev_after_add = add_relay(ev: ev_before_add, keypair: keypair, current_relays: state.pool.our_descriptors, relay: relay, info: .rw) else {
     70                 return
     71             }
     72             process_contact_event(state: state, ev: ev_after_add)
     73             state.postbox.send(ev_after_add)
     74 
     75             if let relay_metadata = make_relay_metadata(relays: state.pool.our_descriptors, keypair: keypair) {
     76                 state.postbox.send(relay_metadata)
     77             }
     78             dismiss()
     79         }) {
     80             HStack {
     81                 Text("Connect", comment: "Button to connect to the relay.")
     82                     .fontWeight(.semibold)
     83             }
     84             .frame(minWidth: 300, maxWidth: .infinity, alignment: .center)
     85         }
     86         .buttonStyle(NeutralButtonShape.rounded.style)
     87     }
     88     
     89     var RelayInfo: some View {
     90         ScrollView(.horizontal) {
     91             Group {
     92                 HStack(spacing: 15) {
     93                     
     94                     RelayAdminDetail(state: state, nip11: nip11)
     95                     
     96                     Divider().frame(width: 1)
     97                     
     98                     RelaySoftwareDetail(nip11: nip11)
     99                     
    100                 }
    101             }
    102         }
    103         .scrollIndicators(.hidden)
    104     }
    105     
    106     var RelayHeader: some View {
    107         HStack(alignment: .top, spacing: 15) {
    108             RelayPicView(relay: relay, icon: nip11?.icon, size: 90, highlight: .none, disable_animation: false)
    109             
    110             VStack(alignment: .leading) {
    111                 Text(nip11?.name ?? relay.absoluteString)
    112                     .font(.title)
    113                     .fontWeight(.bold)
    114                     .lineLimit(1)
    115                 
    116                 Text(relay.absoluteString)
    117                     .font(.headline)
    118                     .fontWeight(.regular)
    119                     .foregroundColor(.gray)
    120                 
    121                 HStack {
    122                     if nip11?.is_paid ?? false {
    123                         RelayPaidDetail(payments_url: nip11?.payments_url, fees: nip11?.fees)
    124                     }
    125                     
    126                     if let authentication_state: RelayAuthenticationState = relay_object?.authentication_state,
    127                        authentication_state != .none {
    128                         RelayAuthenticationDetail(state: authentication_state)
    129                     }
    130                 }
    131             }
    132         }
    133     }
    134     
    135 
    136     var body: some View {
    137         NavigationView {
    138             Group {
    139                 ScrollView {
    140                     Divider()
    141                     VStack(alignment: .leading, spacing: 10) {
    142 
    143                         RelayHeader
    144                         
    145                         Divider()
    146                         
    147                         Text("Description")
    148                             .font(.subheadline)
    149                             .foregroundColor(DamusColors.mediumGrey)
    150 
    151                         Text(nip11?.description ?? "N/A")
    152                             .font(.subheadline)
    153                         
    154                         Divider()
    155                         
    156                         RelayInfo
    157                         
    158                         Divider()
    159                         
    160                         if let nip11 {
    161                             if let nips = nip11.supported_nips, nips.count > 0 {
    162                                 RelayNipList(nips: nips)
    163                                 Divider()
    164                             }
    165                         }
    166                         
    167                         if let keypair = state.keypair.to_full() {
    168                             if check_connection() {
    169                                 RemoveRelayButton(keypair)
    170                                     .padding(.top)
    171                             } else {
    172                                 ConnectRelayButton(keypair)
    173                                     .padding(.top)
    174                             }
    175                         }
    176                         
    177                         if state.settings.developer_mode {
    178                             Text("Relay Logs")
    179                                 .padding(.top)
    180                             Divider()
    181                             Text(log.contents ?? NSLocalizedString("No logs to display", comment: "Label to indicate that there are no developer mode logs available to be displayed on the screen"))
    182                                 .font(.system(size: 13))
    183                                 .lineLimit(nil)
    184                                 .fixedSize(horizontal: false, vertical: true)
    185                         }
    186                     }
    187                     .padding(.horizontal)
    188                 }
    189             }
    190         }
    191         .onReceive(handle_notify(.switched_timeline)) { notif in
    192             dismiss()
    193         }
    194         .navigationTitle(nip11?.name ?? relay.absoluteString)
    195         .navigationBarTitleDisplayMode(.inline)
    196         .navigationBarBackButtonHidden(true)
    197         .navigationBarItems(leading: BackNav())
    198         .ignoresSafeArea(.all)
    199         .toolbar {
    200             if let relay_connection {
    201                 RelayStatusView(connection: relay_connection)
    202             }
    203         }
    204     }
    205 
    206     private var relay_object: Relay? {
    207         state.pool.get_relay(relay)
    208     }
    209 
    210     private var relay_connection: RelayConnection? {
    211         relay_object?.connection
    212     }
    213 }
    214 
    215 struct RelayDetailView_Previews: PreviewProvider {
    216     static var previews: some View {
    217         let admission = Admission(amount: 1000000, unit: "msats")
    218         let sub = Subscription(amount: 5000000, unit: "msats", period: 2592000)
    219         let pub = Publication(kinds: [4], amount: 100, unit: "msats")
    220         let fees = Fees(admission: [admission], subscription: [sub], publication: [pub])
    221         let metadata = RelayMetadata(name: "name", description: "Relay description", pubkey: test_pubkey, contact: "contact@mail.com", supported_nips: [1,2,3], software: "software", version: "version", limitation: Limitations.empty, payments_url: "https://jb55.com", icon: "", fees: fees)
    222         RelayDetailView(state: test_damus_state, relay: RelayURL("wss://relay.damus.io")!, nip11: metadata)
    223     }
    224 }