Add support for rendering highlights with comments
This commit implements rendering comments from the `["comment", <COMMENT_TEXT>]` 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 <daniel@daquino.me>
This commit is contained in:
@@ -496,6 +496,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 */; };
|
||||
@@ -1425,6 +1428,7 @@
|
||||
D753CEA92BE9DE04001C3A5D /* MutingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutingTests.swift; sourceTree = "<group>"; };
|
||||
D76556D52B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleWelcomeView.swift; sourceTree = "<group>"; };
|
||||
D76874F22AE3632B00FB0F68 /* ProfileZapLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileZapLinkView.swift; sourceTree = "<group>"; };
|
||||
D773BC5E2C6D538500349F0A /* CommentItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentItem.swift; sourceTree = "<group>"; };
|
||||
D77BFA0A2AE3051200621634 /* ProfileActionSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileActionSheetView.swift; sourceTree = "<group>"; };
|
||||
D783A63E2AD4E53D00658DDA /* SuggestedHashtagsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestedHashtagsView.swift; sourceTree = "<group>"; };
|
||||
D78525242A7B2EA4002FA637 /* NoteContentViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContentViewTests.swift; sourceTree = "<group>"; };
|
||||
@@ -1681,6 +1685,7 @@
|
||||
B533694D2B66D791008A805E /* MutelistManager.swift */,
|
||||
D7D2A3802BF815D000E4B42B /* PushNotificationClient.swift */,
|
||||
5CC8529C2BD741CD0039FFC5 /* HighlightEvent.swift */,
|
||||
D773BC5E2C6D538500349F0A /* CommentItem.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
@@ -3485,6 +3490,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 */,
|
||||
@@ -3720,6 +3726,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 */,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1170,7 +1170,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):
|
||||
|
||||
23
damus/Models/CommentItem.swift
Normal file
23
damus/Models/CommentItem.swift
Normal file
@@ -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())
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,6 +336,10 @@ extension NdbNote {
|
||||
References<MuteItem>(tags: self.tags)
|
||||
}
|
||||
|
||||
public var referenced_comment_items: References<CommentItem> {
|
||||
References<CommentItem>(tags: self.tags)
|
||||
}
|
||||
|
||||
public var references: References<RefId> {
|
||||
References<RefId>(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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user