damus

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

BannerImageView.swift (4554B)


      1 //
      2 //  BannerImageView.swift
      3 //  damus
      4 //
      5 //  Created by Jason Jōb on 2023-01-10.
      6 //
      7 
      8 import SwiftUI
      9 import Kingfisher
     10 
     11 struct EditBannerImageView: View {
     12     
     13     var damus_state: DamusState
     14     @ObservedObject var viewModel: ImageUploadingObserver
     15     let callback: (URL?) -> Void
     16     let defaultImage = UIImage(named: "damoose") ?? UIImage()
     17     let safeAreaInsets: EdgeInsets
     18     
     19     @State var banner_image: URL? = nil
     20 
     21     var body: some View {
     22         ZStack {
     23             Color(uiColor: .systemBackground)
     24             KFAnimatedImage(get_banner_url(banner: banner_image?.absoluteString, pubkey: damus_state.pubkey, profiles: damus_state.profiles))
     25                 .imageContext(.banner, disable_animation: damus_state.settings.disable_animation)
     26                 .configure { view in
     27                     view.framePreloadCount = .max
     28                 }
     29                 .placeholder { _ in
     30                     Color(uiColor: .secondarySystemBackground)
     31                 }
     32                 .onFailureImage(defaultImage)
     33                 .kfClickable()
     34             
     35             EditPictureControl(
     36                 uploader: damus_state.settings.default_media_uploader,
     37                 context: .normal,
     38                 keypair: damus_state.keypair,
     39                 pubkey: damus_state.pubkey,
     40                 current_image_url: $banner_image,
     41                 upload_observer: viewModel,
     42                 callback: callback
     43             )
     44                 .padding(10)
     45                 .backwardsCompatibleSafeAreaPadding(self.safeAreaInsets)
     46                 .accessibilityLabel(NSLocalizedString("Edit banner image", comment: "Accessibility label for edit banner image button"))
     47                 .accessibilityIdentifier(AppAccessibilityIdentifiers.own_profile_banner_image_edit_button.rawValue)
     48         }
     49     }
     50 }
     51 
     52 extension View {
     53     fileprivate func backwardsCompatibleSafeAreaPadding(_ insets: EdgeInsets) -> some View {
     54         if #available(iOS 17.0, *) {
     55             return self.safeAreaPadding(insets)
     56         } else {
     57             return self.padding(.top, insets.top)
     58         }
     59     }
     60 }
     61 
     62 struct InnerBannerImageView: View {
     63     let disable_animation: Bool
     64     let url: URL?
     65     let defaultImage = UIImage(named: "damoose") ?? UIImage()
     66 
     67     var body: some View {
     68         ZStack {
     69             Color(uiColor: .systemBackground)
     70             
     71             if (url != nil) {
     72                 KFAnimatedImage(url)
     73                     .imageContext(.banner, disable_animation: disable_animation)
     74                     .configure { view in
     75                         view.framePreloadCount = 3
     76                     }
     77                     .placeholder { _ in
     78                         Color(uiColor: .secondarySystemBackground)
     79                     }
     80                     .onFailureImage(defaultImage)
     81                     .kfClickable()
     82             } else {
     83                 Image(uiImage: defaultImage).resizable()
     84             }
     85         }
     86     }
     87 }
     88 
     89 struct BannerImageView: View {
     90     let disable_animation: Bool
     91     let pubkey: Pubkey
     92     let profiles: Profiles
     93     
     94     @State var banner: String?
     95     
     96     init(pubkey: Pubkey, profiles: Profiles, disable_animation: Bool, banner: String? = nil) {
     97         self.pubkey = pubkey
     98         self.profiles = profiles
     99         self._banner = State(initialValue: banner)
    100         self.disable_animation = disable_animation
    101     }
    102     
    103     var body: some View {
    104         InnerBannerImageView(disable_animation: disable_animation, url: get_banner_url(banner: banner, pubkey: pubkey, profiles: profiles))
    105             .onReceive(handle_notify(.profile_updated)) { updated in
    106                 guard updated.pubkey == self.pubkey,
    107                       let profile_txn = profiles.lookup(id: updated.pubkey)
    108                 else {
    109                     return
    110                 }
    111 
    112                 let profile = profile_txn.unsafeUnownedValue
    113                 if let bannerImage = profile?.banner, bannerImage != self.banner {
    114                     self.banner = bannerImage
    115                 }
    116             }
    117     }
    118 }
    119 
    120 func get_banner_url(banner: String?, pubkey: Pubkey, profiles: Profiles) -> URL? {
    121     let bannerUrlString = banner ?? profiles.lookup(id: pubkey)?.map({ p in p?.banner }).value ?? ""
    122     if let url = URL(string: bannerUrlString) {
    123         return url
    124     }
    125     return nil
    126 }
    127 
    128 struct BannerImageView_Previews: PreviewProvider {
    129     static var previews: some View {
    130         BannerImageView(
    131             pubkey: test_pubkey,
    132             profiles: make_preview_profiles(test_pubkey),
    133             disable_animation: false
    134         )
    135     }
    136 }
    137