damus

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

ChatView.swift (5608B)


      1 //
      2 //  ChatView.swift
      3 //  damus
      4 //
      5 //  Created by William Casarin on 2022-04-19.
      6 //
      7 
      8 import SwiftUI
      9 
     10 struct ChatView: View {
     11     let event: NostrEvent
     12     let prev_ev: NostrEvent?
     13     let next_ev: NostrEvent?
     14     
     15     let damus_state: DamusState
     16     
     17     @State var expand_reply: Bool = false
     18     @EnvironmentObject var thread: ThreadModel
     19     
     20     var just_started: Bool {
     21         return prev_ev == nil || prev_ev!.pubkey != event.pubkey
     22     }
     23     
     24     func next_replies_to_this() -> Bool {
     25         guard let next = next_ev else {
     26             return false
     27         }
     28         
     29         return thread.replies.lookup(next.id) != nil
     30     }
     31     
     32     func is_reply_to_prev() -> Bool {
     33         guard let prev = prev_ev else {
     34             return true
     35         }
     36         
     37         if let rep = thread.replies.lookup(event.id) {
     38             return rep.contains(prev.id)
     39         }
     40         
     41         return false
     42     }
     43     
     44     var is_active: Bool {
     45         return thread.event.id == event.id
     46     }
     47     
     48     func prev_reply_is_same() -> String? {
     49         return damus.prev_reply_is_same(event: event, prev_ev: prev_ev, replies: thread.replies)
     50     }
     51     
     52     func reply_is_new() -> String? {
     53         guard let prev = self.prev_ev else {
     54             // if they are both null they are the same?
     55             return nil
     56         }
     57         
     58         if thread.replies.lookup(prev.id) != thread.replies.lookup(event.id) {
     59             return prev.id
     60         }
     61         
     62         return nil
     63     }
     64     
     65     var ReplyDescription: some View {
     66         Text(verbatim: "\(reply_desc(profiles: damus_state.profiles, event: event))")
     67             .font(.footnote)
     68             .foregroundColor(.gray)
     69             .frame(alignment: .leading)
     70     }
     71     
     72     @Environment(\.colorScheme) var colorScheme
     73     
     74     var disable_animation: Bool {
     75         self.damus_state.settings.disable_animation
     76     }
     77     
     78     var body: some View {
     79         HStack {
     80             VStack {
     81                 if is_active || just_started {
     82                     ProfilePicView(pubkey: event.pubkey, size: 32, highlight: is_active ? .main : .none, profiles: damus_state.profiles, disable_animation: disable_animation)
     83                 }
     84 
     85                 Spacer()
     86             }
     87             .frame(maxWidth: 32)
     88             
     89             Group {
     90                 VStack(alignment: .leading) {
     91                     if just_started {
     92                         HStack {
     93                             ProfileName(pubkey: event.pubkey, profile: damus_state.profiles.lookup(id: event.pubkey), damus: damus_state, show_friend_confirmed: true)
     94                                 .foregroundColor(colorScheme == .dark ?  id_to_color(event.pubkey) : Color.black)
     95                                 //.shadow(color: Color.black, radius: 2)
     96                             Text(verbatim: "\(format_relative_time(event.created_at))")
     97                                     .foregroundColor(.gray)
     98                         }
     99                     }
    100                 
    101                     if let _ = thread.replies.lookup(event.id) {
    102                         if !is_reply_to_prev() {
    103                             /*
    104                             ReplyQuoteView(keypair: damus_state.keypair, quoter: event, event_id: ref_id, profiles: damus_state.profiles, previews: damus_state.previews)
    105                                 .frame(maxHeight: expand_reply ? nil : 100)
    106                                 .environmentObject(thread)
    107                                 .onTapGesture {
    108                                     expand_reply = !expand_reply
    109                                 }
    110                              */
    111                             ReplyDescription
    112                         }
    113                     }
    114                     
    115                     let show_images = should_show_images(settings: damus_state.settings, contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey)
    116                     NoteContentView(damus_state: damus_state,
    117                                     event: event,
    118                                     show_images: show_images,
    119                                     size: .normal,
    120                                     artifacts: .just_content(event.content),
    121                                     options: [])
    122 
    123                     if is_active || next_ev == nil || next_ev!.pubkey != event.pubkey {
    124                         let bar = make_actionbar_model(ev: event.id, damus: damus_state)
    125                         EventActionBar(damus_state: damus_state, event: event, bar: bar)
    126                     }
    127 
    128                     //Spacer()
    129                 }
    130                 .padding(6)
    131             }
    132             .background(Color.secondary.opacity(0.1))
    133             .cornerRadius(8.0)
    134             
    135             //.border(Color.red)
    136         }
    137         .contentShape(Rectangle())
    138         .id(event.id)
    139         //.frame(minHeight: just_started ? PFP_SIZE : 0)
    140         .padding([.bottom], 6)
    141         //.border(Color.green)
    142         
    143     }
    144 }
    145 
    146 extension Notification.Name {
    147     static var toggle_thread_view: Notification.Name {
    148         return Notification.Name("convert_to_thread")
    149     }
    150 }
    151 
    152 
    153 /*
    154 struct ChatView_Previews: PreviewProvider {
    155     static var previews: some View {
    156         ChatView()
    157     }
    158 }
    159 
    160 */
    161 
    162 
    163 func prev_reply_is_same(event: NostrEvent, prev_ev: NostrEvent?, replies: ReplyMap) -> String? {
    164     if let prev = prev_ev {
    165         if let prev_reply_id = replies.lookup(prev.id) {
    166             if let cur_reply_id = replies.lookup(event.id) {
    167                 if prev_reply_id != cur_reply_id {
    168                     return cur_reply_id.first
    169                 }
    170             }
    171         }
    172     }
    173     return nil
    174 }
    175