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
@@ -399,7 +399,7 @@
|
|||||||
5C14C29D2BBBA40B00079FD2 /* RelayAdminDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C14C29C2BBBA40B00079FD2 /* RelayAdminDetail.swift */; };
|
5C14C29D2BBBA40B00079FD2 /* RelayAdminDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C14C29C2BBBA40B00079FD2 /* RelayAdminDetail.swift */; };
|
||||||
5C14C29F2BBBA5C600079FD2 /* RelayNipList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C14C29E2BBBA5C600079FD2 /* RelayNipList.swift */; };
|
5C14C29F2BBBA5C600079FD2 /* RelayNipList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C14C29E2BBBA5C600079FD2 /* RelayNipList.swift */; };
|
||||||
5C42E78C29DB76D90086AAC1 /* EmptyUserSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C42E78B29DB76D90086AAC1 /* EmptyUserSearchView.swift */; };
|
5C42E78C29DB76D90086AAC1 /* EmptyUserSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C42E78B29DB76D90086AAC1 /* EmptyUserSearchView.swift */; };
|
||||||
5C4D9EA72C042FA5005EA0F7 /* HighlightPostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C4D9EA62C042FA5005EA0F7 /* HighlightPostView.swift */; };
|
5C4D9EA72C042FA5005EA0F7 /* HighlightDraftContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C4D9EA62C042FA5005EA0F7 /* HighlightDraftContentView.swift */; };
|
||||||
5C513FBA297F72980072348F /* CustomPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C513FB9297F72980072348F /* CustomPicker.swift */; };
|
5C513FBA297F72980072348F /* CustomPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C513FB9297F72980072348F /* CustomPicker.swift */; };
|
||||||
5C513FCC2984ACA60072348F /* QRCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C513FCB2984ACA60072348F /* QRCodeView.swift */; };
|
5C513FCC2984ACA60072348F /* QRCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C513FCB2984ACA60072348F /* QRCodeView.swift */; };
|
||||||
5C6E1DAD2A193EC2008FC15A /* GradientButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6E1DAC2A193EC2008FC15A /* GradientButtonStyle.swift */; };
|
5C6E1DAD2A193EC2008FC15A /* GradientButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6E1DAC2A193EC2008FC15A /* GradientButtonStyle.swift */; };
|
||||||
@@ -1344,7 +1344,7 @@
|
|||||||
5C14C29C2BBBA40B00079FD2 /* RelayAdminDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayAdminDetail.swift; sourceTree = "<group>"; };
|
5C14C29C2BBBA40B00079FD2 /* RelayAdminDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayAdminDetail.swift; sourceTree = "<group>"; };
|
||||||
5C14C29E2BBBA5C600079FD2 /* RelayNipList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayNipList.swift; sourceTree = "<group>"; };
|
5C14C29E2BBBA5C600079FD2 /* RelayNipList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayNipList.swift; sourceTree = "<group>"; };
|
||||||
5C42E78B29DB76D90086AAC1 /* EmptyUserSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyUserSearchView.swift; sourceTree = "<group>"; };
|
5C42E78B29DB76D90086AAC1 /* EmptyUserSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyUserSearchView.swift; sourceTree = "<group>"; };
|
||||||
5C4D9EA62C042FA5005EA0F7 /* HighlightPostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HighlightPostView.swift; sourceTree = "<group>"; };
|
5C4D9EA62C042FA5005EA0F7 /* HighlightDraftContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HighlightDraftContentView.swift; sourceTree = "<group>"; };
|
||||||
5C513FB9297F72980072348F /* CustomPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPicker.swift; sourceTree = "<group>"; };
|
5C513FB9297F72980072348F /* CustomPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPicker.swift; sourceTree = "<group>"; };
|
||||||
5C513FCB2984ACA60072348F /* QRCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeView.swift; sourceTree = "<group>"; };
|
5C513FCB2984ACA60072348F /* QRCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeView.swift; sourceTree = "<group>"; };
|
||||||
5C6E1DAC2A193EC2008FC15A /* GradientButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientButtonStyle.swift; sourceTree = "<group>"; };
|
5C6E1DAC2A193EC2008FC15A /* GradientButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientButtonStyle.swift; sourceTree = "<group>"; };
|
||||||
@@ -2728,7 +2728,7 @@
|
|||||||
5CC852A12BDED9B90039FFC5 /* HighlightDescription.swift */,
|
5CC852A12BDED9B90039FFC5 /* HighlightDescription.swift */,
|
||||||
5CC852A32BDF3CA10039FFC5 /* HighlightLink.swift */,
|
5CC852A32BDF3CA10039FFC5 /* HighlightLink.swift */,
|
||||||
5CC852A52BE00F180039FFC5 /* HighlightEventRef.swift */,
|
5CC852A52BE00F180039FFC5 /* HighlightEventRef.swift */,
|
||||||
5C4D9EA62C042FA5005EA0F7 /* HighlightPostView.swift */,
|
5C4D9EA62C042FA5005EA0F7 /* HighlightDraftContentView.swift */,
|
||||||
);
|
);
|
||||||
path = Highlight;
|
path = Highlight;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -3188,7 +3188,7 @@
|
|||||||
4C75EFAD28049CFB0006080F /* PostButton.swift in Sources */,
|
4C75EFAD28049CFB0006080F /* PostButton.swift in Sources */,
|
||||||
D7EDED1E2B11797D0018B19C /* LongformEvent.swift in Sources */,
|
D7EDED1E2B11797D0018B19C /* LongformEvent.swift in Sources */,
|
||||||
504323A92A3495B6006AE6DC /* RelayModelCache.swift in Sources */,
|
504323A92A3495B6006AE6DC /* RelayModelCache.swift in Sources */,
|
||||||
5C4D9EA72C042FA5005EA0F7 /* HighlightPostView.swift in Sources */,
|
5C4D9EA72C042FA5005EA0F7 /* HighlightDraftContentView.swift in Sources */,
|
||||||
3A8CC6CC2A2CFEF900940F5F /* StringUtil.swift in Sources */,
|
3A8CC6CC2A2CFEF900940F5F /* StringUtil.swift in Sources */,
|
||||||
D7FD12262BD345A700CF195B /* FirstAidSettingsView.swift in Sources */,
|
D7FD12262BD345A700CF195B /* FirstAidSettingsView.swift in Sources */,
|
||||||
D7870BC12AC4750B0080BA88 /* MentionView.swift in Sources */,
|
D7870BC12AC4750B0080BA88 /* MentionView.swift in Sources */,
|
||||||
|
|||||||
@@ -59,9 +59,12 @@ struct SelectableText: View {
|
|||||||
self.highlightPostingState = newValue ? .show_post_view(highlighted_text: self.highlightPostingState.highlighted_text() ?? "") : .hide
|
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 {
|
if let event, case .show_post_view(let highlighted_text) = self.highlightPostingState {
|
||||||
HighlightPostView(damus_state: damus_state, event: event, selectedText: .constant(highlighted_text))
|
PostView(
|
||||||
.presentationDragIndicator(.visible)
|
action: .highlighting(.init(selected_text: highlighted_text, source: .event(event))),
|
||||||
.presentationDetents([.height(selectedTextHeight + 150), .medium, .large])
|
damus_state: damus_state
|
||||||
|
)
|
||||||
|
.presentationDragIndicator(.visible)
|
||||||
|
.presentationDetents([.height(selectedTextHeight + 450), .medium, .large])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(height: selectedTextHeight)
|
.frame(height: selectedTextHeight)
|
||||||
|
|||||||
@@ -1051,7 +1051,7 @@ func handle_post_notification(keypair: FullKeypair, postbox: PostBox, events: Ev
|
|||||||
//let post = tup.0
|
//let post = tup.0
|
||||||
//let to_relays = tup.1
|
//let to_relays = tup.1
|
||||||
print("post \(post.content)")
|
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
|
return false
|
||||||
}
|
}
|
||||||
postbox.send(new_ev)
|
postbox.send(new_ev)
|
||||||
|
|||||||
@@ -28,4 +28,5 @@ class Drafts: ObservableObject {
|
|||||||
@Published var post: DraftArtifacts? = nil
|
@Published var post: DraftArtifacts? = nil
|
||||||
@Published var replies: [NostrEvent: DraftArtifacts] = [:]
|
@Published var replies: [NostrEvent: DraftArtifacts] = [:]
|
||||||
@Published var quotes: [NostrEvent: DraftArtifacts] = [:]
|
@Published var quotes: [NostrEvent: DraftArtifacts] = [:]
|
||||||
|
@Published var highlights: [HighlightSource: DraftArtifacts] = [:]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,3 +32,31 @@ struct HighlightEvent {
|
|||||||
return highlight
|
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)
|
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.kind = kind
|
||||||
self.tags = tags
|
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] {
|
func parse_post_blocks(content: String) -> [Block] {
|
||||||
return parse_note_content(content: .content(content, nil)).blocks
|
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 replying_to(NostrEvent)
|
||||||
case quoting(NostrEvent)
|
case quoting(NostrEvent)
|
||||||
case posting(PostTarget)
|
case posting(PostTarget)
|
||||||
|
case highlighting(HighlightContentDraft)
|
||||||
|
|
||||||
var ev: NostrEvent? {
|
var ev: NostrEvent? {
|
||||||
switch self {
|
switch self {
|
||||||
case .replying_to(let ev):
|
case .replying_to(let ev):
|
||||||
return ev
|
return ev
|
||||||
case .quoting(let ev):
|
case .quoting(let ev):
|
||||||
return ev
|
return ev
|
||||||
case .posting:
|
case .posting:
|
||||||
return nil
|
return nil
|
||||||
|
case .highlighting:
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,7 +131,12 @@ struct PostView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var posting_disabled: Bool {
|
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
|
// 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)
|
damus_state.drafts.quotes.removeValue(forKey: quoting)
|
||||||
case .posting:
|
case .posting:
|
||||||
damus_state.drafts.post = nil
|
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 {
|
if case .quoting(let ev) = action {
|
||||||
BuilderEventView(damus: damus_state, event: ev)
|
BuilderEventView(damus: damus_state, event: ev)
|
||||||
}
|
}
|
||||||
|
else if case .highlighting(let draft) = action {
|
||||||
|
HighlightDraftContentView(draft: draft)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
}
|
}
|
||||||
@@ -454,14 +467,15 @@ struct PostView: View {
|
|||||||
let loaded_draft = load_draft()
|
let loaded_draft = load_draft()
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case .replying_to(let replying_to):
|
case .replying_to(let replying_to):
|
||||||
references = gather_reply_ids(our_pubkey: damus_state.pubkey, from: replying_to)
|
references = gather_reply_ids(our_pubkey: damus_state.pubkey, from: replying_to)
|
||||||
case .quoting(let quoting):
|
case .quoting(let quoting):
|
||||||
references = gather_quote_ids(our_pubkey: damus_state.pubkey, from: quoting)
|
references = gather_quote_ids(our_pubkey: damus_state.pubkey, from: quoting)
|
||||||
case .posting(let target):
|
case .posting(let target):
|
||||||
guard !loaded_draft else { break }
|
guard !loaded_draft else { break }
|
||||||
|
fill_target_content(target: target)
|
||||||
fill_target_content(target: target)
|
case .highlighting(let draft):
|
||||||
|
references = [draft.source.ref()]
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
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
|
drafts.quotes[ev] = artifacts
|
||||||
case .posting:
|
case .posting:
|
||||||
drafts.post = artifacts
|
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]
|
return drafts.quotes[ev]
|
||||||
case .posting:
|
case .posting:
|
||||||
return drafts.post
|
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]] = []
|
var tags: [[String]] = []
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case .replying_to(let replying_to):
|
case .replying_to(let replying_to):
|
||||||
// start off with the reply tags
|
// start off with the reply tags
|
||||||
tags = nip10_reply_tags(replying_to: replying_to, keypair: state.keypair)
|
tags = nip10_reply_tags(replying_to: replying_to, keypair: state.keypair)
|
||||||
|
|
||||||
case .quoting(let ev):
|
case .quoting(let ev):
|
||||||
content.append(" nostr:" + bech32_note_id(ev.id))
|
content.append(" nostr:" + bech32_note_id(ev.id))
|
||||||
|
|
||||||
if let quoted_ev = state.events.lookup(ev.id) {
|
if let quoted_ev = state.events.lookup(ev.id) {
|
||||||
tags.append(["p", quoted_ev.pubkey.hex()])
|
tags.append(["p", quoted_ev.pubkey.hex()])
|
||||||
}
|
}
|
||||||
case .posting(let postTarget):
|
case .posting(let postTarget):
|
||||||
break
|
break
|
||||||
|
case .highlighting(let draft):
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// include pubkeys
|
// include pubkeys
|
||||||
@@ -690,6 +710,17 @@ func build_post(state: DamusState, post: NSMutableAttributedString, action: Post
|
|||||||
|
|
||||||
// append additional tags
|
// append additional tags
|
||||||
tags += uploadedMedias.compactMap { $0.metadata?.to_tag() }
|
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)
|
return NostrPost(content: content, kind: .text, tags: tags)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ class ReplyTests: XCTestCase {
|
|||||||
let content = "this is a @\(pk.npub) mention"
|
let content = "this is a @\(pk.npub) mention"
|
||||||
let blocks = parse_post_blocks(content: content)
|
let blocks = parse_post_blocks(content: content)
|
||||||
let post = NostrPost(content: content, tags: [["e", evid.hex()]])
|
let post = NostrPost(content: content, tags: [["e", evid.hex()]])
|
||||||
let ev = post_to_event(post: post, keypair: test_keypair_full)!
|
let ev = post.to_event(keypair: test_keypair_full)!
|
||||||
|
|
||||||
XCTAssertEqual(ev.tags.count, 2)
|
XCTAssertEqual(ev.tags.count, 2)
|
||||||
XCTAssertEqual(blocks.count, 3)
|
XCTAssertEqual(blocks.count, 3)
|
||||||
@@ -255,7 +255,7 @@ class ReplyTests: XCTestCase {
|
|||||||
let content = "this is a @\(nsec) mention"
|
let content = "this is a @\(nsec) mention"
|
||||||
let blocks = parse_post_blocks(content: content)
|
let blocks = parse_post_blocks(content: content)
|
||||||
let post = NostrPost(content: content, tags: [["e", evid.hex()]])
|
let post = NostrPost(content: content, tags: [["e", evid.hex()]])
|
||||||
let ev = post_to_event(post: post, keypair: test_keypair_full)!
|
let ev = post.to_event(keypair: test_keypair_full)!
|
||||||
|
|
||||||
XCTAssertEqual(ev.tags.count, 2)
|
XCTAssertEqual(ev.tags.count, 2)
|
||||||
XCTAssertEqual(blocks.count, 3)
|
XCTAssertEqual(blocks.count, 3)
|
||||||
@@ -275,7 +275,7 @@ class ReplyTests: XCTestCase {
|
|||||||
]
|
]
|
||||||
|
|
||||||
let post = NostrPost(content: "this is a (@\(pubkey.npub)) mention", tags: tags)
|
let post = NostrPost(content: "this is a (@\(pubkey.npub)) mention", tags: tags)
|
||||||
let ev = post_to_event(post: post, keypair: test_keypair_full)!
|
let ev = post.to_event(keypair: test_keypair_full)!
|
||||||
|
|
||||||
XCTAssertEqual(ev.content, "this is a (nostr:\(pubkey.npub)) mention")
|
XCTAssertEqual(ev.content, "this is a (nostr:\(pubkey.npub)) mention")
|
||||||
XCTAssertEqual(ev.tags[2][1].string(), pubkey.description)
|
XCTAssertEqual(ev.tags[2][1].string(), pubkey.description)
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ class damusTests: XCTestCase {
|
|||||||
|
|
||||||
func testMakeHashtagPost() {
|
func testMakeHashtagPost() {
|
||||||
let post = NostrPost(content: "#damus some content #bitcoin derp #かっこいい wow", tags: [])
|
let post = NostrPost(content: "#damus some content #bitcoin derp #かっこいい wow", tags: [])
|
||||||
let ev = post_to_event(post: post, keypair: test_keypair_full)!
|
let ev = post.to_event(keypair: test_keypair_full)!
|
||||||
|
|
||||||
XCTAssertEqual(ev.tags.count, 3)
|
XCTAssertEqual(ev.tags.count, 3)
|
||||||
XCTAssertEqual(ev.content, "#damus some content #bitcoin derp #かっこいい wow")
|
XCTAssertEqual(ev.content, "#damus some content #bitcoin derp #かっこいい wow")
|
||||||
@@ -270,7 +270,7 @@ class damusTests: XCTestCase {
|
|||||||
|
|
||||||
private func createEventFromContentString(_ content: String) -> NostrEvent {
|
private func createEventFromContentString(_ content: String) -> NostrEvent {
|
||||||
let post = NostrPost(content: content, tags: [])
|
let post = NostrPost(content: content, tags: [])
|
||||||
guard let ev = post_to_event(post: post, keypair: test_keypair_full) else {
|
guard let ev = post.to_event(keypair: test_keypair_full) else {
|
||||||
XCTFail("Could not create event")
|
XCTFail("Could not create event")
|
||||||
return test_note
|
return test_note
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user