mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-10 12:49:29 +02:00
add show replies switch to home feed
This commit is contained in:
parent
409f219c54
commit
57e5229db3
@ -1,4 +1,4 @@
|
||||
import { Button, Card, CardBody, CardHeader, Spacer, useDisclosure } from "@chakra-ui/react";
|
||||
import { Button, Card, CardBody, CardHeader, CardProps, Spacer, useDisclosure } from "@chakra-ui/react";
|
||||
|
||||
import { NoteContents } from "../../note/note-contents";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
@ -13,13 +13,13 @@ import { NoteLink } from "../../note-link";
|
||||
import { ArrowDownSIcon, ArrowUpSIcon } from "../../icons";
|
||||
import Timestamp from "../../timestamp";
|
||||
|
||||
export default function EmbeddedNote({ event }: { event: NostrEvent }) {
|
||||
export default function EmbeddedNote({ event, ...props }: Omit<CardProps, "children"> & { event: NostrEvent }) {
|
||||
const { showSignatureVerification } = useSubject(appSettings);
|
||||
const expand = useDisclosure();
|
||||
|
||||
return (
|
||||
<TrustProvider event={event}>
|
||||
<Card variant="outline">
|
||||
<Card {...props}>
|
||||
<CardHeader padding="2" display="flex" gap="2" alignItems="center" flexWrap="wrap">
|
||||
<UserAvatarLink pubkey={event.pubkey} size="sm" />
|
||||
<UserLink pubkey={event.pubkey} fontWeight="bold" isTruncated fontSize="lg" />
|
||||
|
@ -1,4 +1,5 @@
|
||||
import type { DecodeResult } from "nostr-tools/lib/nip19";
|
||||
import { CardProps } from "@chakra-ui/react";
|
||||
|
||||
import EmbeddedNote from "./event-types/embedded-note";
|
||||
import useSingleEvent from "../../hooks/use-single-event";
|
||||
@ -24,26 +25,30 @@ export type EmbedProps = {
|
||||
goalProps?: EmbeddedGoalOptions;
|
||||
};
|
||||
|
||||
export function EmbedEvent({ event, goalProps }: { event: NostrEvent } & EmbedProps) {
|
||||
export function EmbedEvent({
|
||||
event,
|
||||
goalProps,
|
||||
...cardProps
|
||||
}: Omit<CardProps, "children"> & { event: NostrEvent } & EmbedProps) {
|
||||
switch (event.kind) {
|
||||
case Kind.Text:
|
||||
return <EmbeddedNote event={event} />;
|
||||
return <EmbeddedNote event={event} {...cardProps} />;
|
||||
case STREAM_KIND:
|
||||
return <EmbeddedStream event={event} />;
|
||||
return <EmbeddedStream event={event} {...cardProps} />;
|
||||
case GOAL_KIND:
|
||||
return <EmbeddedGoal goal={event} {...goalProps} />;
|
||||
return <EmbeddedGoal goal={event} {...cardProps} {...goalProps} />;
|
||||
case EMOJI_PACK_KIND:
|
||||
return <EmbeddedEmojiPack pack={event} />;
|
||||
return <EmbeddedEmojiPack pack={event} {...cardProps} />;
|
||||
case PEOPLE_LIST_KIND:
|
||||
case NOTE_LIST_KIND:
|
||||
return <EmbeddedList list={event} />;
|
||||
return <EmbeddedList list={event} {...cardProps} />;
|
||||
case Kind.Article:
|
||||
return <EmbeddedArticle article={event} />;
|
||||
return <EmbeddedArticle article={event} {...cardProps} />;
|
||||
case Kind.BadgeDefinition:
|
||||
return <EmbeddedBadge badge={event} />;
|
||||
return <EmbeddedBadge badge={event} {...cardProps} />;
|
||||
}
|
||||
|
||||
return <EmbeddedUnknown event={event} />;
|
||||
return <EmbeddedUnknown event={event} {...cardProps} />;
|
||||
}
|
||||
|
||||
export function EmbedEventPointer({ pointer, ...props }: { pointer: DecodeResult } & EmbedProps) {
|
||||
|
@ -39,12 +39,12 @@ import ReplyForm from "../../views/note/components/reply-form";
|
||||
import { getReferences } from "../../helpers/nostr/events";
|
||||
import Timestamp from "../timestamp";
|
||||
|
||||
export type NoteProps = {
|
||||
export type NoteProps = Omit<CardProps, "children"> & {
|
||||
event: NostrEvent;
|
||||
variant?: CardProps["variant"];
|
||||
showReplyButton?: boolean;
|
||||
};
|
||||
export const Note = React.memo(({ event, variant = "outline", showReplyButton }: NoteProps) => {
|
||||
export const Note = React.memo(({ event, variant = "outline", showReplyButton, ...props }: NoteProps) => {
|
||||
const account = useCurrentAccount();
|
||||
const { showReactions, showSignatureVerification } = useSubject(appSettings);
|
||||
const replyForm = useDisclosure();
|
||||
@ -63,7 +63,7 @@ export const Note = React.memo(({ event, variant = "outline", showReplyButton }:
|
||||
return (
|
||||
<TrustProvider event={event}>
|
||||
<ExpandProvider>
|
||||
<Card variant={variant} ref={ref} data-event-id={event.id}>
|
||||
<Card variant={variant} ref={ref} data-event-id={event.id} {...props}>
|
||||
<CardHeader padding="2">
|
||||
<Flex flex="1" gap="2" alignItems="center">
|
||||
<UserAvatarLink pubkey={event.pubkey} size={["xs", "sm"]} />
|
||||
|
@ -1,22 +1,25 @@
|
||||
import React from "react";
|
||||
import { Text } from "@chakra-ui/react";
|
||||
import { Kind } from "nostr-tools";
|
||||
|
||||
import useSubject from "../../../hooks/use-subject";
|
||||
import { TimelineLoader } from "../../../classes/timeline-loader";
|
||||
import RepostNote from "./repost-note";
|
||||
import { Note } from "../../note";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import { Text } from "@chakra-ui/react";
|
||||
import { Kind } from "nostr-tools";
|
||||
import { STREAM_KIND } from "../../../helpers/nostr/stream";
|
||||
import StreamNote from "./stream-note";
|
||||
import { ErrorBoundary } from "../../error-boundary";
|
||||
import RelayCard from "../../../views/relays/components/relay-card";
|
||||
import { safeRelayUrl } from "../../../helpers/url";
|
||||
import EmbeddedArticle from "../../embed-event/event-types/embedded-article";
|
||||
import { isReply } from "../../../helpers/nostr/events";
|
||||
import ReplyNote from "./reply-note";
|
||||
|
||||
const RenderEvent = React.memo(({ event }: { event: NostrEvent }) => {
|
||||
switch (event.kind) {
|
||||
case Kind.Text:
|
||||
return <Note event={event} showReplyButton />;
|
||||
return isReply(event) ? <ReplyNote event={event} /> : <Note event={event} showReplyButton />;
|
||||
case Kind.Repost:
|
||||
return <RepostNote event={event} />;
|
||||
case Kind.Article:
|
||||
|
@ -0,0 +1,33 @@
|
||||
import { memo, useRef } from "react";
|
||||
import { Flex, SkeletonText, Text } from "@chakra-ui/react";
|
||||
|
||||
import { getReferences } from "../../../helpers/nostr/events";
|
||||
import useSingleEvent from "../../../hooks/use-single-event";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import { EmbedEvent } from "../../embed-event";
|
||||
import { useRegisterIntersectionEntity } from "../../../providers/intersection-observer";
|
||||
import Note from "../../note";
|
||||
import { UserAvatar } from "../../user-avatar";
|
||||
import { UserLink } from "../../user-link";
|
||||
|
||||
function ReplyNote({ event }: { event: NostrEvent }) {
|
||||
const refs = getReferences(event);
|
||||
const { event: parent } = useSingleEvent(refs.replyId);
|
||||
|
||||
// if there is a parent intersection observer, register this card
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
useRegisterIntersectionEntity(ref, event.id);
|
||||
|
||||
return (
|
||||
<Flex gap="2" direction="column" ref={ref}>
|
||||
<Flex gap="2">
|
||||
<UserAvatar pubkey={event.pubkey} size="xs" alignItems="center" />
|
||||
<UserLink pubkey={event.pubkey} />
|
||||
<Text>Replied to:</Text>
|
||||
</Flex>
|
||||
{parent ? <EmbedEvent event={parent} ml="4" /> : <SkeletonText />}
|
||||
<Note event={event} />
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
export default memo(ReplyNote);
|
@ -1,13 +1,13 @@
|
||||
import { useCallback } from "react";
|
||||
import { Flex, FlexProps, SimpleGrid } from "@chakra-ui/react";
|
||||
import { Flex, FlexProps } from "@chakra-ui/react";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
|
||||
import IntersectionObserverProvider from "../../providers/intersection-observer";
|
||||
import GenericNoteTimeline from "./generic-note-timeline";
|
||||
import { LightboxProvider } from "../lightbox-provider";
|
||||
import MediaTimeline from "./media-timeline";
|
||||
import { TimelineLoader } from "../../classes/timeline-loader";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
import TimelineActionAndStatus from "./timeline-action-and-status";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
import { getMatchLink } from "../../helpers/regexp";
|
||||
import TimelineHealth from "./timeline-health";
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { Flex, Switch, useDisclosure } from "@chakra-ui/react";
|
||||
import { Kind } from "nostr-tools";
|
||||
|
||||
import { isReply } from "../../helpers/nostr/events";
|
||||
@ -15,12 +15,13 @@ import { NostrRequestFilter } from "../../types/nostr-query";
|
||||
|
||||
function HomePage() {
|
||||
const timelinePageEventFilter = useTimelinePageEventFilter();
|
||||
const showReplies = useDisclosure();
|
||||
const eventFilter = useCallback(
|
||||
(event: NostrEvent) => {
|
||||
if (isReply(event)) return false;
|
||||
if (!showReplies.isOpen && isReply(event)) return false;
|
||||
return timelinePageEventFilter(event);
|
||||
},
|
||||
[timelinePageEventFilter],
|
||||
[timelinePageEventFilter, showReplies.isOpen],
|
||||
);
|
||||
|
||||
const { relays } = useRelaySelectionContext();
|
||||
@ -38,8 +39,11 @@ function HomePage() {
|
||||
});
|
||||
|
||||
const header = (
|
||||
<Flex gap="2" wrap="wrap" px={["2", 0]}>
|
||||
<Flex gap="2" wrap="wrap" px={["2", 0]} alignItems="center">
|
||||
<PeopleListSelection />
|
||||
<Switch checked={showReplies.isOpen} onChange={showReplies.onToggle}>
|
||||
Show Replies
|
||||
</Switch>
|
||||
<RelaySelectionButton ml="auto" />
|
||||
<TimelineViewTypeButtons />
|
||||
</Flex>
|
||||
|
Loading…
x
Reference in New Issue
Block a user