damus

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

RelayPicView.swift (3933B)


      1 //
      2 //  RelayPicView.swift
      3 //  damus
      4 //
      5 //  Created by eric on 9/2/23.
      6 //
      7 
      8 import SwiftUI
      9 import Kingfisher
     10 
     11 struct FailedRelayImage: View {
     12     let url: URL?
     13 
     14     var body: some View {
     15         let abbrv = String(url?.host()?.first?.uppercased() ?? "R")
     16         Text(abbrv)
     17             .font(.system(size: 40, weight: .bold))
     18     }
     19 }
     20 
     21 struct InnerRelayPicView: View {
     22     let url: URL?
     23     let size: CGFloat
     24     let highlight: Highlight
     25     let disable_animation: Bool
     26     @State var failedImage: Bool = false
     27 
     28     func Placeholder(url: URL?) -> some View {
     29         ZStack {
     30             RoundedRectangle(cornerRadius: 15)
     31                 .frame(width: size, height: size)
     32                 .foregroundColor(DamusColors.adaptableGrey)
     33                 .overlay(RoundedRectangle(cornerRadius: 15).stroke(highlight_color(highlight), lineWidth: pfp_line_width(highlight)))
     34                 .padding(2)
     35 
     36             FailedRelayImage(url: url)
     37         }
     38     }
     39 
     40     var body: some View {
     41         ZStack {
     42             Color(uiColor: .secondarySystemBackground)
     43 
     44             if let url {
     45                 KFAnimatedImage(url)
     46                     .imageContext(.pfp, disable_animation: disable_animation)
     47                     .onFailure { _ in
     48                         failedImage = true
     49                     }
     50                     .cancelOnDisappear(true)
     51                     .configure { view in
     52                         view.framePreloadCount = 3
     53                     }
     54                     .placeholder { _ in
     55                         Placeholder(url: url)
     56                     }
     57                     .scaledToFit()
     58                     .kfClickable()
     59             } else {
     60                 FailedRelayImage(url: nil)
     61             }
     62         }
     63         .frame(width: size, height: size)
     64         .clipShape(RoundedRectangle(cornerRadius: 15))
     65         .overlay(RoundedRectangle(cornerRadius: 15).stroke(.gray.opacity(0.5), lineWidth: 0.5))
     66     }
     67 }
     68 
     69 struct RelayPicView: View {
     70     let relay: RelayURL
     71     let icon: String?
     72     let size: CGFloat
     73     let highlight: Highlight
     74     let disable_animation: Bool
     75 
     76     init(relay: RelayURL, icon: String? = nil, size: CGFloat, highlight: Highlight, disable_animation: Bool) {
     77         self.relay = relay
     78         self.icon = icon
     79         self.size = size
     80         self.highlight = highlight
     81         self.disable_animation = disable_animation
     82     }
     83 
     84     var relay_url: URL? {
     85         get_relay_url(relay: relay, icon: icon)
     86     }
     87     
     88     var body: some View {
     89         InnerRelayPicView(url: relay_url, size: size, highlight: highlight, disable_animation: disable_animation)
     90     }
     91 }
     92 
     93 func extract_tld(_ host: String) -> String {
     94     let parts = host.split(separator: ".")
     95 
     96     if parts.count >= 3  {
     97         let last_3 = parts.suffix(3)
     98         if parts[1] == "co" && parts[2] == "uk" {
     99             return String(last_3.joined(separator: "."))
    100         } else {
    101             return String(parts.suffix(2).joined(separator: "."))
    102         }
    103     } else if parts.count == 2 {
    104         return host
    105     }
    106 
    107     return host
    108 }
    109 
    110 func get_relay_url(relay: RelayURL, icon: String?) -> URL? {
    111     var favicon = relay.absoluteString + "/favicon.ico"
    112     let tld = extract_tld(relay.absoluteString)
    113     if tld != relay.absoluteString {
    114         favicon = "https://" + tld + "/favicon.ico"
    115     }
    116     let pic = icon ?? favicon
    117     return URL(string: pic)
    118 }
    119 
    120 struct RelayPicView_Previews: PreviewProvider {
    121     static var previews: some View {
    122         VStack {
    123             RelayPicView(relay: RelayURL("wss://relay.damus.io")!, size: 55, highlight: .none, disable_animation: false)
    124             RelayPicView(relay: RelayURL("wss://nostr.wine")!, size: 55, highlight: .none, disable_animation: false)
    125             RelayPicView(relay: RelayURL("wss://nos.lol")!, size: 55, highlight: .none, disable_animation: false)
    126             RelayPicView(relay: RelayURL("wss://fail.com")!, size: 55, highlight: .none, disable_animation: false)
    127         }
    128     }
    129 }
    130