mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-03-17 13:21:44 +01:00
add NIP-22 comments on articles
This commit is contained in:
parent
1b84b7fa9b
commit
fc2063bf75
5
.changeset/stale-eels-think.md
Normal file
5
.changeset/stale-eels-think.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"nostrudel": minor
|
||||
---
|
||||
|
||||
Add NIP-22 comments on articles
|
@ -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} />
|
||||
|
@ -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" />}
|
||||
</>
|
||||
|
@ -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} />
|
||||
|
@ -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)) ?? [];
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
100
src/views/articles/components/article-comment-form.tsx
Normal file
100
src/views/articles/components/article-comment-form.tsx
Normal 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>
|
||||
);
|
||||
}
|
110
src/views/articles/components/article-comments.tsx
Normal file
110
src/views/articles/components/article-comments.tsx
Normal 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>
|
||||
);
|
||||
}
|
@ -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();
|
||||
|
@ -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">
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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} />
|
||||
|
@ -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"
|
||||
|
@ -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 />
|
||||
|
@ -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>
|
||||
|
@ -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 />
|
||||
|
@ -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
|
||||
|
@ -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} />
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user