damus

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

RelayPicView.swift (3898B)


      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             } else {
     59                 FailedRelayImage(url: nil)
     60             }
     61         }
     62         .frame(width: size, height: size)
     63         .clipShape(RoundedRectangle(cornerRadius: 15))
     64         .overlay(RoundedRectangle(cornerRadius: 15).stroke(.gray.opacity(0.5), lineWidth: 0.5))
     65     }
     66 }
     67 
     68 struct RelayPicView: View {
     69     let relay: RelayURL
     70     let icon: String?
     71     let size: CGFloat
     72     let highlight: Highlight
     73     let disable_animation: Bool
     74 
     75     init(relay: RelayURL, icon: String? = nil, size: CGFloat, highlight: Highlight, disable_animation: Bool) {
     76         self.relay = relay
     77         self.icon = icon
     78         self.size = size
     79         self.highlight = highlight
     80         self.disable_animation = disable_animation
     81     }
     82 
     83     var relay_url: URL? {
     84         get_relay_url(relay: relay, icon: icon)
     85     }
     86     
     87     var body: some View {
     88         InnerRelayPicView(url: relay_url, size: size, highlight: highlight, disable_animation: disable_animation)
     89     }
     90 }
     91 
     92 func extract_tld(_ host: String) -> String {
     93     let parts = host.split(separator: ".")
     94 
     95     if parts.count >= 3  {
     96         let last_3 = parts.suffix(3)
     97         if parts[1] == "co" && parts[2] == "uk" {
     98             return String(last_3.joined(separator: "."))
     99         } else {
    100             return String(parts.suffix(2).joined(separator: "."))
    101         }
    102     } else if parts.count == 2 {
    103         return host
    104     }
    105 
    106     return host
    107 }
    108 
    109 func get_relay_url(relay: RelayURL, icon: String?) -> URL? {
    110     var favicon = relay.absoluteString + "/favicon.ico"
    111     let tld = extract_tld(relay.absoluteString)
    112     if tld != relay.absoluteString {
    113         favicon = "https://" + tld + "/favicon.ico"
    114     }
    115     let pic = icon ?? favicon
    116     return URL(string: pic)
    117 }
    118 
    119 struct RelayPicView_Previews: PreviewProvider {
    120     static var previews: some View {
    121         VStack {
    122             RelayPicView(relay: RelayURL("wss://relay.damus.io")!, size: 55, highlight: .none, disable_animation: false)
    123             RelayPicView(relay: RelayURL("wss://nostr.wine")!, size: 55, highlight: .none, disable_animation: false)
    124             RelayPicView(relay: RelayURL("wss://nos.lol")!, size: 55, highlight: .none, disable_animation: false)
    125             RelayPicView(relay: RelayURL("wss://fail.com")!, size: 55, highlight: .none, disable_animation: false)
    126         }
    127     }
    128 }
    129