import { normalizeReaction } from "@snort/shared";
import { countLeadingZeros, NostrLink, TaggedNostrEvent } from "@snort/system";
import { useEventReactions, useReactions } from "@snort/system-react";
import { Menu, MenuItem } from "@szhsin/react-menu";
import classNames from "classnames";
import React, { useMemo } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { AsyncFooterIcon } from "@/Components/Event/Note/NoteFooter/AsyncFooterIcon";
import { FooterZapButton } from "@/Components/Event/Note/NoteFooter/FooterZapButton";
import Icon from "@/Components/Icons/Icon";
import useEventPublisher from "@/Hooks/useEventPublisher";
import { useInteractionCache } from "@/Hooks/useInteractionCache";
import useLogin from "@/Hooks/useLogin";
import { useNoteCreator } from "@/State/NoteCreator";
import { findTag } from "@/Utils";
import messages from "../../../messages";
export interface NoteFooterProps {
replies?: number;
ev: TaggedNostrEvent;
}
export default function NoteFooter(props: NoteFooterProps) {
const { ev } = props;
const link = useMemo(() => NostrLink.fromEvent(ev), [ev.id]);
const ids = useMemo(() => [link], [link]);
const related = useReactions("note:reactions", ids, undefined, false);
const { reactions, zaps, reposts } = useEventReactions(link, related);
const { positive } = reactions;
const { formatMessage } = useIntl();
const {
publicKey,
preferences: prefs,
readonly,
} = useLogin(s => ({ preferences: s.appData.item.preferences, publicKey: s.publicKey, readonly: s.readonly }));
const interactionCache = useInteractionCache(publicKey, ev.id);
const { publisher, system } = useEventPublisher();
const note = useNoteCreator(n => ({ show: n.show, replyTo: n.replyTo, update: n.update, quote: n.quote }));
function hasReacted(emoji: string) {
return (
interactionCache.data.reacted ||
positive?.some(({ pubkey, content }) => normalizeReaction(content) === emoji && pubkey === publicKey)
);
}
function hasReposted() {
return interactionCache.data.reposted || reposts.some(a => a.pubkey === publicKey);
}
async function react(content: string) {
if (!hasReacted(content) && publisher) {
const evLike = await publisher.react(ev, content);
system.BroadcastEvent(evLike);
interactionCache.react();
}
}
async function repost() {
if (!hasReposted() && publisher) {
if (!prefs.confirmReposts || window.confirm(formatMessage(messages.ConfirmRepost, { id: ev.id }))) {
const evRepost = await publisher.repost(ev);
system.BroadcastEvent(evRepost);
await interactionCache.repost();
}
}
}
function powIcon() {
const pow = findTag(ev, "nonce") ? countLeadingZeros(ev.id) : undefined;
if (pow) {
return (