feat: add compatibility for legacy comments

This commit is contained in:
codytseng 2025-12-23 23:30:57 +08:00
parent 0ee93718da
commit 96abe5f24f
4 changed files with 61 additions and 24 deletions

View file

@ -16,7 +16,7 @@ import { Event, kinds, nip19 } from 'nostr-tools'
import { import {
getReplaceableCoordinate, getReplaceableCoordinate,
getReplaceableCoordinateFromEvent, getReplaceableCoordinateFromEvent,
getRootETag, getRootTag,
isProtectedEvent, isProtectedEvent,
isReplaceableEvent isReplaceableEvent
} from './event' } from './event'
@ -153,7 +153,7 @@ export async function createShortTextNoteDraftEvent(
} = {} } = {}
): Promise<TDraftEvent> { ): Promise<TDraftEvent> {
const { content: transformedEmojisContent, emojiTags } = transformCustomEmojisInContent(content) const { content: transformedEmojisContent, emojiTags } = transformCustomEmojisInContent(content)
const { quoteTags, rootETag, parentETag } = await extractRelatedEventIds( const { quoteTags, rootTag, parentTag } = await extractRelatedEventIds(
transformedEmojisContent, transformedEmojisContent,
options.parentEvent options.parentEvent
) )
@ -170,13 +170,13 @@ export async function createShortTextNoteDraftEvent(
// q tags // q tags
tags.push(...quoteTags) tags.push(...quoteTags)
// e tags // thread tags
if (rootETag.length) { if (rootTag) {
tags.push(rootETag) tags.push(rootTag)
} }
if (parentETag.length) { if (parentTag) {
tags.push(parentETag) tags.push(parentTag)
} }
// p tags // p tags
@ -640,36 +640,42 @@ function generateImetaTags(imageUrls: string[]) {
} }
async function extractRelatedEventIds(content: string, parentEvent?: Event) { async function extractRelatedEventIds(content: string, parentEvent?: Event) {
let rootETag: string[] = [] let rootTag: string[] | null = null
let parentETag: string[] = [] let parentTag: string[] | null = null
const quoteTags = extractQuoteTags(content) const quoteTags = extractQuoteTags(content)
if (parentEvent) { if (parentEvent) {
const _rootETag = getRootETag(parentEvent) const _rootTag = getRootTag(parentEvent)
if (_rootETag) { if (_rootTag?.type === 'e') {
parentETag = buildETagWithMarker(parentEvent.id, parentEvent.pubkey, '', 'reply') parentTag = buildETagWithMarker(parentEvent.id, parentEvent.pubkey, '', 'reply')
const [, rootEventHexId, hint, , rootEventPubkey] = _rootETag const [, rootEventHexId, hint, , rootEventPubkey] = _rootTag.tag
if (rootEventPubkey) { if (rootEventPubkey) {
rootETag = buildETagWithMarker(rootEventHexId, rootEventPubkey, hint, 'root') rootTag = buildETagWithMarker(rootEventHexId, rootEventPubkey, hint, 'root')
} else { } else {
const rootEventId = generateBech32IdFromETag(_rootETag) const rootEventId = generateBech32IdFromETag(_rootTag.tag)
const rootEvent = rootEventId ? await client.fetchEvent(rootEventId) : undefined const rootEvent = rootEventId ? await client.fetchEvent(rootEventId) : undefined
rootETag = rootEvent rootTag = rootEvent
? buildETagWithMarker(rootEvent.id, rootEvent.pubkey, hint, 'root') ? buildETagWithMarker(rootEvent.id, rootEvent.pubkey, hint, 'root')
: buildETagWithMarker(rootEventHexId, rootEventPubkey, hint, 'root') : buildETagWithMarker(rootEventHexId, rootEventPubkey, hint, 'root')
} }
}
if (_rootTag?.type === 'a') {
// Legacy
parentTag = buildETagWithMarker(parentEvent.id, parentEvent.pubkey, '', 'reply')
const [, coordinate, hint] = _rootTag.tag
rootTag = buildLegacyRootATag(coordinate, hint)
} else { } else {
// reply to root event // reply to root event
rootETag = buildETagWithMarker(parentEvent.id, parentEvent.pubkey, '', 'root') rootTag = buildETagWithMarker(parentEvent.id, parentEvent.pubkey, '', 'root')
} }
} }
return { return {
quoteTags, quoteTags,
rootETag, rootTag,
parentETag parentTag
} }
} }
@ -823,6 +829,16 @@ function buildETagWithMarker(
return trimTagEnd(['e', eventHexId, hint, marker, pubkey]) return trimTagEnd(['e', eventHexId, hint, marker, pubkey])
} }
function buildLegacyRootATag(coordinate: string, hint: string = '') {
if (!hint) {
const evt = client.getReplaeableEventFromCache(coordinate)
if (evt) {
hint = client.getEventHint(evt.id)
}
}
return trimTagEnd(['a', coordinate, hint, 'root'])
}
function buildITag(url: string, upperCase: boolean = false) { function buildITag(url: string, upperCase: boolean = false) {
return [upperCase ? 'I' : 'i', url] return [upperCase ? 'I' : 'i', url]
} }

