From 2a9ddd10c81a45f9a1f72d07c74d7b68236d1a8a Mon Sep 17 00:00:00 2001 From: Joel Klabo Date: Sun, 22 Jan 2023 10:08:50 -0800 Subject: [PATCH] Choose Participants on a Thread Reply Closes: #345 Changelog-Added: Add the ability to choose participants when replying --- damus.xcodeproj/project.pbxproj | 4 ++ damus/Nostr/NostrEvent.swift | 19 ++++++++ damus/Views/ParicipantsView.swift | 79 +++++++++++++++++++++++++++++++ damus/Views/ReplyView.swift | 24 ++++++++-- 4 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 damus/Views/ParicipantsView.swift diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj index e765350..f0b72df 100644 --- a/damus.xcodeproj/project.pbxproj +++ b/damus.xcodeproj/project.pbxproj @@ -161,6 +161,7 @@ E990020F2955F837003BBC5A /* EditMetadataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E990020E2955F837003BBC5A /* EditMetadataView.swift */; }; E9E4ED0B295867B900DD7078 /* ThreadV2View.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */; }; F7F0BA25297892BD009531F3 /* SwipeToDismiss.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F0BA24297892BD009531F3 /* SwipeToDismiss.swift */; }; + F7F0BA272978E54D009531F3 /* ParicipantsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F0BA262978E54D009531F3 /* ParicipantsView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -380,6 +381,7 @@ E990020E2955F837003BBC5A /* EditMetadataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditMetadataView.swift; sourceTree = ""; }; E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadV2View.swift; sourceTree = ""; }; F7F0BA24297892BD009531F3 /* SwipeToDismiss.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeToDismiss.swift; sourceTree = ""; }; + F7F0BA262978E54D009531F3 /* ParicipantsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParicipantsView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -550,6 +552,7 @@ 4C06670028FC7C5900038D2A /* RelayView.swift */, 4C0A3F94280F6C78000448DE /* ReplyQuoteView.swift */, 4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */, + F7F0BA262978E54D009531F3 /* ParicipantsView.swift */, 4C285C8D28399BFD008A31F1 /* SaveKeysView.swift */, 4C3AC7A628369BA200E1F516 /* SearchHomeView.swift */, 4C5C7E69284EDE2E00A22DF5 /* SearchResultsView.swift */, @@ -916,6 +919,7 @@ 4C0A3F8C280F5FCA000448DE /* ChatroomView.swift in Sources */, 4C477C9E282C3A4800033AA3 /* TipCounter.swift in Sources */, 647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */, + F7F0BA272978E54D009531F3 /* ParicipantsView.swift in Sources */, 4C0A3F91280F6528000448DE /* ChatView.swift in Sources */, 4C216F362870A9A700040376 /* InputDismissKeyboard.swift in Sources */, 4C216F382871EDE300040376 /* DirectMessageModel.swift in Sources */, diff --git a/damus/Nostr/NostrEvent.swift b/damus/Nostr/NostrEvent.swift index 160ce0f..8a03444 100644 --- a/damus/Nostr/NostrEvent.swift +++ b/damus/Nostr/NostrEvent.swift @@ -790,6 +790,7 @@ func inner_event_or_self(ev: NostrEvent) -> NostrEvent { return inner_ev } +<<<<<<< HEAD func first_eref_mention(ev: NostrEvent, privkey: String?) -> Mention? { let blocks = ev.blocks(privkey).filter { block in @@ -815,3 +816,21 @@ func first_eref_mention(ev: NostrEvent, privkey: String?) -> Mention? { return nil } + +extension [ReferencedId] { + var pRefs: [ReferencedId] { + get { + self.filter { ref in + ref.key == "p" + } + } + } + + var eRefs: [ReferencedId] { + get { + self.filter { ref in + ref.key == "e" + } + } + } +} diff --git a/damus/Views/ParicipantsView.swift b/damus/Views/ParicipantsView.swift new file mode 100644 index 0000000..909ca07 --- /dev/null +++ b/damus/Views/ParicipantsView.swift @@ -0,0 +1,79 @@ +// +// ParicipantsView.swift +// damus +// +// Created by Joel Klabo on 1/18/23. +// + +import SwiftUI + +struct ParticipantsView: View { + + let damus_state: DamusState + + @Binding var references: [ReferencedId] + @Binding var originalReferences: [ReferencedId] + + var body: some View { + VStack { + Text("Edit participants") + HStack { + Spacer() + Button { + // Remove all "p" refs, keep "e" refs + references = originalReferences.eRefs + } label: { + Text("Remove all") + } + .buttonStyle(.borderedProminent) + Spacer() + Button { + references = originalReferences + } label: { + Text("Add all") + } + .buttonStyle(.borderedProminent) + Spacer() + } + VStack { + ForEach(originalReferences.pRefs) { participant in + let pubkey = participant.id + HStack { + ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: .none, profiles: damus_state.profiles) + + VStack(alignment: .leading) { + let profile = damus_state.profiles.lookup(id: pubkey) + ProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_friend_confirmed: false, show_nip5_domain: false) + if let about = profile?.about { + Text(FollowUserView.markdown.process(about)) + .lineLimit(3) + .font(.footnote) + } + } + + Spacer() + + Image(systemName: "checkmark.circle.fill") + .font(.system(size: 30)) + .foregroundColor(references.contains(participant) ? .purple : .gray) + } + .onTapGesture { + if references.contains(participant) { + references = references.filter { + $0 != participant + } + } else { + if references.contains(participant) { + // Don't add it twice + } else { + references.append(participant) + } + } + } + } + } + Spacer() + } + .padding() + } +} diff --git a/damus/Views/ReplyView.swift b/damus/Views/ReplyView.swift index 404a5e7..0e9d4fc 100644 --- a/damus/Views/ReplyView.swift +++ b/damus/Views/ReplyView.swift @@ -18,11 +18,16 @@ struct ReplyView: View { let replying_to: NostrEvent let damus: DamusState + @State var originalReferences: [ReferencedId] = [] + @State var references: [ReferencedId] = [] + + @State var participantsShown: Bool = false + var body: some View { VStack { Text("Replying to:", comment: "Indicating that the user is replying to the following listed people.") HStack(alignment: .top) { - let names = all_referenced_pubkeys(replying_to) + let names = references.pRefs .map { pubkey in let pk = pubkey.ref_id let prof = damus.profiles.lookup(id: pk) @@ -33,13 +38,22 @@ struct ReplyView: View { .foregroundColor(.gray) .font(.footnote) } + .onTapGesture { + participantsShown.toggle() + } + .sheet(isPresented: $participantsShown) { + ParticipantsView(damus_state: damus, references: $references, originalReferences: $originalReferences) + } ScrollView { - EventView(event: replying_to, highlight: .none, has_action_bar: false, damus: damus, show_friend_icon: true) + EventView(event: replying_to, highlight: .none, has_action_bar: false, damus: damus, show_friend_icon: true) } - PostView(replying_to: replying_to, references: gather_reply_ids(our_pubkey: damus.pubkey, from: replying_to)) + PostView(replying_to: replying_to, references: references) + } + .onAppear { + references = gather_reply_ids(our_pubkey: damus.pubkey, from: replying_to) + originalReferences = references } .padding() - } @@ -47,6 +61,6 @@ struct ReplyView: View { struct ReplyView_Previews: PreviewProvider { static var previews: some View { - ReplyView(replying_to: NostrEvent(content: "hi", pubkey: "pubkey"), damus: test_damus_state()) + ReplyView(replying_to: NostrEvent(content: "hi", pubkey: "pubkey"), damus: test_damus_state(), references: []) } }