add reply button to note feed

This commit is contained in:
hzrd149 2023-09-05 14:14:56 -05:00
parent 6dd619613a
commit 8fd08ed3ea
6 changed files with 41 additions and 18 deletions

View File

@ -0,0 +1,5 @@
---
"nostrudel": minor
---
Add reply button to note feed

View File

@ -12,6 +12,7 @@ import {
IconButton,
Link,
useBreakpointValue,
useDisclosure,
} from "@chakra-ui/react";
import { NostrEvent } from "../../types/nostr-event";
import { UserAvatarLink } from "../user-avatar-link";
@ -27,23 +28,26 @@ import appSettings from "../../services/settings/app-settings";
import EventVerificationIcon from "../event-verification-icon";
import { RepostButton } from "./components/repost-button";
import { QuoteRepostButton } from "./components/quote-repost-button";
import { ExternalLinkIcon } from "../icons";
import { ExternalLinkIcon, ReplyIcon } from "../icons";
import NoteContentWithWarning from "./note-content-with-warning";
import { TrustProvider } from "../../providers/trust";
import { NoteLink } from "../note-link";
import { useRegisterIntersectionEntity } from "../../providers/intersection-observer";
import BookmarkButton from "./components/bookmark-button";
import EventReactionButtons from "../event-reactions";
import { useCurrentAccount } from "../../hooks/use-current-account";
import NoteReactions from "./components/note-reactions";
import ReplyForm from "../../views/note/components/reply-form";
import { getReferences } from "../../helpers/nostr/events";
export type NoteProps = {
event: NostrEvent;
variant?: CardProps["variant"];
showReplyButton?: boolean;
};
export const Note = React.memo(({ event, variant = "outline" }: NoteProps) => {
export const Note = React.memo(({ event, variant = "outline", showReplyButton }: NoteProps) => {
const account = useCurrentAccount();
const { showReactions, showSignatureVerification } = useSubject(appSettings);
const replyForm = useDisclosure();
// if there is a parent intersection observer, register this card
const ref = useRef<HTMLDivElement | null>(null);
@ -79,6 +83,9 @@ export const Note = React.memo(({ event, variant = "outline" }: NoteProps) => {
{showReactionsOnNewLine && reactionButtons}
<Flex gap="2" w="full" alignItems="center">
<ButtonGroup size="xs" variant="ghost" isDisabled={account?.readonly ?? true}>
{showReplyButton && (
<IconButton icon={<ReplyIcon />} aria-label="Reply" title="Reply" onClick={replyForm.onOpen} />
)}
<RepostButton event={event} />
<QuoteRepostButton event={event} />
<NoteZapButton event={event} />
@ -103,6 +110,15 @@ export const Note = React.memo(({ event, variant = "outline" }: NoteProps) => {
</CardFooter>
</Card>
</ExpandProvider>
{replyForm.isOpen && (
<ReplyForm
item={{ event, replies: [], refs: getReferences(event) }}
onCancel={replyForm.onClose}
onSubmitted={replyForm.onClose}
/>
)}
</TrustProvider>
);
});
export default Note;

View File

@ -15,7 +15,7 @@ import { safeRelayUrl } from "../../../helpers/url";
const RenderEvent = React.memo(({ event }: { event: NostrEvent }) => {
switch (event.kind) {
case Kind.Text:
return <Note event={event} />;
return <Note event={event} showReplyButton />;
case Kind.Repost:
return <RepostNote event={event} />;
case STREAM_KIND:

View File

@ -63,7 +63,7 @@ export default function RepostNote({ event }: { event: NostrEvent }) {
</Text>
<NoteMenu event={event} size="sm" variant="link" aria-label="note options" />
</Flex>
{loading ? <SkeletonText /> : note ? <Note event={note} /> : <ErrorFallback error={error} />}
{loading ? <SkeletonText /> : note ? <Note event={note} showReplyButton /> : <ErrorFallback error={error} />}
</Flex>
</TrustProvider>
);

View File

@ -2,7 +2,7 @@ import { Flex, Spinner } from "@chakra-ui/react";
import { nip19 } from "nostr-tools";
import { useParams } from "react-router-dom";
import { Note } from "../../components/note";
import Note from "../../components/note";
import { isHexKey } from "../../helpers/nip19";
import { useThreadLoader } from "../../hooks/use-thread-loader";
import { ThreadPost } from "./components/thread-post";

View File

@ -1,5 +1,5 @@
import { useMemo } from "react";
import { Box, Button, useToast } from "@chakra-ui/react";
import { Box, Button, Flex, useToast } from "@chakra-ui/react";
import { useForm } from "react-hook-form";
import { ParsedStream, buildChatMessage } from "../../../../helpers/nostr/stream";
@ -45,17 +45,19 @@ export default function ChatMessageForm({ stream }: { stream: ParsedStream }) {
return (
<>
<Box as="form" borderRadius="md" flexShrink={0} display="flex" gap="2" px="2" pb="2" onSubmit={sendMessage}>
<MagicInput
placeholder="Message"
autoComplete="off"
isRequired
value={getValues().content}
onChange={(e) => setValue("content", e.target.value)}
/>
<Button colorScheme="brand" type="submit" isLoading={formState.isSubmitting}>
Send
</Button>
<Box borderRadius="md" flexShrink={0} display="flex" gap="2" px="2" pb="2">
<Flex as="form" onSubmit={sendMessage} gap="2" flex={1}>
<MagicInput
placeholder="Message"
autoComplete="off"
isRequired
value={getValues().content}
onChange={(e) => setValue("content", e.target.value)}
/>
<Button colorScheme="brand" type="submit" isLoading={formState.isSubmitting}>
Send
</Button>
</Flex>
<StreamZapButton stream={stream} onZap={reset} initComment={getValues().content} />
</Box>
</>