[comments] align count with displayed kinds + preserve multi-line content

- discussionCountService now counts getAllowedCommentKinds() (NIP-22 kind 1111
  + legacy kind 1) instead of 1111-only, so the discussion badge no longer
  undercounts threads that contain legacy comments. The count filters are
  derived from the same source the thread display uses, so they can't drift.
- Add white-space: pre-wrap to .comment-thread__body so comments with line
  breaks/paragraphs preserve them instead of collapsing into one run-on line
  (long lines still wrap via word-break: break-word).

Test: spec-corrected discussion-count-service to assert the count filters use
getAllowedCommentKinds() (reverting to 1111-only fails the deepEqual).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-18 12:15:46 -04:00
1 parent 89747d7290
commit 6f5da76d30
3 files changed
+25 -11

No files matched your search

+4
View File
@@ -2721,6 +2721,10 @@
color: var(--text-primary);
line-height: 1.6;
word-break: break-word;
/* Comment content is inserted as a single text node, so preserve the
author's line breaks/paragraphs instead of collapsing them into one
run-on line. pre-wrap keeps newlines while still wrapping long lines. */
white-space: pre-wrap;
}
.comment-thread__actions {
+9 -4
View File
@@ -1,6 +1,6 @@
import { devLogger } from "../utils/logger.js";
import { buildVideoAddressPointer } from "../utils/videoPointer.js";
import { COMMENT_EVENT_KIND } from "../nostr/commentEvents.js";
import { getAllowedCommentKinds } from "../nostr/commentTargetNormalizer.js";
const DEFAULT_MAX_DISCUSSION_COUNT_VIDEOS = 24;
const COUNT_UNSUPPORTED_TITLE = "Relay does not support NIP-45 COUNT queries.";
@@ -131,17 +131,22 @@ export default class DiscussionCountService {
return [];
}
// Count the same kinds the thread actually displays (NIP-22 kind 1111 plus
// legacy kind 1). Counting only 1111 made the badge undercount threads that
// contain legacy comments.
const commentKinds = getAllowedCommentKinds();
const filters = [];
const eventId = typeof video.id === "string" ? video.id.trim() : "";
if (eventId) {
filters.push({ kinds: [COMMENT_EVENT_KIND], "#E": [eventId] });
filters.push({ kinds: commentKinds, "#E": [eventId] });
}
const address = buildVideoAddressPointer(video);
const rootIdentifier =
typeof video.videoRootId === "string" ? video.videoRootId.trim() : "";
const uppercaseFilter = { kinds: [COMMENT_EVENT_KIND] };
const uppercaseFilter = { kinds: commentKinds };
let hasUppercasePointer = false;
if (rootIdentifier) {
@@ -184,7 +189,7 @@ export default class DiscussionCountService {
}
if (address) {
filters.push({ kinds: [COMMENT_EVENT_KIND], "#A": [address] });
filters.push({ kinds: commentKinds, "#A": [address] });
}
return filters;
+12 -7
View File
@@ -6,7 +6,12 @@ import { JSDOM } from "jsdom";
import DiscussionCountService, {
COUNT_UNSUPPORTED_TITLE,
} from "../js/services/discussionCountService.js";
import { COMMENT_EVENT_KIND } from "../js/nostr/commentEvents.js";
import { getAllowedCommentKinds } from "../js/nostr/commentTargetNormalizer.js";
// SPEC CHANGE: the discussion-count badge now counts the same kinds the thread
// displays (NIP-22 kind 1111 + legacy kind 1) instead of only 1111, so it no
// longer undercounts threads that contain legacy comments.
const COMMENT_KINDS = getAllowedCommentKinds();
function createDomWithCountElement(videoId) {
const dom = new JSDOM(`
@@ -39,17 +44,17 @@ async function testRefreshCountsCachesResults() {
assert.equal(filters.length, 3, "should request id, uppercase, and address filters");
const [eventFilter, uppercaseFilter, addressFilter] = filters;
assert.deepEqual(eventFilter, {
kinds: [COMMENT_EVENT_KIND],
kinds: COMMENT_KINDS,
"#E": ["count-video-1"],
});
assert.deepEqual(uppercaseFilter, {
kinds: [COMMENT_EVENT_KIND],
kinds: COMMENT_KINDS,
"#A": ["30078:pubkey-1:identifier-1"],
"#K": ["30078"],
"#P": ["pubkey-1"],
});
assert.deepEqual(addressFilter, {
kinds: [COMMENT_EVENT_KIND],
kinds: COMMENT_KINDS,
"#A": ["30078:pubkey-1:identifier-1"],
});
return {
@@ -122,17 +127,17 @@ async function testUnsupportedRelaysUpdateDomState() {
assert.equal(filters.length, 3, "unsupported relays should still receive all filters");
const [eventFilter, uppercaseFilter, addressFilter] = filters;
assert.deepEqual(eventFilter, {
kinds: [COMMENT_EVENT_KIND],
kinds: COMMENT_KINDS,
"#E": ["unsupported-video"],
});
assert.deepEqual(uppercaseFilter, {
kinds: [COMMENT_EVENT_KIND],
kinds: COMMENT_KINDS,
"#A": ["30078:pubkey-2:identifier-2"],
"#K": ["30078"],
"#P": ["pubkey-2"],
});
assert.deepEqual(addressFilter, {
kinds: [COMMENT_EVENT_KIND],
kinds: COMMENT_KINDS,
"#A": ["30078:pubkey-2:identifier-2"],
});
return {