Improve reply view

Changelog-Changed: Improved look of reply view
This commit is contained in:
ericholguin
2023-03-29 15:05:33 -06:00
committed by William Casarin
parent 7a55ea13e3
commit 0dd74fde7f
5 changed files with 155 additions and 119 deletions

View File

@@ -312,9 +312,9 @@ struct ContentView: View {
case .report(let target): case .report(let target):
MaybeReportView(target: target) MaybeReportView(target: target)
case .post: case .post:
PostView(replying_to: nil, references: [], damus_state: damus_state!) PostView(replying_to: nil, damus_state: damus_state!)
case .reply(let event): case .reply(let event):
ReplyView(replying_to: event, damus: damus_state!) PostView(replying_to: event, damus_state: damus_state!)
case .event: case .event:
EventDetailView() EventDetailView()
case .filter: case .filter:

View File

@@ -16,23 +16,34 @@ struct ParticipantsView: View {
var body: some View { var body: some View {
VStack { VStack {
Text("Edit participants", comment: "Text indicating that the view is used for editing which participants are replied to in a note.") Text("Replying to", comment: "Text indicating that the view is used for editing which participants are replied to in a note.")
.font(.headline)
HStack { HStack {
Spacer() Spacer()
Button { Button {
// Remove all "p" refs, keep "e" refs // Remove all "p" refs, keep "e" refs
references = originalReferences.eRefs references = originalReferences.eRefs
} label: { } label: {
Text("Remove all", comment: "Button label to remove all participants from a note reply.") Text("Remove all", comment: "Button label to remove all participants from a note reply.")
} }
.buttonStyle(.borderedProminent) .font(.system(size: 14, weight: .bold))
Spacer() .frame(width: 100, height: 30)
.foregroundColor(.white)
.background(LINEAR_GRADIENT)
.clipShape(Capsule())
Button { Button {
references = originalReferences references = originalReferences
} label: { } label: {
Text("Add all", comment: "Button label to re-add all original participants as profiles to reply to in a note") Text("Add all", comment: "Button label to re-add all original participants as profiles to reply to in a note")
} }
.buttonStyle(.borderedProminent) .font(.system(size: 14, weight: .bold))
.frame(width: 80, height: 30)
.foregroundColor(.white)
.background(LINEAR_GRADIENT)
.clipShape(Capsule())
Spacer() Spacer()
} }
VStack { VStack {
@@ -56,7 +67,7 @@ struct ParticipantsView: View {
Image(systemName: "checkmark.circle.fill") Image(systemName: "checkmark.circle.fill")
.font(.system(size: 30)) .font(.system(size: 30))
.foregroundColor(references.contains(participant) ? .purple : .gray) .foregroundColor(references.contains(participant) ? DamusColors.purple : .gray)
} }
.onTapGesture { .onTapGesture {
if references.contains(participant) { if references.contains(participant) {

View File

@@ -22,10 +22,12 @@ struct PostView: View {
@State var attach_camera: Bool = false @State var attach_camera: Bool = false
@State var error: String? = nil @State var error: String? = nil
@State var originalReferences: [ReferencedId] = []
@State var references: [ReferencedId] = []
@StateObject var image_upload: ImageUploadModel = ImageUploadModel() @StateObject var image_upload: ImageUploadModel = ImageUploadModel()
let replying_to: NostrEvent? let replying_to: NostrEvent?
let references: [ReferencedId]
let damus_state: DamusState let damus_state: DamusState
@Environment(\.presentationMode) var presentationMode @Environment(\.presentationMode) var presentationMode
@@ -105,10 +107,12 @@ struct PostView: View {
self.send_post() self.send_post()
} }
} }
.disabled(is_post_empty)
.font(.system(size: 14, weight: .bold)) .font(.system(size: 14, weight: .bold))
.frame(width: 80, height: 30) .frame(width: 80, height: 30)
.foregroundColor(.white) .foregroundColor(.white)
.background(LINEAR_GRADIENT) .background(LINEAR_GRADIENT)
.opacity(is_post_empty ? 0.5 : 1.0)
.clipShape(Capsule()) .clipShape(Capsule())
} }
@@ -150,10 +154,8 @@ struct PostView: View {
Spacer() Spacer()
if !is_post_empty {
PostButton PostButton
} }
}
if let progress = image_upload.progress { if let progress = image_upload.progress {
ProgressView(value: progress, total: 1.0) ProgressView(value: progress, total: 1.0)
@@ -161,7 +163,7 @@ struct PostView: View {
} }
} }
.frame(height: 30) .frame(height: 30)
.padding([.top, .bottom], 4) .padding([.bottom], 10)
} }
func append_url(_ url: String) { func append_url(_ url: String) {
@@ -200,29 +202,48 @@ struct PostView: View {
} }
var body: some View { var body: some View {
GeometryReader { (deviceSize: GeometryProxy) in
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
let searching = get_searching_string(post.string) let searching = get_searching_string(post.string)
TopBar TopBar
ScrollViewReader { scroller in
ScrollView {
if let replying_to = replying_to {
ReplyView(replying_to: replying_to, damus: damus_state, originalReferences: $originalReferences, references: $references)
}
VStack(alignment: .leading, spacing: 0) {
HStack(alignment: .top) { HStack(alignment: .top) {
ProfilePicView(pubkey: damus_state.pubkey, size: 45.0, highlight: .none, profiles: damus_state.profiles) ProfilePicView(pubkey: damus_state.pubkey, size: PFP_SIZE, highlight: .none, profiles: damus_state.profiles)
.padding(.leading, replying_to != nil ? 15 : 0)
TextEntry TextEntry
} }
.frame(maxHeight: searching == nil ? .infinity : 50) .frame(height: deviceSize.size.height*0.78)
.id("post")
}
}
.frame(maxHeight: searching == nil ? .infinity : 70)
.onAppear {
scroll_to_event(scroller: scroller, id: "post", delay: 1.0, animate: true, anchor: .top)
}
}
// This if-block observes @ for tagging // This if-block observes @ for tagging
if let searching { if let searching {
UserSearch(damus_state: damus_state, search: searching, post: $post) UserSearch(damus_state: damus_state, search: searching, post: $post)
.padding(.leading, replying_to != nil ? 15 : 0)
.frame(maxHeight: .infinity) .frame(maxHeight: .infinity)
} else { } else {
Divider() Divider()
.padding([.bottom], 10) .padding([.top, .bottom], 10)
VStack(alignment: .leading) {
AttachmentBar AttachmentBar
} }
} }
}
.padding() .padding()
.sheet(isPresented: $attach_media) { .sheet(isPresented: $attach_media) {
ImagePicker(sourceType: .photoLibrary, damusState: damus_state) { img in ImagePicker(sourceType: .photoLibrary, damusState: damus_state) { img in
@@ -240,6 +261,8 @@ struct PostView: View {
} }
.onAppear() { .onAppear() {
if let replying_to { if let replying_to {
references = gather_reply_ids(our_pubkey: damus_state.pubkey, from: replying_to)
originalReferences = references
if damus_state.drafts.replies[replying_to] == nil { if damus_state.drafts.replies[replying_to] == nil {
damus_state.drafts.post = NSMutableAttributedString(string: "") damus_state.drafts.post = NSMutableAttributedString(string: "")
} }
@@ -271,6 +294,7 @@ struct PostView: View {
}) })
} }
} }
}
func get_searching_string(_ post: String) -> String? { func get_searching_string(_ post: String) -> String? {
guard let last_word = post.components(separatedBy: .whitespacesAndNewlines).last else { guard let last_word = post.components(separatedBy: .whitespacesAndNewlines).last else {
@@ -295,6 +319,6 @@ func get_searching_string(_ post: String) -> String? {
struct PostView_Previews: PreviewProvider { struct PostView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
PostView(replying_to: nil, references: [], damus_state: test_damus_state()) PostView(replying_to: nil, damus_state: test_damus_state())
} }
} }

View File

@@ -7,71 +7,71 @@
import SwiftUI import SwiftUI
func all_referenced_pubkeys(_ ev: NostrEvent) -> [ReferencedId] {
var keys = ev.referenced_pubkeys
let ref = ReferencedId(ref_id: ev.pubkey, relay_id: nil, key: "p")
keys.insert(ref, at: 0)
return keys
}
struct ReplyView: View { struct ReplyView: View {
let replying_to: NostrEvent let replying_to: NostrEvent
let damus: DamusState let damus: DamusState
@State var originalReferences: [ReferencedId] = [] @Binding var originalReferences: [ReferencedId]
@State var references: [ReferencedId] = [] @Binding var references: [ReferencedId]
@State var participantsShown: Bool = false @State var participantsShown: Bool = false
var body: some View { var ReplyingToSection: some View {
VStack { HStack {
Text("Replying to:", comment: "Indicating that the user is replying to the following listed people.") Group {
HStack(alignment: .top) {
let names = references.pRefs let names = references.pRefs
.map { pubkey in .map { pubkey in
let pk = pubkey.ref_id let pk = pubkey.ref_id
let prof = damus.profiles.lookup(id: pk) let prof = damus.profiles.lookup(id: pk)
return Profile.displayName(profile: prof, pubkey: pk).username return "@" + Profile.displayName(profile: prof, pubkey: pk).username
} }
.joined(separator: ", ") .joined(separator: " ")
Text(names) Text("Replying to ", comment: "Indicating that the user is replying to the following listed people.")
.foregroundColor(.gray) .foregroundColor(.gray)
.font(.footnote) +
Text(names.isEmpty ? "self" : names)
.foregroundColor(.accentColor)
.font(.footnote) .font(.footnote)
} }
.onTapGesture { .onTapGesture {
participantsShown.toggle() participantsShown.toggle()
} }
.sheet(isPresented: $participantsShown) { .sheet(isPresented: $participantsShown) {
if #available(iOS 16.0, *) {
ParticipantsView(damus_state: damus, references: $references, originalReferences: $originalReferences)
.presentationDetents([.medium, .large])
.presentationDragIndicator(.visible)
} else {
ParticipantsView(damus_state: damus, references: $references, originalReferences: $originalReferences) ParticipantsView(damus_state: damus, references: $references, originalReferences: $originalReferences)
} }
}
.padding(.leading, 75)
Spacer()
}
}
var body: some View {
VStack(alignment: .leading) {
ScrollViewReader { scroller in
ScrollView {
EventView(damus: damus, event: replying_to, options: [.no_action_bar]) EventView(damus: damus, event: replying_to, options: [.no_action_bar])
PostView(replying_to: replying_to, references: references, damus_state: damus)
.frame(minHeight: 500, maxHeight: .infinity)
.id("post")
}
.frame(maxHeight: .infinity)
.onAppear {
scroll_to_event(scroller: scroller, id: "post", delay: 1.0, animate: true, anchor: .top)
}
}
}
.padding() .padding()
.onAppear { .background(GeometryReader { geometry in
references = gather_reply_ids(our_pubkey: damus.pubkey, from: replying_to) let eventHeight = geometry.frame(in: .global).height
originalReferences = references Rectangle()
} .fill(Color.gray.opacity(0.25))
} .frame(width: 2, height: eventHeight + 7)
.offset(x: 25, y: 40)
.padding(.leading)
})
ReplyingToSection
} .background(GeometryReader { geometry in
let replyingToHeight = geometry.frame(in: .global).height
struct ReplyView_Previews: PreviewProvider { Rectangle()
static var previews: some View { .fill(Color.gray.opacity(0.25))
ReplyView(replying_to: NostrEvent(content: "hi", pubkey: "pubkey"), damus: test_damus_state(), references: []) .frame(width: 2, height: replyingToHeight)
.offset(x: 25, y: 40)
.padding(.leading)
})
}
} }
} }

View File

@@ -13,6 +13,7 @@ struct TextViewWrapper: UIViewRepresentable {
func makeUIView(context: Context) -> UITextView { func makeUIView(context: Context) -> UITextView {
let textView = UITextView() let textView = UITextView()
textView.delegate = context.coordinator textView.delegate = context.coordinator
textView.showsVerticalScrollIndicator = false
TextViewWrapper.setTextProperties(textView) TextViewWrapper.setTextProperties(textView)
return textView return textView
} }