Add support for adding comments when creating a highlight
Changelog-Added: Add support for adding comments when creating a highlight Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
committed by
William Casarin
parent
d71d448ac8
commit
c09018be48
@@ -59,9 +59,12 @@ struct SelectableText: View {
|
||||
self.highlightPostingState = newValue ? .show_post_view(highlighted_text: self.highlightPostingState.highlighted_text() ?? "") : .hide
|
||||
})) {
|
||||
if let event, case .show_post_view(let highlighted_text) = self.highlightPostingState {
|
||||
HighlightPostView(damus_state: damus_state, event: event, selectedText: .constant(highlighted_text))
|
||||
.presentationDragIndicator(.visible)
|
||||
.presentationDetents([.height(selectedTextHeight + 150), .medium, .large])
|
||||
PostView(
|
||||
action: .highlighting(.init(selected_text: highlighted_text, source: .event(event))),
|
||||
damus_state: damus_state
|
||||
)
|
||||
.presentationDragIndicator(.visible)
|
||||
.presentationDetents([.height(selectedTextHeight + 450), .medium, .large])
|
||||
}
|
||||
}
|
||||
.frame(height: selectedTextHeight)
|
||||
|
||||
@@ -1051,7 +1051,7 @@ func handle_post_notification(keypair: FullKeypair, postbox: PostBox, events: Ev
|
||||
//let post = tup.0
|
||||
//let to_relays = tup.1
|
||||
print("post \(post.content)")
|
||||
guard let new_ev = post_to_event(post: post, keypair: keypair) else {
|
||||
guard let new_ev = post.to_event(keypair: keypair) else {
|
||||
return false
|
||||
}
|
||||
postbox.send(new_ev)
|
||||
|
||||
@@ -28,4 +28,5 @@ class Drafts: ObservableObject {
|
||||
@Published var post: DraftArtifacts? = nil
|
||||
@Published var replies: [NostrEvent: DraftArtifacts] = [:]
|
||||
@Published var quotes: [NostrEvent: DraftArtifacts] = [:]
|
||||
@Published var highlights: [HighlightSource: DraftArtifacts] = [:]
|
||||
}
|
||||
|
||||
@@ -32,3 +32,31 @@ struct HighlightEvent {
|
||||
return highlight
|
||||
}
|
||||
}
|
||||
|
||||
struct HighlightContentDraft: Hashable {
|
||||
let selected_text: String
|
||||
let source: HighlightSource
|
||||
}
|
||||
|
||||
enum HighlightSource: Hashable {
|
||||
case event(NostrEvent)
|
||||
case external_url(URL)
|
||||
|
||||
func tags() -> [[String]] {
|
||||
switch self {
|
||||
case .event(let event):
|
||||
return [ ["e", "\(event.id)"] ]
|
||||
case .external_url(let url):
|
||||
return [ ["r", "\(url)"] ]
|
||||
}
|
||||
}
|
||||
|
||||
func ref() -> RefId {
|
||||
switch self {
|
||||
case .event(let event):
|
||||
return .event(event.id)
|
||||
case .external_url(let url):
|
||||
return .reference(url.absoluteString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,12 +290,3 @@ func make_post_tags(post_blocks: [Block], tags: [[String]]) -> PostTags {
|
||||
|
||||
return PostTags(blocks: post_blocks, tags: new_tags)
|
||||
}
|
||||
|
||||
func post_to_event(post: NostrPost, keypair: FullKeypair) -> NostrEvent? {
|
||||
let post_blocks = parse_post_blocks(content: post.content)
|
||||
let post_tags = make_post_tags(post_blocks: post_blocks, tags: post.tags)
|
||||
let content = post_tags.blocks
|
||||
.map(\.asString)
|
||||
.joined(separator: "")
|
||||
return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: post.kind.rawValue, tags: post_tags.tags)
|
||||
}
|
||||
|
||||
@@ -17,10 +17,40 @@ struct NostrPost {
|
||||
self.kind = kind
|
||||
self.tags = tags
|
||||
}
|
||||
|
||||
func to_event(keypair: FullKeypair) -> NostrEvent? {
|
||||
let post_blocks = self.parse_blocks()
|
||||
let post_tags = make_post_tags(post_blocks: post_blocks, tags: self.tags)
|
||||
let content = post_tags.blocks
|
||||
.map(\.asString)
|
||||
.joined(separator: "")
|
||||
|
||||
if self.kind == .highlight {
|
||||
var new_tags = post_tags.tags.filter({ $0[safe: 0] != "comment" })
|
||||
if content.count > 0 {
|
||||
new_tags.append(["comment", content])
|
||||
}
|
||||
return NostrEvent(content: self.content, keypair: keypair.to_keypair(), kind: self.kind.rawValue, tags: new_tags)
|
||||
}
|
||||
|
||||
return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: self.kind.rawValue, tags: post_tags.tags)
|
||||
}
|
||||
|
||||
func parse_blocks() -> [Block] {
|
||||
guard let content_for_parsing = self.default_content_for_block_parsing() else { return [] }
|
||||
return parse_post_blocks(content: content_for_parsing)
|
||||
}
|
||||
|
||||
private func default_content_for_block_parsing() -> String? {
|
||||
switch kind {
|
||||
case .highlight:
|
||||
return tags.filter({ $0[safe: 0] == "comment" }).first?[safe: 1]
|
||||
default:
|
||||
return self.content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Return a list of tags
|
||||
func parse_post_blocks(content: String) -> [Block] {
|
||||
return parse_note_content(content: .content(content, nil)).blocks
|
||||
}
|
||||
|
||||
42
damus/Views/Events/Highlight/HighlightDraftContentView.swift
Normal file
42
damus/Views/Events/Highlight/HighlightDraftContentView.swift
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// HighlightDraftContentView.swift
|
||||
// damus
|
||||
//
|
||||
// Created by eric on 5/26/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct HighlightDraftContentView: View {
|
||||
let draft: HighlightContentDraft
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
HStack {
|
||||
var attributedString: AttributedString {
|
||||
var attributedString = AttributedString(draft.selected_text)
|
||||
|
||||
if let range = attributedString.range(of: draft.selected_text) {
|
||||
attributedString[range].backgroundColor = DamusColors.highlight
|
||||
}
|
||||
|
||||
return attributedString
|
||||
}
|
||||
|
||||
Text(attributedString)
|
||||
.lineSpacing(5)
|
||||
.padding(10)
|
||||
}
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 25).fill(DamusColors.highlight).frame(width: 4),
|
||||
alignment: .leading
|
||||
)
|
||||
|
||||
if case .external_url(let url) = draft.source {
|
||||
LinkViewRepresentable(meta: .url(url))
|
||||
.frame(height: 50)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
//
|
||||
// HighlightPostView.swift
|
||||
// damus
|
||||
//
|
||||
// Created by eric on 5/26/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct HighlightPostView: View {
|
||||
let damus_state: DamusState
|
||||
let event: NostrEvent
|
||||
@Binding var selectedText: String
|
||||
|
||||
@Environment(\.dismiss) var dismiss
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
VStack {
|
||||
HStack(spacing: 5.0) {
|
||||
Button(action: {
|
||||
dismiss()
|
||||
}, label: {
|
||||
Text("Cancel", comment: "Button to cancel out of highlighting a note.")
|
||||
.padding(10)
|
||||
})
|
||||
.buttonStyle(NeutralButtonStyle())
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(NSLocalizedString("Post", comment: "Button to post a highlight.")) {
|
||||
let tags: [[String]] = [ ["e", "\(self.event.id)"] ]
|
||||
|
||||
let kind = NostrKind.highlight.rawValue
|
||||
guard let ev = NostrEvent(content: selectedText, keypair: damus_state.keypair, kind: kind, tags: tags) else {
|
||||
return
|
||||
}
|
||||
damus_state.postbox.send(ev)
|
||||
dismiss()
|
||||
}
|
||||
.bold()
|
||||
.buttonStyle(GradientButtonStyle(padding: 10))
|
||||
}
|
||||
|
||||
Divider()
|
||||
.foregroundColor(DamusColors.neutral3)
|
||||
.padding(.top, 5)
|
||||
}
|
||||
.frame(height: 30)
|
||||
.padding()
|
||||
.padding(.top, 15)
|
||||
|
||||
HStack {
|
||||
var attributedString: AttributedString {
|
||||
var attributedString = AttributedString(selectedText)
|
||||
|
||||
if let range = attributedString.range(of: selectedText) {
|
||||
attributedString[range].backgroundColor = DamusColors.highlight
|
||||
}
|
||||
|
||||
return attributedString
|
||||
}
|
||||
|
||||
Text(attributedString)
|
||||
.lineSpacing(5)
|
||||
.padding(10)
|
||||
}
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 25).fill(DamusColors.highlight).frame(width: 4),
|
||||
alignment: .leading
|
||||
)
|
||||
.padding()
|
||||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,15 +30,18 @@ enum PostAction {
|
||||
case replying_to(NostrEvent)
|
||||
case quoting(NostrEvent)
|
||||
case posting(PostTarget)
|
||||
case highlighting(HighlightContentDraft)
|
||||
|
||||
var ev: NostrEvent? {
|
||||
switch self {
|
||||
case .replying_to(let ev):
|
||||
return ev
|
||||
case .quoting(let ev):
|
||||
return ev
|
||||
case .posting:
|
||||
return nil
|
||||
case .replying_to(let ev):
|
||||
return ev
|
||||
case .quoting(let ev):
|
||||
return ev
|
||||
case .posting:
|
||||
return nil
|
||||
case .highlighting:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,7 +131,12 @@ struct PostView: View {
|
||||
}
|
||||
|
||||
var posting_disabled: Bool {
|
||||
return is_post_empty || uploading_disabled
|
||||
switch action {
|
||||
case .highlighting(_):
|
||||
return false
|
||||
default:
|
||||
return is_post_empty || uploading_disabled
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a valid height for the text box, even when textHeight is not a number
|
||||
@@ -204,6 +212,8 @@ struct PostView: View {
|
||||
damus_state.drafts.quotes.removeValue(forKey: quoting)
|
||||
case .posting:
|
||||
damus_state.drafts.post = nil
|
||||
case .highlighting(let draft):
|
||||
damus_state.drafts.highlights.removeValue(forKey: draft.source)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -371,6 +381,9 @@ struct PostView: View {
|
||||
if case .quoting(let ev) = action {
|
||||
BuilderEventView(damus: damus_state, event: ev)
|
||||
}
|
||||
else if case .highlighting(let draft) = action {
|
||||
HighlightDraftContentView(draft: draft)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
}
|
||||
@@ -454,14 +467,15 @@ struct PostView: View {
|
||||
let loaded_draft = load_draft()
|
||||
|
||||
switch action {
|
||||
case .replying_to(let replying_to):
|
||||
references = gather_reply_ids(our_pubkey: damus_state.pubkey, from: replying_to)
|
||||
case .quoting(let quoting):
|
||||
references = gather_quote_ids(our_pubkey: damus_state.pubkey, from: quoting)
|
||||
case .posting(let target):
|
||||
guard !loaded_draft else { break }
|
||||
|
||||
fill_target_content(target: target)
|
||||
case .replying_to(let replying_to):
|
||||
references = gather_reply_ids(our_pubkey: damus_state.pubkey, from: replying_to)
|
||||
case .quoting(let quoting):
|
||||
references = gather_quote_ids(our_pubkey: damus_state.pubkey, from: quoting)
|
||||
case .posting(let target):
|
||||
guard !loaded_draft else { break }
|
||||
fill_target_content(target: target)
|
||||
case .highlighting(let draft):
|
||||
references = [draft.source.ref()]
|
||||
}
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
@@ -597,6 +611,8 @@ func set_draft_for_post(drafts: Drafts, action: PostAction, artifacts: DraftArti
|
||||
drafts.quotes[ev] = artifacts
|
||||
case .posting:
|
||||
drafts.post = artifacts
|
||||
case .highlighting(let draft):
|
||||
drafts.highlights[draft.source] = artifacts
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,6 +624,8 @@ func load_draft_for_post(drafts: Drafts, action: PostAction) -> DraftArtifacts?
|
||||
return drafts.quotes[ev]
|
||||
case .posting:
|
||||
return drafts.post
|
||||
case .highlighting(let draft):
|
||||
return drafts.highlights[draft.source]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -669,18 +687,20 @@ func build_post(state: DamusState, post: NSMutableAttributedString, action: Post
|
||||
var tags: [[String]] = []
|
||||
|
||||
switch action {
|
||||
case .replying_to(let replying_to):
|
||||
// start off with the reply tags
|
||||
tags = nip10_reply_tags(replying_to: replying_to, keypair: state.keypair)
|
||||
case .replying_to(let replying_to):
|
||||
// start off with the reply tags
|
||||
tags = nip10_reply_tags(replying_to: replying_to, keypair: state.keypair)
|
||||
|
||||
case .quoting(let ev):
|
||||
content.append(" nostr:" + bech32_note_id(ev.id))
|
||||
case .quoting(let ev):
|
||||
content.append(" nostr:" + bech32_note_id(ev.id))
|
||||
|
||||
if let quoted_ev = state.events.lookup(ev.id) {
|
||||
tags.append(["p", quoted_ev.pubkey.hex()])
|
||||
}
|
||||
case .posting(let postTarget):
|
||||
break
|
||||
if let quoted_ev = state.events.lookup(ev.id) {
|
||||
tags.append(["p", quoted_ev.pubkey.hex()])
|
||||
}
|
||||
case .posting(let postTarget):
|
||||
break
|
||||
case .highlighting(let draft):
|
||||
break
|
||||
}
|
||||
|
||||
// include pubkeys
|
||||
@@ -690,6 +710,17 @@ func build_post(state: DamusState, post: NSMutableAttributedString, action: Post
|
||||
|
||||
// append additional tags
|
||||
tags += uploadedMedias.compactMap { $0.metadata?.to_tag() }
|
||||
|
||||
switch action {
|
||||
case .highlighting(let draft):
|
||||
tags.append(contentsOf: draft.source.tags())
|
||||
if !(content.isEmpty || content.allSatisfy { $0.isWhitespace }) {
|
||||
tags.append(["comment", content])
|
||||
}
|
||||
return NostrPost(content: draft.selected_text, kind: .highlight, tags: tags)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return NostrPost(content: content, kind: .text, tags: tags)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user