damus

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

FollowPackView.swift (6472B)


      1 //
      2 //  FollowPackView.swift
      3 //  damus
      4 //
      5 //  Created by eric on 4/30/25.
      6 //
      7 
      8 import SwiftUI
      9 import Kingfisher
     10 
     11 struct FollowPackView: View {
     12     let state: DamusState
     13     let event: FollowPackEvent
     14     @StateObject var model: FollowPackModel
     15     @State var blur_imgs: Bool
     16     
     17     @Environment(\.colorScheme) var colorScheme
     18     
     19     @ObservedObject var artifacts: NoteArtifactsModel
     20 
     21     init(state: DamusState, ev: FollowPackEvent, model: FollowPackModel, blur_imgs: Bool) {
     22         self.state = state
     23         self.event = ev
     24         self._model = StateObject(wrappedValue: model)
     25         self.blur_imgs = blur_imgs
     26 
     27         self._artifacts = ObservedObject(wrappedValue: state.events.get_cache_data(ev.event.id).artifacts_model)
     28     }
     29 
     30     init(state: DamusState, ev: NostrEvent, model: FollowPackModel, blur_imgs: Bool) {
     31         self.state = state
     32         self.event = FollowPackEvent.parse(from: ev)
     33         self._model = StateObject(wrappedValue: model)
     34         self.blur_imgs = blur_imgs
     35 
     36         self._artifacts = ObservedObject(wrappedValue: state.events.get_cache_data(ev.id).artifacts_model)
     37     }
     38     
     39     func content_filter(_ pubkeys: [Pubkey]) -> ((NostrEvent) -> Bool) {
     40         var filters = ContentFilters.defaults(damus_state: self.state)
     41         filters.append({ pubkeys.contains($0.pubkey) })
     42         return ContentFilters(filters: filters).filter
     43     }
     44     
     45     enum FollowPackTabSelection: Int {
     46         case people = 0
     47         case posts = 1
     48     }
     49     
     50     @State var tab_selection: FollowPackTabSelection = .people
     51     
     52     var body: some View {
     53         ZStack {
     54             ScrollView {
     55                 FollowPackHeader
     56                 
     57                 FollowPackTabs
     58             }
     59         }
     60         .onAppear {
     61             if model.events.events.isEmpty {
     62                 model.subscribe(follow_pack_users: event.publicKeys)
     63             }
     64         }
     65         .onDisappear {
     66             model.unsubscribe()
     67         }
     68     }
     69     
     70     var tabs: [(String, FollowPackTabSelection)] {
     71         let tabs = [
     72             (NSLocalizedString("People", comment: "Label for filter for seeing the people in this follow pack."), FollowPackTabSelection.people),
     73             (NSLocalizedString("Posts", comment: "Label for filter for seeing the posts from the people in this follow pack."), FollowPackTabSelection.posts)
     74             ]
     75         return tabs
     76     }
     77     
     78     var FollowPackTabs: some View {
     79 
     80         VStack(spacing: 0) {
     81             VStack(spacing: 0) {
     82                 CustomPicker(tabs: tabs, selection: $tab_selection)
     83                 Divider()
     84                     .frame(height: 1)
     85             }
     86             .background(colorScheme == .dark ? Color.black : Color.white)
     87             
     88             if tab_selection == FollowPackTabSelection.people {
     89                 LazyVStack(alignment: .leading) {
     90                     ForEach(event.publicKeys.reversed(), id: \.self) { pk in
     91                         FollowUserView(target: .pubkey(pk), damus_state: state)
     92                     }
     93                 }
     94                 .padding()
     95                 .padding(.bottom, 50)
     96                 .tag(FollowPackTabSelection.people)
     97                 .id(FollowPackTabSelection.people)
     98             }
     99             
    100             if tab_selection == FollowPackTabSelection.posts {
    101                 InnerTimelineView(events: model.events, damus: state, filter: content_filter(event.publicKeys))
    102             }
    103         }
    104         .onAppear() {
    105             model.subscribe(follow_pack_users: event.publicKeys)
    106         }
    107         .onDisappear {
    108             model.unsubscribe()
    109         }
    110     }
    111 
    112     var FollowPackHeader: some View {
    113         VStack(alignment: .leading, spacing: 10) {
    114             
    115             if state.settings.media_previews {
    116                 FollowPackBannerImage(state: state, options: EventViewOptions(), image: event.image, preview: false, blur_imgs: blur_imgs)
    117             }
    118             
    119             Text(event.title ?? NSLocalizedString("Untitled", comment: "Title of follow list event if it is untitled."))
    120                 .font(.title)
    121                 .padding(.horizontal, 10)
    122                 .padding(.top, 5)
    123             
    124             if let description = event.description {
    125                 Text(description)
    126                     .font(.body)
    127                     .foregroundColor(.gray)
    128                     .padding(.horizontal, 10)
    129             } else {
    130                 EmptyView()
    131             }
    132             
    133             HStack(alignment: .center) {
    134                 ProfilePicView(pubkey: event.event.pubkey, size: 25, highlight: .none, profiles: state.profiles, disable_animation: state.settings.disable_animation, show_zappability: true)
    135                     .onTapGesture {
    136                         state.nav.push(route: Route.ProfileByKey(pubkey: event.event.pubkey))
    137                     }
    138                 let profile_txn = state.profiles.lookup(id: event.event.pubkey)
    139                 let profile = profile_txn?.unsafeUnownedValue
    140                 let displayName = Profile.displayName(profile: profile, pubkey: event.event.pubkey)
    141                 switch displayName {
    142                 case .one(let one):
    143                     Text("Created by \(one)", comment: "Lets the user know who created this follow pack.")
    144                         .font(.subheadline).foregroundColor(.gray)
    145                     
    146                 case .both(username: let username, displayName: let displayName):
    147                         HStack(spacing: 6) {
    148                             Text("Created by \(displayName)", comment: "Lets the user know who created this follow pack.")
    149                                 .font(.subheadline).foregroundColor(.gray)
    150                             
    151                             Text(verbatim: "@\(username)")
    152                                 .font(.subheadline).foregroundColor(.gray)
    153                         }
    154                 }
    155             }
    156             .padding(.horizontal, 10)
    157             .padding(.bottom, 20)
    158             
    159             HStack(alignment: .center) {
    160                 FollowPackUsers(state: state, publicKeys: event.publicKeys)
    161             }
    162             .padding(.horizontal, 10)
    163             .padding(.bottom, 20)
    164         }
    165     }
    166 }
    167 
    168 
    169 struct FollowPackView_Previews: PreviewProvider {
    170     static var previews: some View {
    171         VStack {
    172             FollowPackView(state: test_damus_state, ev: test_follow_list_event, model: FollowPackModel(damus_state: test_damus_state), blur_imgs: false)
    173         }
    174         .frame(height: 400)
    175     }
    176 }