From d71d448ac8b076b3fbfe75a617b680a9ef145f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=E2=80=99Aquino?= Date: Sat, 17 Aug 2024 14:55:23 -0700 Subject: [PATCH] Add support for rendering highlights with comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit implements rendering comments from the `["comment", ]` tag in a highlight note. Comment contents get rendered like a kind 1 note's "content" field This commit also adds the `r` "reference" tag as a standard tag reference type Changelog-Added: Add support for rendering highlights with comments Signed-off-by: Daniel D’Aquino --- damus.xcodeproj/project.pbxproj | 7 ++++++ damus/ContentParsing.swift | 2 +- damus/ContentView.swift | 2 +- damus/Models/CommentItem.swift | 23 +++++++++++++++++++ damus/Models/Contacts+.swift | 2 +- damus/Nostr/ReferencedId.swift | 19 +++++++++------ .../Events/Highlight/HighlightView.swift | 19 +++++++++++++-- nostrdb/NdbNote.swift | 7 ++++++ 8 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 damus/Models/CommentItem.swift diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj index aa96f4dd..d4f77090 100644 --- a/damus.xcodeproj/project.pbxproj +++ b/damus.xcodeproj/project.pbxproj @@ -497,6 +497,9 @@ D753CEAA2BE9DE04001C3A5D /* MutingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D753CEA92BE9DE04001C3A5D /* MutingTests.swift */; }; D76556D62B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76556D52B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift */; }; D76874F32AE3632B00FB0F68 /* ProfileZapLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76874F22AE3632B00FB0F68 /* ProfileZapLinkView.swift */; }; + D773BC5F2C6D538500349F0A /* CommentItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D773BC5E2C6D538500349F0A /* CommentItem.swift */; }; + D773BC602C6D538500349F0A /* CommentItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D773BC5E2C6D538500349F0A /* CommentItem.swift */; }; + D773BC612C6D58A700349F0A /* CommentItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D773BC5E2C6D538500349F0A /* CommentItem.swift */; }; D77BFA0B2AE3051200621634 /* ProfileActionSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77BFA0A2AE3051200621634 /* ProfileActionSheetView.swift */; }; D783A63F2AD4E53D00658DDA /* SuggestedHashtagsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D783A63E2AD4E53D00658DDA /* SuggestedHashtagsView.swift */; }; D78525252A7B2EA4002FA637 /* NoteContentViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D78525242A7B2EA4002FA637 /* NoteContentViewTests.swift */; }; @@ -1427,6 +1430,7 @@ D753CEA92BE9DE04001C3A5D /* MutingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutingTests.swift; sourceTree = ""; }; D76556D52B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleWelcomeView.swift; sourceTree = ""; }; D76874F22AE3632B00FB0F68 /* ProfileZapLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileZapLinkView.swift; sourceTree = ""; }; + D773BC5E2C6D538500349F0A /* CommentItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentItem.swift; sourceTree = ""; }; D77BFA0A2AE3051200621634 /* ProfileActionSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileActionSheetView.swift; sourceTree = ""; }; D783A63E2AD4E53D00658DDA /* SuggestedHashtagsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestedHashtagsView.swift; sourceTree = ""; }; D78525242A7B2EA4002FA637 /* NoteContentViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContentViewTests.swift; sourceTree = ""; }; @@ -1683,6 +1687,7 @@ B533694D2B66D791008A805E /* MutelistManager.swift */, D7D2A3802BF815D000E4B42B /* PushNotificationClient.swift */, 5CC8529C2BD741CD0039FFC5 /* HighlightEvent.swift */, + D773BC5E2C6D538500349F0A /* CommentItem.swift */, ); path = Models; sourceTree = ""; @@ -3489,6 +3494,7 @@ 4CF38C882A9442DC00BE01B6 /* UserStatusView.swift in Sources */, 4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */, 4C1253582A76C9060004F4B8 /* PresentSheetNotify.swift in Sources */, + D773BC5F2C6D538500349F0A /* CommentItem.swift in Sources */, 4C363A962827096D006E126D /* PostBlock.swift in Sources */, 4CA9275F2A2902B20098A105 /* LongformPreview.swift in Sources */, 4C5F9116283D855D0052CD1C /* EventsModel.swift in Sources */, @@ -3724,6 +3730,7 @@ D74AAFC62B155B8B006CF0F4 /* Zaps.swift in Sources */, D7CCFC0B2B0585EA00323D86 /* nostrdb.c in Sources */, D7CE1B252B0BE1F4002EDAD4 /* sha256.c in Sources */, + D773BC612C6D58A700349F0A /* CommentItem.swift in Sources */, D7CE1B262B0BE1F8002EDAD4 /* bech32.c in Sources */, D7EDED232B117DFB0018B19C /* NoteContent.swift in Sources */, D798D21B2B0856F200234419 /* NdbTagsIterator.swift in Sources */, diff --git a/damus/ContentParsing.swift b/damus/ContentParsing.swift index cb080a1d..61daf8bc 100644 --- a/damus/ContentParsing.swift +++ b/damus/ContentParsing.swift @@ -12,7 +12,7 @@ enum NoteContent { case content(String, TagsSequence?) init(note: NostrEvent, keypair: Keypair) { - if note.known_kind == .dm { + if note.known_kind == .dm || note.known_kind == .highlight { self = .content(note.get_content(keypair), note.tags) } else { self = .note(note) diff --git a/damus/ContentView.swift b/damus/ContentView.swift index 0bad6ba9..15eaa258 100644 --- a/damus/ContentView.swift +++ b/damus/ContentView.swift @@ -1112,7 +1112,7 @@ func on_open_url(state: DamusState, url: URL, result: @escaping (OpenResult?) -> } case .hashtag(let ht): result(.filter(.filter_hashtag([ht.hashtag]))) - case .param, .quote: + case .param, .quote, .reference: // doesn't really make sense here break case .naddr(let naddr): diff --git a/damus/Models/CommentItem.swift b/damus/Models/CommentItem.swift new file mode 100644 index 00000000..457d32bd --- /dev/null +++ b/damus/Models/CommentItem.swift @@ -0,0 +1,23 @@ +// +// CommentItem.swift +// damus +// +// Created by Daniel D’Aquino on 2024-08-14. +// + +import Foundation + +struct CommentItem: TagConvertible { + static let TAG_KEY: String = "comment" + let content: String + var tag: [String] { + return [Self.TAG_KEY, content] + } + + static func from_tag(tag: TagSequence) -> CommentItem? { + guard tag.count == 2 else { return nil } + guard tag[0].string() == Self.TAG_KEY else { return nil } + + return CommentItem(content: tag[1].string()) + } +} diff --git a/damus/Models/Contacts+.swift b/damus/Models/Contacts+.swift index 3ed16a22..d73df431 100644 --- a/damus/Models/Contacts+.swift +++ b/damus/Models/Contacts+.swift @@ -109,7 +109,7 @@ func is_already_following(contacts: NostrEvent, follow: FollowRef) -> Bool { case let (.pubkey(pk), .pubkey(follow_pk)): return pk == follow_pk case (.hashtag, .pubkey), (.pubkey, .hashtag), - (.event, _), (.quote, _), (.param, _), (.naddr, _): + (.event, _), (.quote, _), (.param, _), (.naddr, _), (.reference(_), _): return false } } diff --git a/damus/Nostr/ReferencedId.swift b/damus/Nostr/ReferencedId.swift index 3d45322a..e75e5941 100644 --- a/damus/Nostr/ReferencedId.swift +++ b/damus/Nostr/ReferencedId.swift @@ -122,20 +122,22 @@ enum RefId: TagConvertible, TagKeys, Equatable, Hashable { case hashtag(Hashtag) case param(TagElem) case naddr(NAddr) + case reference(String) var key: RefKey { switch self { - case .event: return .e - case .pubkey: return .p - case .quote: return .q - case .hashtag: return .t - case .param: return .d - case .naddr: return .a + case .event: return .e + case .pubkey: return .p + case .quote: return .q + case .hashtag: return .t + case .param: return .d + case .naddr: return .a + case .reference: return .r } } enum RefKey: AsciiCharacter, TagKey, CustomStringConvertible { - case e, p, t, d, q, a + case e, p, t, d, q, a, r var keychar: AsciiCharacter { self.rawValue @@ -159,6 +161,8 @@ enum RefId: TagConvertible, TagKeys, Equatable, Hashable { case .param(let string): return string.string() case .naddr(let naddr): return naddr.kind.description + ":" + naddr.author.hex() + ":" + naddr.identifier + case .reference(let string): + return string } } @@ -179,6 +183,7 @@ enum RefId: TagConvertible, TagKeys, Equatable, Hashable { case .t: return .hashtag(Hashtag(hashtag: t1.string())) case .d: return .param(t1) case .a: return .naddr(NAddr(identifier: "", author: Pubkey(Data()), relays: [], kind: 0)) + case .r: return .reference(t1.string()) } } } diff --git a/damus/Views/Events/Highlight/HighlightView.swift b/damus/Views/Events/Highlight/HighlightView.swift index 441d7041..4feefa0d 100644 --- a/damus/Views/Events/Highlight/HighlightView.swift +++ b/damus/Views/Events/Highlight/HighlightView.swift @@ -59,9 +59,9 @@ struct HighlightBodyView: View { var body: some View { Group { if options.contains(.wide) { - Main.padding(.horizontal) - } else { Main + } else { + Main.padding(.horizontal) } } } @@ -92,6 +92,18 @@ struct HighlightBodyView: View { var Main: some View { VStack(alignment: .leading, spacing: 0) { + + if self.event.event.referenced_comment_items.first?.content != nil { + let all_options = options.union(.no_action_bar) + NoteContentView( + damus_state: self.state, + event: self.event.event, + blur_images: should_blur_images(damus_state: self.state, ev: self.event.event), + size: .normal, + options: all_options + ).padding(.vertical, 10) + } + HStack { var attributedString: AttributedString { var attributedString: AttributedString = "" @@ -119,14 +131,17 @@ struct HighlightBodyView: View { RoundedRectangle(cornerRadius: 25).fill(DamusColors.highlight).frame(width: 4), alignment: .leading ) + .padding(.horizontal) .padding(.bottom, 10) if let url = event.url_ref { HighlightLink(state: state, url: url, content: event.event.content) + .padding(.horizontal) } else { if let evRef = event.event_ref { if let eventHex = hex_decode_id(evRef) { HighlightEventRef(damus_state: state, event_ref: NoteId(eventHex)) + .padding(.horizontal) .padding(.top, 5) } } diff --git a/nostrdb/NdbNote.swift b/nostrdb/NdbNote.swift index 9c0f7f8a..1d6d1908 100644 --- a/nostrdb/NdbNote.swift +++ b/nostrdb/NdbNote.swift @@ -335,6 +335,10 @@ extension NdbNote { public var referenced_mute_items: References { References(tags: self.tags) } + + public var referenced_comment_items: References { + References(tags: self.tags) + } public var references: References { References(tags: self.tags) @@ -355,6 +359,9 @@ extension NdbNote { if known_kind == .dm { return decrypted(keypair: keypair) ?? "*failed to decrypt content*" } + else if known_kind == .highlight { + return self.referenced_comment_items.first?.content ?? "" + } return content }