import "./ReactionsModal.css"; import { NostrLink, socialGraphInstance, TaggedNostrEvent } from "@snort/system"; import { useEventReactions, useReactions } from "@snort/system-react"; import { useMemo, useState } from "react"; import { FormattedMessage, MessageDescriptor, useIntl } from "react-intl"; import CloseButton from "@/Components/Button/CloseButton"; import Icon from "@/Components/Icons/Icon"; import Modal from "@/Components/Modal/Modal"; import TabSelectors, { Tab } from "@/Components/TabSelectors/TabSelectors"; import ProfileImage from "@/Components/User/ProfileImage"; import { formatShort } from "@/Utils/Number"; import messages from "../../messages"; interface ReactionsModalProps { onClose(): void; event: TaggedNostrEvent; initialTab?: number; } const ReactionsModal = ({ onClose, event, initialTab = 0 }: ReactionsModalProps) => { const { formatMessage } = useIntl(); const link = NostrLink.fromEvent(event); const related = useReactions(`reactions:${link.tagKey}`, link, undefined, false); const { reactions, zaps, reposts } = useEventReactions(link, related); const { positive, negative } = reactions; const sortEvents = (events: Array) => events.sort( (a, b) => socialGraphInstance.getFollowDistance(a.pubkey) - socialGraphInstance.getFollowDistance(b.pubkey), ); const likes = useMemo(() => sortEvents([...positive]), [positive]); const dislikes = useMemo(() => sortEvents([...negative]), [negative]); const sortedReposts = useMemo(() => sortEvents([...reposts]), [reposts]); const total = positive.length + negative.length + zaps.length + reposts.length; const createTab = (message: MessageDescriptor, count: number, value: number, disabled = false) => ({ text: formatMessage(message, { n: count }), value, disabled, }) as Tab; const tabs = useMemo(() => { const baseTabs = [ createTab(messages.Likes, likes.length, 0), createTab(messages.Zaps, zaps.length, 1, zaps.length === 0), createTab(messages.Reposts, reposts.length, 2, reposts.length === 0), ]; return dislikes.length !== 0 ? baseTabs.concat(createTab(messages.Dislikes, dislikes.length, 3)) : baseTabs; }, [likes.length, zaps.length, reposts.length, dislikes.length, formatMessage]); const [tab, setTab] = useState(tabs[initialTab]); const renderReactionItem = (ev: TaggedNostrEvent, icon: string, iconClass?: string, size?: number) => (
); return (

{tab.value === 0 && likes.map(ev => renderReactionItem(ev, "heart-solid", "text-heart"))} {tab.value === 1 && zaps.map( z => z.sender && (
{formatShort(z.amount)}
{z.content}
} link={z.anonZap ? "" : undefined} overrideUsername={ z.anonZap ? formatMessage({ defaultMessage: "Anonymous", id: "LXxsbk" }) : undefined } />
), )} {tab.value === 2 && sortedReposts.map(ev => renderReactionItem(ev, "repost", "text-repost", 16))} {tab.value === 3 && dislikes.map(ev => renderReactionItem(ev, "dislike"))}
); }; export default ReactionsModal;