damus

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

EventMenu.swift (7993B)


      1 //
      2 //  EventMenu.swift
      3 //  damus
      4 //
      5 //  Created by William Casarin on 2023-01-23.
      6 //
      7 
      8 import SwiftUI
      9 
     10 struct EventMenuContext: View {
     11     let damus_state: DamusState
     12     let event: NostrEvent
     13     let target_pubkey: Pubkey
     14     let profileModel : ProfileModel
     15     
     16     init(damus: DamusState, event: NostrEvent) {
     17         self.damus_state = damus
     18         self.event = event
     19         self.target_pubkey = event.pubkey
     20         self.profileModel = ProfileModel(pubkey: target_pubkey, damus: damus)
     21     }
     22     
     23     var body: some View {
     24         HStack {
     25             Label("", systemImage: "ellipsis")
     26                 .foregroundColor(Color.gray)
     27                 .contentShape(Circle())
     28                 // Add our Menu button inside an overlay modifier to avoid affecting the rest of the layout around us.
     29                 .overlay(
     30                     Menu {
     31                         MenuItems(damus_state: damus_state, event: event, target_pubkey: target_pubkey, profileModel: profileModel)
     32                     } label: {
     33                         Color.clear
     34                     }
     35                     // Hitbox frame size
     36                     .frame(width: 50, height: 35)
     37                 )
     38         }
     39         .padding([.bottom], 4)
     40         .contentShape(Rectangle())
     41         .onTapGesture {}
     42     }
     43 }
     44 
     45 struct MenuItems: View {
     46     let damus_state: DamusState
     47     let event: NostrEvent
     48     let target_pubkey: Pubkey
     49     let profileModel: ProfileModel
     50 
     51     @State private var isBookmarked: Bool = false
     52     @State private var isMutedThread: Bool = false
     53     
     54     init(damus_state: DamusState, event: NostrEvent, target_pubkey: Pubkey, profileModel: ProfileModel) {
     55         let bookmarked = damus_state.bookmarks.isBookmarked(event)
     56         self._isBookmarked = State(initialValue: bookmarked)
     57 
     58         let muted_thread = damus_state.mutelist_manager.is_event_muted(event)
     59         self._isMutedThread = State(initialValue: muted_thread)
     60         
     61         self.damus_state = damus_state
     62         self.event = event
     63         self.target_pubkey = target_pubkey
     64         self.profileModel = profileModel
     65     }
     66     
     67     var body: some View {
     68         Group {
     69             Button {
     70                 UIPasteboard.general.string = event.get_content(damus_state.keypair)
     71             } label: {
     72                 Label(NSLocalizedString("Copy text", comment: "Context menu option for copying the text from an note."), image: "copy2")
     73             }
     74 
     75             Button {
     76                 UIPasteboard.general.string = Bech32Object.encode(.nprofile(NProfile(author: target_pubkey, relays: profileModel.getCappedRelayStrings())))
     77             } label: {
     78                 Label(NSLocalizedString("Copy user public key", comment: "Context menu option for copying the ID of the user who created the note."), image: "user")
     79             }
     80 
     81             Button {
     82                 UIPasteboard.general.string = event.id.bech32
     83             } label: {
     84                 Label(NSLocalizedString("Copy note ID", comment: "Context menu option for copying the ID of the note."), image: "note-book")
     85             }
     86 
     87             if damus_state.settings.developer_mode {
     88                 Button {
     89                     UIPasteboard.general.string = event_to_json(ev: event)
     90                 } label: {
     91                     Label(NSLocalizedString("Copy note JSON", comment: "Context menu option for copying the JSON text from the note."), image: "code.on.square")
     92                 }
     93             }
     94             
     95             Button {
     96                 self.damus_state.bookmarks.updateBookmark(event)
     97                 isBookmarked = self.damus_state.bookmarks.isBookmarked(event)
     98             } label: {
     99                 let imageName = isBookmarked ? "bookmark.fill" : "bookmark"
    100                 let removeBookmarkString = NSLocalizedString("Remove bookmark", comment: "Context menu option for removing a note bookmark.")
    101                 let addBookmarkString = NSLocalizedString("Add bookmark", comment: "Context menu option for adding a note bookmark.")
    102                 Label(isBookmarked ? removeBookmarkString : addBookmarkString, image: imageName)
    103             }
    104 
    105             Button {
    106                 notify(.broadcast(event))
    107             } label: {
    108                 Label(NSLocalizedString("Broadcast", comment: "Context menu option for broadcasting the user's note to all of the user's connected relay servers."), image: "globe")
    109             }
    110             // Mute thread - relocated to below Broadcast, as to move further away from Add Bookmark to prevent accidental muted threads
    111             if event.known_kind != .dm {
    112                 MuteDurationMenu { duration in
    113                     if let full_keypair = self.damus_state.keypair.to_full(),
    114                        let new_mutelist_ev = toggle_from_mutelist(keypair: full_keypair, prev: damus_state.mutelist_manager.event, to_toggle: .thread(event.thread_id(keypair: damus_state.keypair), duration?.date_from_now)) {
    115                         damus_state.mutelist_manager.set_mutelist(new_mutelist_ev)
    116                         damus_state.postbox.send(new_mutelist_ev)
    117                     }
    118                     let muted = damus_state.mutelist_manager.is_event_muted(event)
    119                     isMutedThread = muted
    120                 } label: {
    121                     let imageName = isMutedThread ? "mute" : "mute"
    122                     let unmuteThreadString = NSLocalizedString("Unmute conversation", comment: "Context menu option for unmuting a conversation.")
    123                     let muteThreadString = NSLocalizedString("Mute conversation", comment: "Context menu option for muting a conversation.")
    124                     Label(isMutedThread ? unmuteThreadString : muteThreadString, image: imageName)
    125                 }
    126             }
    127             // Only allow reporting if logged in with private key and the currently viewed profile is not the logged in profile.
    128             if damus_state.keypair.pubkey != target_pubkey && damus_state.keypair.privkey != nil {
    129                 Button(role: .destructive) {
    130                     notify(.report(.note(ReportNoteTarget(pubkey: target_pubkey, note_id: event.id))))
    131                 } label: {
    132                     Label(NSLocalizedString("Report", comment: "Context menu option for reporting content."), image: "raising-hand")
    133                 }
    134                 
    135                 MuteDurationMenu { duration in
    136                     notify(.mute(.user(target_pubkey, duration?.date_from_now)))
    137                 } label: {
    138                     Label(NSLocalizedString("Mute user", comment: "Context menu option for muting users."), image: "mute")
    139                 }
    140             }
    141         }
    142         .onAppear() {
    143             profileModel.subscribeToFindRelays()
    144         }
    145         .onDisappear() {
    146             profileModel.unsubscribeFindRelays()
    147         }
    148     }
    149 }
    150 
    151 /*
    152 struct EventMenu: UIViewRepresentable {
    153     
    154     typealias UIViewType = UIButton
    155 
    156     let saveAction = UIAction(title: "") { action in }
    157     let saveMenu = UIMenu(title: "", children: [
    158         UIAction(title: "First Menu Item", image: UIImage(systemName: "nameOfSFSymbol")) { action in
    159             //code action for menu item
    160         },
    161         UIAction(title: "First Menu Item", image: UIImage(systemName: "nameOfSFSymbol")) { action in
    162             //code action for menu item
    163         },
    164         UIAction(title: "First Menu Item", image: UIImage(systemName: "nameOfSFSymbol")) { action in
    165             //code action for menu item
    166         },
    167     ])
    168 
    169     func makeUIView(context: Context) -> UIButton {
    170         let button = UIButton(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
    171         button.showsMenuAsPrimaryAction = true
    172         button.menu = saveMenu
    173         
    174         return button
    175     }
    176     
    177     func updateUIView(_ uiView: UIButton, context: Context) {
    178         uiView.setImage(UIImage(systemName: "plus"), for: .normal)
    179     }
    180 }
    181 
    182 struct EventMenu_Previews: PreviewProvider {
    183     static var previews: some View {
    184         EventMenu(event: test_event, privkey: nil, pubkey: test_event.pubkey)
    185     }
    186 }
    187 
    188 */