add NIP-22 comments on articles

This commit is contained in:
hzrd149 2025-01-08 11:58:59 -06:00
parent 1b84b7fa9b
commit fc2063bf75
21 changed files with 269 additions and 38 deletions

View File

@ -0,0 +1,5 @@
---
"nostrudel": minor
---
Add NIP-22 comments on articles

View File

@ -22,7 +22,7 @@ import TrackStemstrButton from "../../../views/tracks/components/track-stemstr-b
import TrackDownloadButton from "../../../views/tracks/components/track-download-button";
import TrackPlayer from "../../../views/tracks/components/track-player";
import QuoteEventButton from "../../note/quote-event-button";
import NoteZapButton from "../../note/note-zap-button";
import EventZapButton from "../../zap/event-zap-button";
// example nevent1qqst32cnyhhs7jt578u7vp3y047dduuwjquztpvwqc43f3nvg8dh28gpzamhxue69uhhyetvv9ujuum5v4khxarj9eshquq4rxdxa
export default function EmbeddedStemstrTrack({ track, ...props }: Omit<CardProps, "children"> & { track: NostrEvent }) {
@ -54,7 +54,7 @@ export default function EmbeddedStemstrTrack({ track, ...props }: Omit<CardProps
</Button>
</Tooltip>
<QuoteEventButton event={track} />
<NoteZapButton event={track} />
<EventZapButton event={track} />
</ButtonGroup>
<ButtonGroup size="sm" ml="auto">
<TrackDownloadButton track={track} />

View File

@ -9,7 +9,7 @@ import useEventReactions from "../../hooks/use-event-reactions";
import EventReactionButtons from "../event-reactions/event-reactions";
import { IconThreadButton } from "./thread-button";
import AddReactionButton from "../note/timeline-note/components/add-reaction-button";
import NoteZapButton from "../note/note-zap-button";
import EventZapButton from "../zap/event-zap-button";
import useEventIntersectionRef from "../../hooks/use-event-intersection-ref";
export type MessageBubbleProps = {
@ -36,7 +36,7 @@ export default function MessageBubble({
const actions = (
<>
<NoteZapButton event={message} />
<EventZapButton event={message} />
<AddReactionButton event={message} />
{showThreadButton && <IconThreadButton event={message} aria-label="Open Thread" />}
</>

View File

@ -20,7 +20,7 @@ import { useObservable } from "applesauce-react/hooks";
import NoteMenu from "../note-menu";
import UserLink from "../../user/user-link";
import NoteZapButton from "../note-zap-button";
import EventZapButton from "../../zap/event-zap-button";
import { ExpandProvider } from "../../../providers/local/expanded";
import EventVerificationIcon from "../../common-event/event-verification-icon";
import ShareButton from "./components/share-button";
@ -132,7 +132,7 @@ export function TimelineNote({
)}
<ShareButton event={event} />
<QuoteEventButton event={event} />
<NoteZapButton event={event} />
<EventZapButton event={event} />
</ButtonGroup>
{!showReactionsOnNewLine && reactionButtons}
<Box flexGrow={1} />

View File

@ -19,7 +19,7 @@ export type NoteZapButtonProps = Omit<ButtonProps, "children"> & {
showEventPreview?: boolean;
};
export default function NoteZapButton({ event, allowComment, showEventPreview, ...props }: NoteZapButtonProps) {
export default function EventZapButton({ event, allowComment, showEventPreview, ...props }: NoteZapButtonProps) {
const account = useCurrentAccount();
const { metadata } = useUserLNURLMetadata(event.pubkey);
const zaps = useEventZaps(getEventUID(event)) ?? [];

View File

@ -1,5 +1,5 @@
import { NostrEvent } from "nostr-tools";
import { Box, Flex, Heading, Image, Spinner, Text } from "@chakra-ui/react";
import { Box, Button, Flex, Heading, Image, Spinner, Text, useDisclosure } from "@chakra-ui/react";
import dayjs from "dayjs";
import useParamsAddressPointer from "../../hooks/use-params-address-pointer";
@ -18,10 +18,13 @@ import MarkdownContent from "../../components/markdown/markdown";
import ArticleMenu from "./components/article-menu";
import ArticleTags from "./components/article-tags";
import NoteReactions from "../../components/note/timeline-note/components/note-reactions";
import NoteZapButton from "../../components/note/note-zap-button";
import EventZapButton from "../../components/zap/event-zap-button";
import ZapBubbles from "../../components/note/timeline-note/components/zap-bubbles";
import BookmarkEventButton from "../../components/note/bookmark-event";
import QuoteEventButton from "../../components/note/quote-event-button";
import { ArticleComments } from "./components/article-comments";
import ArticleCommentForm from "./components/article-comment-form";
import { ThreadIcon } from "../../components/icons";
function ArticlePage({ article }: { article: NostrEvent }) {
const image = getArticleImage(article);
@ -29,8 +32,10 @@ function ArticlePage({ article }: { article: NostrEvent }) {
const published = getArticlePublishDate(article);
const summary = getArticleSummary(article);
const comment = useDisclosure();
return (
<VerticalPageLayout pt={{ base: "2", lg: "8" }} pb="12">
<VerticalPageLayout pt={{ base: "2", lg: "8" }} pb="32">
<Box mx="auto" maxW="4xl" w="full" mb="2">
<ArticleMenu article={article} aria-label="More Options" float="right" />
<Heading size="xl">{title}</Heading>
@ -46,10 +51,10 @@ function ArticlePage({ article }: { article: NostrEvent }) {
<BookmarkEventButton event={article} aria-label="Bookmark" variant="ghost" float="right" size="sm" />
</Box>
{image && <Image src={image} maxW="6xl" w="full" mx="auto" maxH="60vh" />}
<Box mx="auto" maxW="4xl" w="full">
<Box mx="auto" maxW="4xl" w="full" mb="8">
<ZapBubbles event={article} mb="2" />
<Flex gap="2">
<NoteZapButton event={article} size="sm" variant="ghost" showEventPreview={false} />
<EventZapButton event={article} size="sm" variant="ghost" showEventPreview={false} />
<QuoteEventButton event={article} size="sm" variant="ghost" />
<NoteReactions event={article} size="sm" variant="ghost" />
</Flex>
@ -57,11 +62,22 @@ function ArticlePage({ article }: { article: NostrEvent }) {
<MarkdownContent event={article} />
</Box>
<Flex gap="2">
<NoteZapButton event={article} size="sm" variant="ghost" showEventPreview={false} />
<EventZapButton event={article} size="sm" variant="ghost" showEventPreview={false} />
<QuoteEventButton event={article} size="sm" variant="ghost" />
<NoteReactions event={article} size="sm" variant="ghost" />
</Flex>
</Box>
<Flex mx="auto" maxW="4xl" w="full" gap="2" direction="column">
{comment.isOpen ? (
<ArticleCommentForm event={article} onCancel={comment.onClose} onSubmitted={comment.onClose} />
) : (
<Button leftIcon={<ThreadIcon />} onClick={comment.onOpen} mr="auto">
Comment
</Button>
)}
<ArticleComments article={article} />
</Flex>
</VerticalPageLayout>
);
}

View File

@ -0,0 +1,100 @@
import { useRef } from "react";
import { NostrEvent } from "nostr-tools";
import { useEventFactory } from "applesauce-react/hooks";
import { getEventUID } from "applesauce-core/helpers";
import { useForm } from "react-hook-form";
import { useAsync, useThrottle } from "react-use";
import { usePublishEvent } from "../../../providers/global/publish-provider";
import { useContextEmojis } from "../../../providers/global/emoji-provider";
import useTextAreaUploadFile, { useTextAreaInsertTextWithForm } from "../../../hooks/use-textarea-upload-file";
import MagicTextArea, { RefType } from "../../../components/magic-textarea";
import useCacheForm from "../../../hooks/use-cache-form";
import { Box, Button, ButtonGroup, Flex } from "@chakra-ui/react";
import InsertImageButton from "../../new/note/insert-image-button";
import InsertGifButton from "../../../components/gif/insert-gif-button";
import { TrustProvider } from "../../../providers/local/trust-provider";
import TextNoteContents from "../../../components/note/timeline-note/text-note-contents";
export default function ArticleCommentForm({
event,
onSubmitted,
onCancel,
}: {
event: NostrEvent;
onSubmitted?: (comment: NostrEvent) => void;
onCancel?: () => void;
}) {
const publish = usePublishEvent();
const factory = useEventFactory();
const emojis = useContextEmojis();
const { setValue, getValues, watch, handleSubmit, formState, reset } = useForm({
defaultValues: {
content: "",
},
mode: "all",
});
const clearCache = useCacheForm<{ content: string }>(`comment-${getEventUID(event)}`, getValues, reset, formState);
watch("content");
const textAreaRef = useRef<RefType | null>(null);
const insertText = useTextAreaInsertTextWithForm(textAreaRef, getValues, setValue);
const { onPaste } = useTextAreaUploadFile(insertText);
const submit = handleSubmit(async (values) => {
const draft = await factory.comment(event, values.content, { emojis });
const pub = await publish("Comment", draft);
if (pub && onSubmitted) onSubmitted(pub.event);
clearCache();
});
const formRef = useRef<HTMLFormElement | null>(null);
// throttle preview
const throttleValues = useThrottle(getValues(), 500);
const { value: preview } = useAsync(
() => factory.comment(event, throttleValues.content, { emojis }),
[throttleValues, emojis],
);
return (
<Flex as="form" direction="column" gap="2" pb="4" onSubmit={submit} ref={formRef}>
<MagicTextArea
placeholder="Comment"
autoFocus
mb="2"
rows={4}
isRequired
value={getValues().content}
onChange={(e) => setValue("content", e.target.value, { shouldDirty: true })}
instanceRef={(inst) => (textAreaRef.current = inst)}
onPaste={onPaste}
onKeyDown={(e) => {
if ((e.ctrlKey || e.metaKey) && e.key === "Enter" && formRef.current) formRef.current.requestSubmit();
}}
/>
<Flex gap="2" alignItems="center">
<InsertImageButton onUploaded={insertText} size="sm" aria-label="Upload image" />
<InsertGifButton onSelectURL={insertText} aria-label="Add gif" size="sm" />
<ButtonGroup size="sm" ml="auto">
{onCancel && <Button onClick={onCancel}>Cancel</Button>}
<Button type="submit" colorScheme="primary" size="sm">
Comment
</Button>
</ButtonGroup>
</Flex>
{preview && preview.content.length > 0 && (
<Box p="2" borderWidth={1} borderRadius="md" mb="2">
<TrustProvider trust>
<TextNoteContents event={preview} />
</TrustProvider>
</Box>
)}
</Flex>
);
}

View File

@ -0,0 +1,110 @@
import {
Box,
Button,
ButtonGroup,
Card,
CardBody,
CardFooter,
CardHeader,
Flex,
IconButton,
useDisclosure,
} from "@chakra-ui/react";
import { NostrEvent } from "nostr-tools";
import { COMMENT_KIND, getEventUID } from "applesauce-core/helpers";
import { useStoreQuery } from "applesauce-react/hooks";
import { CommentsQuery, RepliesQuery } from "applesauce-core/queries";
import Timestamp from "../../../components/timestamp";
import DebugEventButton from "../../../components/debug-modal/debug-event-button";
import UserLink from "../../../components/user/user-link";
import TextNoteContents from "../../../components/note/timeline-note/text-note-contents";
import { useReadRelays } from "../../../hooks/use-client-relays";
import useTimelineLoader from "../../../hooks/use-timeline-loader";
import { useTimelineCurserIntersectionCallback } from "../../../hooks/use-timeline-cursor-intersection-callback";
import IntersectionObserverProvider from "../../../providers/local/intersection-observer";
import UserAvatarLink from "../../../components/user/user-avatar-link";
import UserDnsIdentity from "../../../components/user/user-dns-identity";
import ArticleCommentForm from "./article-comment-form";
import NoteReactions from "../../../components/note/timeline-note/components/note-reactions";
import { ChevronDownIcon, ChevronUpIcon, ReplyIcon } from "../../../components/icons";
import EventZapButton from "../../../components/zap/event-zap-button";
function Comment({ comment }: { comment: NostrEvent }) {
const reply = useDisclosure();
const replies = useStoreQuery(RepliesQuery, [comment]);
const expand = useDisclosure({ defaultIsOpen: true });
const all = useDisclosure();
return (
<>
<Card>
<CardHeader px="4" py="2" display="flex" gap="2" alignItems="center">
<UserAvatarLink pubkey={comment.pubkey} size="sm" />
<Box>
<UserLink pubkey={comment.pubkey} fontWeight="bold" me="2" />
<Timestamp timestamp={comment.created_at} />
<br />
<UserDnsIdentity pubkey={comment.pubkey} />
</Box>
<ButtonGroup ms="auto" variant="ghost" size="sm" alignItems="center">
<EventZapButton event={comment} aria-label="Zap comment" />
<DebugEventButton event={comment} />
</ButtonGroup>
</CardHeader>
<CardBody px="4" py="0">
<TextNoteContents event={comment} />
</CardBody>
<CardFooter p="2" gap="2" display="flex">
{!reply.isOpen && (
<Button leftIcon={<ReplyIcon />} variant="ghost" size="sm" onClick={reply.onOpen}>
reply
</Button>
)}
<NoteReactions event={comment} size="sm" variant="ghost" />
{replies && replies.length > 0 && (
<IconButton
ms="auto"
icon={expand.isOpen ? <ChevronUpIcon boxSize={5} /> : <ChevronDownIcon boxSize={5} />}
aria-label="Expand"
size="sm"
variant="ghost"
onClick={expand.onToggle}
/>
)}
</CardFooter>
</Card>
{reply.isOpen && <ArticleCommentForm event={comment} onCancel={reply.onClose} onSubmitted={reply.onClose} />}
{replies && replies.length > 2 && expand.isOpen && !all.isOpen && (
<Button w="full" variant="link" p="2" onClick={all.onOpen}>
Show more replies ({replies.length - 2})
</Button>
)}
{replies && replies.length > 0 && expand.isOpen && (
<Flex pl="4" direction="column" gap="2" borderLeftWidth={1} position="relative">
{(replies.length > 2 && !all.isOpen ? replies.slice(0, 2) : replies).map((reply) => (
<Comment key={comment.id} comment={reply} />
))}
</Flex>
)}
</>
);
}
export function ArticleComments({ article }: { article: NostrEvent }) {
const readRelays = useReadRelays();
const { loader } = useTimelineLoader(`${getEventUID(article)}-comments`, readRelays, {
kinds: [COMMENT_KIND],
"#A": [getEventUID(article)],
});
const comments = useStoreQuery(CommentsQuery, [article]);
const callback = useTimelineCurserIntersectionCallback(loader);
return (
<IntersectionObserverProvider callback={callback}>
{comments?.map((comment) => <Comment key={comment.id} comment={comment} />)}
</IntersectionObserverProvider>
);
}

View File

@ -31,7 +31,7 @@ import UserAvatar from "../../../../components/user/user-avatar";
import UserLink from "../../../../components/user/user-link";
import UserDnsIdentity from "../../../../components/user/user-dns-identity";
import DebugEventButton from "../../../../components/debug-modal/debug-event-button";
import NoteZapButton from "../../../../components/note/note-zap-button";
import EventZapButton from "../../../../components/zap/event-zap-button";
function NextPageButton({ chain, pointer }: { pointer: AddressPointer; chain: ChainedDVMJob[] }) {
const publish = usePublishEvent();

View File

@ -18,7 +18,7 @@ import UserLink from "../../../components/user/user-link";
import { NostrEvent } from "../../../types/nostr-event";
import EmojiPackFavoriteButton from "./emoji-pack-favorite-button";
import EmojiPackMenu from "./emoji-pack-menu";
import NoteZapButton from "../../../components/note/note-zap-button";
import EventZapButton from "../../../components/zap/event-zap-button";
import HoverLinkOverlay from "../../../components/hover-link-overlay";
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
import useShareableEventAddress from "../../../hooks/use-shareable-event-address";
@ -53,7 +53,7 @@ export default function EmojiPackCard({ pack, ...props }: Omit<CardProps, "child
</CardBody>
<CardFooter p="2" display="flex" pt="0">
<ButtonGroup size="sm" variant="ghost">
<NoteZapButton event={pack} />
<EventZapButton event={pack} />
<EmojiPackFavoriteButton pack={pack} />
</ButtonGroup>
<ButtonGroup size="sm" ml="auto" variant="ghost">

View File

@ -34,7 +34,7 @@ import UserAvatarLink from "../../components/user/user-avatar-link";
import Timestamp from "../../components/timestamp";
import useParamsAddressPointer from "../../hooks/use-params-address-pointer";
import { usePublishEvent } from "../../providers/global/publish-provider";
import NoteZapButton from "../../components/note/note-zap-button";
import EventZapButton from "../../components/zap/event-zap-button";
import QuoteEventButton from "../../components/note/quote-event-button";
function AddEmojiForm({ onAdd }: { onAdd: (values: { name: string; url: string }) => void }) {
@ -175,7 +175,7 @@ function EmojiPackPage({ pack }: { pack: NostrEvent }) {
</Text>
<ButtonGroup variant="ghost">
<NoteZapButton event={pack} />
<EventZapButton event={pack} />
<QuoteEventButton event={pack} />
<EmojiPackFavoriteButton pack={pack} />
</ButtonGroup>

View File

@ -16,7 +16,7 @@ import MimeTypePicker from "./mime-type-picker";
import TimelineActionAndStatus from "../../components/timeline/timeline-action-and-status";
import VerticalPageLayout from "../../components/vertical-page-layout";
import Timestamp from "../../components/timestamp";
import NoteZapButton from "../../components/note/note-zap-button";
import EventZapButton from "../../components/zap/event-zap-button";
import IntersectionObserverProvider from "../../providers/local/intersection-observer";
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
import { useReadRelays } from "../../hooks/use-client-relays";
@ -65,7 +65,7 @@ function ImageFile({ event }: { event: NostrEvent }) {
<UserLink pubkey={event.pubkey} fontWeight="bold" isTruncated />
<Timestamp timestamp={event.created_at} />
<Spacer />
<NoteZapButton event={event} size="sm" colorScheme="yellow" variant="outline" />
<EventZapButton event={event} size="sm" colorScheme="yellow" variant="outline" />
</Flex>
</Flex>
);

View File

@ -32,7 +32,7 @@ import ListMenu from "./list-menu";
import { NotesIcon } from "../../../components/icons";
import User01 from "../../../components/icons/user-01";
import HoverLinkOverlay from "../../../components/hover-link-overlay";
import NoteZapButton from "../../../components/note/note-zap-button";
import EventZapButton from "../../../components/zap/event-zap-button";
import Link01 from "../../../components/icons/link-01";
import File02 from "../../../components/icons/file-02";
import SimpleLikeButton from "../../../components/event-reactions/simple-like-button";
@ -113,7 +113,7 @@ function ListCardRender({
<ListCardContent list={list} />
</CardBody>
<CardFooter p="2">
{!isSpecialList && <NoteZapButton event={list} size="sm" variant="ghost" />}
{!isSpecialList && <EventZapButton event={list} size="sm" variant="ghost" />}
{!isSpecialList && <SimpleLikeButton event={list} variant="ghost" size="sm" />}
<ButtonGroup size="sm" variant="ghost" ml="auto">
<ListFavoriteButton list={list} />

View File

@ -6,7 +6,7 @@ import UserAvatar from "../../../../components/user/user-avatar";
import UserLink from "../../../../components/user/user-link";
import { TrustProvider } from "../../../../providers/local/trust-provider";
import ChatMessageContent from "./chat-message-content";
import NoteZapButton from "../../../../components/note/note-zap-button";
import EventZapButton from "../../../../components/zap/event-zap-button";
import useEventIntersectionRef from "../../../../hooks/use-event-intersection-ref";
import { getStreamHost } from "../../../../helpers/nostr/stream";
@ -23,7 +23,7 @@ function ChatMessage({ event, stream }: { event: NostrEvent; stream: NostrEvent
<UserLink pubkey={event.pubkey} />
{": "}
</Text>
<NoteZapButton
<EventZapButton
display="inline-block"
event={event}
size="xs"

View File

@ -20,7 +20,7 @@ import useThreadColorLevelProps from "../../../hooks/use-thread-color-level-prop
import POWIcon from "../../../components/pow/pow-icon";
import ShareButton from "../../../components/note/timeline-note/components/share-button";
import QuoteEventButton from "../../../components/note/quote-event-button";
import NoteZapButton from "../../../components/note/note-zap-button";
import EventZapButton from "../../../components/zap/event-zap-button";
import NoteProxyLink from "../../../components/note/timeline-note/components/note-proxy-link";
import BookmarkEventButton from "../../../components/note/bookmark-event";
import NoteMenu from "../../../components/note/note-menu";
@ -116,7 +116,7 @@ function ThreadPost({ post, initShowReplies, focusId, level = -1 }: ThreadItemPr
<IconButton aria-label="Reply" title="Reply" onClick={replyForm.onToggle} icon={<ReplyIcon />} />
<ShareButton event={post.event} />
<QuoteEventButton event={post.event} />
<NoteZapButton event={post.event} />
<EventZapButton event={post.event} />
</ButtonGroup>
{!showReactionsOnNewLine && reactionButtons}
<Spacer />

View File

@ -9,7 +9,7 @@ import UserLink from "../../../components/user/user-link";
import Magnet from "../../../components/icons/magnet";
import { formatBytes } from "../../../helpers/number";
import TorrentMenu from "./torrent-menu";
import NoteZapButton from "../../../components/note/note-zap-button";
import EventZapButton from "../../../components/zap/event-zap-button";
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
import useShareableEventAddress from "../../../hooks/use-shareable-event-address";
@ -70,7 +70,7 @@ function TorrentTableRow({ torrent }: { torrent: NostrEvent }) {
</Td>
<Td isNumeric>
<ButtonGroup variant="ghost" size="xs">
<NoteZapButton event={torrent} />
<EventZapButton event={torrent} />
<IconButton as={Link} icon={<Magnet />} aria-label="Magnet URI" isExternal href={magnetLink} />
<TorrentMenu torrent={torrent} aria-label="More Options" ml="auto" />
</ButtonGroup>

View File

@ -34,7 +34,7 @@ import ReplyForm from "../../thread/components/reply-form";
import useThreadColorLevelProps from "../../../hooks/use-thread-color-level-props";
import TorrentCommentMenu from "./torrent-comment-menu";
import NoteReactions from "../../../components/note/timeline-note/components/note-reactions";
import NoteZapButton from "../../../components/note/note-zap-button";
import EventZapButton from "../../../components/zap/event-zap-button";
import { TextNoteContents } from "../../../components/note/timeline-note/text-note-contents";
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
@ -104,7 +104,7 @@ export const ThreadPost = memo(({ post, level = -1 }: { post: ThreadItem; level?
<Flex gap="2" alignItems="center">
<ButtonGroup variant="ghost" size="sm">
<IconButton aria-label="Reply" title="Reply" onClick={replyForm.onToggle} icon={<ReplyIcon />} />
<NoteZapButton event={post.event} />
<EventZapButton event={post.event} />
</ButtonGroup>
{!showReactionsOnNewLine && reactionButtons}
<Spacer />

View File

@ -41,7 +41,7 @@ import ReplyForm from "../thread/components/reply-form";
import { getThreadReferences } from "../../helpers/nostr/event";
import MessageTextCircle01 from "../../components/icons/message-text-circle-01";
import useParamsEventPointer from "../../hooks/use-params-event-pointer";
import NoteZapButton from "../../components/note/note-zap-button";
import EventZapButton from "../../components/zap/event-zap-button";
import QuoteEventButton from "../../components/note/quote-event-button";
import { TextNoteContents } from "../../components/note/timeline-note/text-note-contents";
@ -74,7 +74,7 @@ function TorrentDetailsPage({ torrent }: { torrent: NostrEvent }) {
))}
</Flex>
<ButtonGroup variant="ghost" size="sm">
<NoteZapButton event={torrent} />
<EventZapButton event={torrent} />
<QuoteEventButton event={torrent} />
<Button as={Link} leftIcon={<Magnet boxSize={5} />} href={getTorrentMagnetLink(torrent)} isExternal>
Download torrent

View File

@ -13,7 +13,7 @@ import TrackPlayer from "./track-player";
import UserDnsIdentity from "../../../components/user/user-dns-identity";
import TrackMenu from "./track-menu";
import QuoteEventButton from "../../../components/note/quote-event-button";
import NoteZapButton from "../../../components/note/note-zap-button";
import EventZapButton from "../../../components/zap/event-zap-button";
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
export default function TrackCard({ track, ...props }: { track: NostrEvent } & Omit<CardProps, "children">) {
@ -46,7 +46,7 @@ export default function TrackCard({ track, ...props }: { track: NostrEvent } & O
Comment
</Button>
<QuoteEventButton event={track} />
<NoteZapButton event={track} />
<EventZapButton event={track} />
</ButtonGroup>
<ButtonGroup size="sm" ml="auto">
<TrackDownloadButton track={track} />

View File

@ -26,7 +26,7 @@ import VideoCard from "./components/video-card";
import UserName from "../../components/user/user-name";
import { useBreakpointValue } from "../../providers/global/breakpoint-provider";
import SimpleBookmarkButton from "../../components/simple-bookmark-button";
import NoteZapButton from "../../components/note/note-zap-button";
import EventZapButton from "../../components/zap/event-zap-button";
import QuoteEventButton from "../../components/note/quote-event-button";
function VideoRecommendations({ video }: { video: NostrEvent }) {
@ -56,7 +56,7 @@ function VideoDetailsPage({ video }: { video: NostrEvent }) {
{title}
</Heading>
<ButtonGroup ml="auto" size="sm" variant="ghost">
<NoteZapButton event={video} />
<EventZapButton event={video} />
<SimpleLikeButton event={video} />
<SimpleDislikeButton event={video} />
</ButtonGroup>

View File

@ -29,7 +29,7 @@ import { WIKI_RELAYS } from "../../const";
import GitBranch01 from "../../components/icons/git-branch-01";
import { ExternalLinkIcon } from "../../components/icons";
import FileSearch01 from "../../components/icons/file-search-01";
import NoteZapButton from "../../components/note/note-zap-button";
import EventZapButton from "../../components/zap/event-zap-button";
import ZapBubbles from "../../components/note/timeline-note/components/zap-bubbles";
import QuoteEventButton from "../../components/note/quote-event-button";
import WikiPageMenu from "./components/wiki-page-menu";
@ -120,7 +120,7 @@ export function WikiPagePage({ page }: { page: NostrEvent }) {
<EventVoteButtons event={page} inline chevrons={false} />
<ButtonGroup size="sm">
<QuoteEventButton event={page} />
<NoteZapButton event={page} showEventPreview={false} />
<EventZapButton event={page} showEventPreview={false} />
<WikiPageMenu page={page} aria-label="Page Options" />
</ButtonGroup>
</Flex>