Find a comment's root through reader(Comment).root() instead of three hand-rolled K/A/E parsers

This commit is contained in:
Jon Staab 2026-09-25 16:00:58 -07:00
parent e7c7fac112
commit f130af4edd
3 changed files with 42 additions and 20 deletions

View file

@ -1,6 +1,18 @@
import {derived, get, readable, writable} from "svelte/store"
import type {Readable} from "svelte/store"
import {batch, call, int, ms, now, on, sleep, uniqBy, MONTH, YEAR} from "@welshman/lib"
import {
batch,
call,
int,
ms,
now,
on,
removeUndefined,
sleep,
uniqBy,
MONTH,
YEAR,
} from "@welshman/lib"
import {
COMMENT,
DELETE,
@ -17,7 +29,7 @@ import {
matchFilters,
tagValues,
} from "@welshman/util"
import {TimeEvent} from "@welshman/domain"
import {Comment, TimeEvent} from "@welshman/domain"
import type {Maybe} from "@welshman/lib"
import type {Filter, TrustedEvent} from "@welshman/util"
import {mergeRepositoryUpdates} from "@welshman/net"
@ -51,10 +63,15 @@ const mergeSorted = <T>(left: T[], right: T[], compare: (a: T, b: T) => number)
}
// A NIP-22 comment points at its thread root with `E`/`A`, which is the scope a reply count wants.
const getTargets = ({kind, tags}: TrustedEvent) =>
kind === COMMENT
? [...tagValues(hexTags("E"), tags), ...tagValues(addressTags("A"), tags)]
: [...tagValues(hexTags("e"), tags), ...tagValues(addressTags("a"), tags)]
const getTargets = (event: TrustedEvent) => {
if (event.kind === COMMENT) {
const {id, address} = reader(Comment)(event).root()
return removeUndefined([id, address])
}
return [...tagValues(hexTags("e"), event.tags), ...tagValues(addressTags("a"), event.tags)]
}
// A related event may point at a replaceable one by either id or address, so both are keys
const getKeys = (event: TrustedEvent) =>

View file

@ -13,10 +13,11 @@ import {
makeHttpAuth,
makeHttpAuthHeader,
} from "@welshman/util"
import {Comment} from "@welshman/domain"
import {synced, throttled, withGetter} from "@welshman/store"
import {Relays, RoomLists} from "@welshman/app"
import {deriveEventsByIdByUrl} from "@app/repository"
import {app, fromApp} from "@app/core"
import {app, fromApp, reader} from "@app/core"
import {makeRoomPath, makeSpaceChatPath, makeChatPath, makeContentPath} from "@app/routes"
import {CONTENT_KINDS, makeCommentFilter} from "@app/content"
import {getIsMuted, notificationSettings, userSettingsValues} from "@app/settings"
@ -185,8 +186,9 @@ const getContentTarget = (event: TrustedEvent) => {
}
if (event.kind === COMMENT) {
const kind = parseInt(tagValue(tagSpec("K"), event.tags) || "")
const idOrAddress = tagValue(tagSpec("A"), event.tags) || tagValue(tagSpec("E"), event.tags)
const root = reader(Comment)(event).root()
const kind = parseInt(root.kind || "")
const idOrAddress = root.address || root.id
if (CONTENT_KINDS.includes(kind) && idOrAddress) {
return {kind, idOrAddress}

View file

@ -5,6 +5,7 @@ import {identity, tryCatch} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util"
import {
CLASSIFIED,
COMMENT,
EVENT_TIME,
LONG_FORM,
MESSAGE,
@ -19,7 +20,8 @@ import {
tagValue,
tagValues,
} from "@welshman/util"
import {app, messagingRelayLists, user} from "@app/core"
import {Comment} from "@welshman/domain"
import {app, messagingRelayLists, reader, user} from "@app/core"
import {makeChatId} from "@app/chats"
import {entityLink, PLATFORM_URL, PLATFORM_RELAYS} from "@app/env"
import {decodeRelay, encodeRelay} from "@app/relays"
@ -219,19 +221,20 @@ export const makeEventPath = (event: TrustedEvent, urls: string[]) => {
return path
}
const parentKind = tagValue(tagSpec("K"), event.tags)
const parentIdOrAddress =
tagValue(tagSpec("A"), event.tags) ?? tagValue(tagSpec("E"), event.tags)
if (event.kind === COMMENT) {
const root = reader(Comment)(event).root()
const rootIdOrAddress = root.address ?? root.id
if (parentKind && parentIdOrAddress) {
if (parseInt(parentKind) === MESSAGE) {
return makeMessagePath(url, event)
}
if (root.kind && rootIdOrAddress) {
if (parseInt(root.kind) === MESSAGE) {
return makeMessagePath(url, event)
}
const parentPath = makeContentPath(url, parseInt(parentKind), parentIdOrAddress)
const rootPath = makeContentPath(url, parseInt(root.kind), rootIdOrAddress)
if (parentPath) {
return parentPath
if (rootPath) {
return rootPath
}
}
}
}