View file

@ -83,6 +83,14 @@ export function getParentETag(event?: Event) {
return tag return tag
} }
function getLegacyParentATag(event?: Event) {
if (!event || event.kind !== kinds.ShortTextNote) {
return undefined
}
return event.tags.find(([tagName, , , marker]) => tagName === 'a' && marker === 'reply')
}
export function getParentATag(event?: Event) { export function getParentATag(event?: Event) {
if ( if (
!event || !event ||
@ -114,8 +122,9 @@ export function getParentTag(event?: Event): { type: 'e' | 'a' | 'i'; tag: strin
if (!event) return undefined if (!event) return undefined
if (event.kind === kinds.ShortTextNote) { if (event.kind === kinds.ShortTextNote) {
const tag = getParentETag(event) const tag = getLegacyParentATag(event) ?? getParentETag(event) ?? getLegacyRootATag(event)
return tag ? { type: 'e', tag } : undefined if (!tag) return undefined
return { type: tag[0] === 'e' ? 'e' : 'a', tag }
} }
// NIP-22 // NIP-22
@ -164,6 +173,14 @@ export function getRootETag(event?: Event) {
return tag return tag
} }
function getLegacyRootATag(event?: Event) {
if (!event || event.kind !== kinds.ShortTextNote) {
return undefined
}
return event.tags.find(([tagName, , , marker]) => tagName === 'a' && marker === 'root')
}
export function getRootATag(event?: Event) { export function getRootATag(event?: Event) {
if ( if (
!event || !event ||
@ -195,8 +212,9 @@ export function getRootTag(event?: Event): { type: 'e' | 'a' | 'i'; tag: string[
if (!event) return undefined if (!event) return undefined
if (event.kind === kinds.ShortTextNote) { if (event.kind === kinds.ShortTextNote) {
const tag = getRootETag(event) const tag = getLegacyRootATag(event) ?? getRootETag(event)
return tag ? { type: 'e', tag } : undefined if (!tag) return undefined
return { type: tag[0] === 'e' ? 'e' : 'a', tag }
} }
// NIP-22 // NIP-22

View file

@ -842,6 +842,10 @@ class ClientService extends EventTarget {
} }
} }
getReplaeableEventFromCache(coordinate: string): NEvent | undefined {
return this.replaceableEventCacheMap.get(coordinate)
}
private async fetchEventById(relayUrls: string[], id: string): Promise<NEvent | undefined> { private async fetchEventById(relayUrls: string[], id: string): Promise<NEvent | undefined> {
const event = await this.fetchEventFromBigRelaysDataloader.load(id) const event = await this.fetchEventFromBigRelaysDataloader.load(id)
if (event) { if (event) {

View file

@ -17,7 +17,6 @@ class FayanService {
return new Array(pubkeys.length).fill(null) return new Array(pubkeys.length).fill(null)
} }
const data = await res.json() const data = await res.json()
console.log('FayanService fetched user percentiles:', data)
return pubkeys.map((pubkey) => data[pubkey] ?? null) return pubkeys.map((pubkey) => data[pubkey] ?? null)
} catch { } catch {
return new Array(pubkeys.length).fill(null) return new Array(pubkeys.length).fill(null)