commit f436291209e2f7eefbcd9e8f37a901fe4814a8a0
parent a9196a39df7c3bc6bb3ffd48e729767b75b7e821
Author: Terry Yiu <git@tyiu.xyz>
Date: Mon, 19 May 2025 21:39:18 -0400
Hide end previewables when hashtags are present
Changelog-Fixed: Hide end previewables when hashtags are present
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Diffstat:
2 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/damus/Models/NoteContent.swift b/damus/Models/NoteContent.swift
@@ -117,6 +117,10 @@ func render_blocks(blocks bs: Blocks, profiles: Profiles, can_hide_last_previewa
}
hide_text_index = i
} else if case .text(let txt) = block, txt.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
+ // We should hide whitespace at the end sequence.
+ hide_text_index = i
+ } else if case .hashtag = block {
+ // We should keep hashtags at the end sequence but hide all the other previewables around it.
hide_text_index = i
} else {
break
@@ -149,7 +153,16 @@ func render_blocks(blocks bs: Blocks, profiles: Profiles, can_hide_last_previewa
// No need to show the text representation of the block if the only previewables are the sequence of them
// found at the end of the content.
// This is to save unnecessary use of screen space.
+ // The only exception is that if there are hashtags embedded in the end sequence, which is not uncommon,
+ // then we still want to show those hashtags but hide everything else that is previewable in the end sequence.
if ind >= hide_text_index {
+ if case .text(let txt) = block, txt.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
+ if case .hashtag = blocks[safe: ind+1] {
+ return str + CompatibleText(stringLiteral: reduce_text_block(ind: ind, hide_text_index: -1, txt: txt))
+ }
+ } else if case .hashtag(let htag) = block {
+ return str + hashtag_str(htag)
+ }
return str
}
}
diff --git a/damusTests/NoteContentViewTests.swift b/damusTests/NoteContentViewTests.swift
@@ -291,6 +291,45 @@ class NoteContentViewTests: XCTestCase {
XCTAssertEqual(noteArtifactsSeparated.images[0].absoluteString, "https://damus.io/nothidden.png")
}
+ func testRenderBlocksWithPreviewableBlocksAtEndAreHiddenWhenHashtagsAreEmbedded() throws {
+ let noteId = test_note.id.bech32
+ let invoiceString = "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r"
+ let content = " Check this out. \nhttps://hidden.tld/\nhttps://damus.io/hidden1.png\n\(invoiceString)\nhttps://damus.io/hidden2.png\nnostr:\(noteId)#hashtag1 #hashtag2 "
+ let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
+ let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
+
+ let testState = test_damus_state
+
+ let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles, can_hide_last_previewable_refs: true)
+ let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
+
+ let runs: AttributedString.Runs = attributedText.runs
+ let runArray: [AttributedString.Runs.Run] = Array(runs)
+ XCTAssertEqual(runArray.count, 4)
+ XCTAssertTrue(runArray[0].description.contains("Check this out."))
+ XCTAssertFalse(runArray[0].description.contains("https://hidden.tld/"))
+ XCTAssertFalse(runArray[0].description.contains("https://damus.io/hidden1.png"))
+ XCTAssertFalse(runArray[0].description.contains("lnbc100n:qpsql29r"))
+ XCTAssertFalse(runArray[0].description.contains("https://damus.io/hidden2.png"))
+ XCTAssertFalse(runArray[0].description.contains("note1qqq:qqn2l0z3"))
+ XCTAssertTrue(runArray[1].description.contains("#hashtag1"))
+ XCTAssertTrue(runArray[3].description.contains("#hashtag2"))
+
+ XCTAssertEqual(noteArtifactsSeparated.images.count, 2)
+ XCTAssertEqual(noteArtifactsSeparated.images[0].absoluteString, "https://damus.io/hidden1.png")
+ XCTAssertEqual(noteArtifactsSeparated.images[1].absoluteString, "https://damus.io/hidden2.png")
+
+ XCTAssertEqual(noteArtifactsSeparated.media.count, 2)
+ XCTAssertEqual(noteArtifactsSeparated.media[0].url.absoluteString, "https://damus.io/hidden1.png")
+ XCTAssertEqual(noteArtifactsSeparated.media[1].url.absoluteString, "https://damus.io/hidden2.png")
+
+ XCTAssertEqual(noteArtifactsSeparated.links.count, 1)
+ XCTAssertEqual(noteArtifactsSeparated.links[0].absoluteString, "https://hidden.tld/")
+
+ XCTAssertEqual(noteArtifactsSeparated.invoices.count, 1)
+ XCTAssertEqual(noteArtifactsSeparated.invoices[0].string, invoiceString)
+ }
+
/// Based on https://github.com/damus-io/damus/issues/1468
/// Tests whether a note content view correctly parses an image block when url in JSON content contains optional escaped slashes
func testParseImageBlockInContentWithEscapedSlashes() throws {