diff --git a/packages/app/src/Components/Event/Note/NoteInner.tsx b/packages/app/src/Components/Event/Note/NoteInner.tsx index c1f40d52..4d103ab9 100644 --- a/packages/app/src/Components/Event/Note/NoteInner.tsx +++ b/packages/app/src/Components/Event/Note/NoteInner.tsx @@ -1,20 +1,18 @@ -import { EventExt, EventKind, HexKey, NostrLink, NostrPrefix, TaggedNostrEvent } from "@snort/system"; +import { EventKind, HexKey, NostrLink, NostrPrefix, TaggedNostrEvent } from "@snort/system"; import classNames from "classnames"; -import React, { ReactNode, useState } from "react"; +import React, { useState } from "react"; import { useInView } from "react-intersection-observer"; import { FormattedMessage, useIntl } from "react-intl"; -import { Link, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; -import { UserCache } from "@/Cache"; import { NoteText } from "@/Components/Event/Note/NoteText"; +import ReplyTag from "@/Components/Event/Note/ReplyTag"; import Icon from "@/Components/Icons/Icon"; -import DisplayName from "@/Components/User/DisplayName"; -import { ProfileLink } from "@/Components/User/ProfileLink"; import useEventPublisher from "@/Hooks/useEventPublisher"; import useLogin from "@/Hooks/useLogin"; import useModeration from "@/Hooks/useModeration"; import { chainKey } from "@/Hooks/useThreadContext"; -import { findTag, hexToBech32 } from "@/Utils"; +import { findTag } from "@/Utils"; import { setBookmarked, setPinned } from "@/Utils/Login"; import messages from "../../messages"; @@ -111,62 +109,6 @@ export function NoteInner(props: NoteProps) { } } - function replyTag() { - const thread = EventExt.extractThread(ev); - if (thread === undefined) { - return undefined; - } - - const maxMentions = 2; - const replyTo = thread?.replyTo ?? thread?.root; - const replyLink = replyTo - ? NostrLink.fromTag( - [replyTo.key, replyTo.value ?? "", replyTo.relay ?? "", replyTo.marker ?? ""].filter(a => a.length > 0), - ) - : undefined; - const mentions: { pk: string; name: string; link: ReactNode }[] = []; - for (const pk of thread?.pubKeys ?? []) { - const u = UserCache.getFromCache(pk); - const npub = hexToBech32(NostrPrefix.PublicKey, pk); - const shortNpub = npub.substring(0, 12); - mentions.push({ - pk, - name: u?.name ?? shortNpub, - link: ( - - {" "} - - ), - }); - } - mentions.sort(a => (a.name.startsWith(NostrPrefix.PublicKey) ? 1 : -1)); - const othersLength = mentions.length - maxMentions; - const renderMention = (m: { link: React.ReactNode; pk: string; name: string }, idx: number) => { - return ( - - {idx > 0 && ", "} - {m.link} - - ); - }; - const pubMentions = - mentions.length > maxMentions ? mentions?.slice(0, maxMentions).map(renderMention) : mentions?.map(renderMention); - const others = mentions.length > maxMentions ? formatMessage(messages.Others, { n: othersLength }) : ""; - const link = replyLink?.encode(CONFIG.eventLinkPrefix); - return ( -
- re:  - {(mentions?.length ?? 0) > 0 ? ( - <> - {pubMentions} {others} - - ) : ( - replyLink && {link?.substring(0, 12)} - )} -
- ); - } - const canRenderAsTextNote = [EventKind.TextNote, EventKind.Polls]; if (!canRenderAsTextNote.includes(ev.kind)) { const alt = findTag(ev, "alt"); @@ -225,7 +167,7 @@ export function NoteInner(props: NoteProps) {
} link={opt?.canClick === undefined ? undefined : ""} showProfileCard={options.showProfileCard ?? true} showBadges={true} diff --git a/packages/app/src/Components/Event/Note/ReplyTag.tsx b/packages/app/src/Components/Event/Note/ReplyTag.tsx new file mode 100644 index 00000000..bf9bdd16 --- /dev/null +++ b/packages/app/src/Components/Event/Note/ReplyTag.tsx @@ -0,0 +1,67 @@ +import { EventExt, NostrLink, NostrPrefix, TaggedNostrEvent } from "@snort/system"; +import React, { ReactNode } from "react"; +import { useIntl } from "react-intl"; +import { Link } from "react-router-dom"; + +import { UserCache } from "@/Cache"; +import messages from "@/Components/messages"; +import DisplayName from "@/Components/User/DisplayName"; +import { ProfileLink } from "@/Components/User/ProfileLink"; +import { hexToBech32 } from "@/Utils"; + +export default function ReplyTag({ ev }: { ev: TaggedNostrEvent }) { + const { formatMessage } = useIntl(); + const thread = EventExt.extractThread(ev); + if (thread === undefined) { + return undefined; + } + + const maxMentions = 2; + const replyTo = thread?.replyTo ?? thread?.root; + const replyLink = replyTo + ? NostrLink.fromTag( + [replyTo.key, replyTo.value ?? "", replyTo.relay ?? "", replyTo.marker ?? ""].filter(a => a.length > 0), + ) + : undefined; + const mentions: { pk: string; name: string; link: ReactNode }[] = []; + for (const pk of thread?.pubKeys ?? []) { + const u = UserCache.getFromCache(pk); + const npub = hexToBech32(NostrPrefix.PublicKey, pk); + const shortNpub = npub.substring(0, 12); + mentions.push({ + pk, + name: u?.name ?? shortNpub, + link: ( + + {" "} + + ), + }); + } + mentions.sort(a => (a.name.startsWith(NostrPrefix.PublicKey) ? 1 : -1)); + const othersLength = mentions.length - maxMentions; + const renderMention = (m: { link: React.ReactNode; pk: string; name: string }, idx: number) => { + return ( + + {idx > 0 && ", "} + {m.link} + + ); + }; + const pubMentions = + mentions.length > maxMentions ? mentions?.slice(0, maxMentions).map(renderMention) : mentions?.map(renderMention); + const others = mentions.length > maxMentions ? formatMessage(messages.Others, { n: othersLength }) : ""; + const link = replyLink?.encode(CONFIG.eventLinkPrefix); + return ( +
+ re:  + {(mentions?.length ?? 0) > 0 ? ( + <> + {pubMentions} {others} + + ) : ( + replyLink && {link?.substring(0, 12)} + )} +
+ ); +}