mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-09-27 20:17:05 +02:00
cleanup
This commit is contained in:
@@ -17,6 +17,7 @@ export default function EmbeddedCommunity({
|
||||
<Card
|
||||
as={LinkBox}
|
||||
variant="outline"
|
||||
maxW="lg"
|
||||
gap="2"
|
||||
overflow="hidden"
|
||||
borderRadius="xl"
|
||||
|
@@ -53,9 +53,9 @@ function CommunityCard({ community, ...props }: Omit<CardProps, "children"> & {
|
||||
</LinkOverlay>
|
||||
</Heading>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
{/* <CardBody>
|
||||
<CommunityDescription community={community} maxLength={128} flex={1} />
|
||||
</CardBody>
|
||||
</CardBody> */}
|
||||
<CardFooter display="flex" alignItems="center" gap="2" pt="0">
|
||||
<UserAvatarLink pubkey={community.pubkey} size="sm" />
|
||||
<Text>by</Text>
|
||||
|
@@ -1,12 +1,22 @@
|
||||
import { Button, Center, Flex, Heading, Link, SimpleGrid, Text } from "@chakra-ui/react";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import { Navigate } from "react-router-dom";
|
||||
import { nip19 } from "nostr-tools";
|
||||
|
||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import { ErrorBoundary } from "../../components/error-boundary";
|
||||
import useSubscribedCommunitiesList from "../../hooks/use-subscribed-communities-list";
|
||||
import { useCurrentAccount } from "../../hooks/use-current-account";
|
||||
import { Navigate } from "react-router-dom";
|
||||
import { EmbedEventPointer } from "../../components/embed-event";
|
||||
import { AddressPointer } from "nostr-tools/lib/nip19";
|
||||
import useReplaceableEvent from "../../hooks/use-replaceable-event";
|
||||
import CommunityCard from "./components/community-card";
|
||||
|
||||
function LoadCommunityCard({ pointer }: { pointer: AddressPointer }) {
|
||||
const community = useReplaceableEvent(pointer);
|
||||
if (!community) return <span>{nip19.naddrEncode(pointer)}</span>;
|
||||
return <CommunityCard community={community} />;
|
||||
}
|
||||
|
||||
function CommunitiesHomePage() {
|
||||
const account = useCurrentAccount()!;
|
||||
@@ -22,8 +32,8 @@ function CommunitiesHomePage() {
|
||||
{communities.length > 0 ? (
|
||||
<SimpleGrid spacing="2" columns={{ base: 1, lg: 2 }}>
|
||||
{communities.map((pointer) => (
|
||||
<ErrorBoundary>
|
||||
<EmbedEventPointer pointer={{ type: "naddr", data: pointer }} />
|
||||
<ErrorBoundary key={pointer.kind + pointer.pubkey + pointer.identifier}>
|
||||
<LoadCommunityCard pointer={pointer} />
|
||||
</ErrorBoundary>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
|
83
src/views/community/components/post-vote-buttions.tsx
Normal file
83
src/views/community/components/post-vote-buttions.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { Card, IconButton, Text, useToast } from "@chakra-ui/react";
|
||||
|
||||
import { useCurrentAccount } from "../../../hooks/use-current-account";
|
||||
import useEventReactions from "../../../hooks/use-event-reactions";
|
||||
import { useSigningContext } from "../../../providers/signing-provider";
|
||||
import { draftEventReaction } from "../../../helpers/nostr/reactions";
|
||||
import clientRelaysService from "../../../services/client-relays";
|
||||
import { getCommunityRelays } from "../../../helpers/nostr/communities";
|
||||
import { unique } from "../../../helpers/array";
|
||||
import eventReactionsService from "../../../services/event-reactions";
|
||||
import NostrPublishAction from "../../../classes/nostr-publish-action";
|
||||
import { ChevronDownIcon, ChevronUpIcon } from "../../../components/icons";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
|
||||
export default function PostVoteButtons({ event, community }: { event: NostrEvent; community: NostrEvent }) {
|
||||
const account = useCurrentAccount();
|
||||
const reactions = useEventReactions(event.id);
|
||||
const toast = useToast();
|
||||
|
||||
const voteReactions = useMemo(() => {
|
||||
return reactions?.filter((r) => r.content === "+" || r.content === "-") ?? [];
|
||||
}, [reactions]);
|
||||
const vote = useMemo(() => {
|
||||
return voteReactions.reduce((t, r) => {
|
||||
if (r.content === "+") return t + 1;
|
||||
else if (r.content === "-") return t - 1;
|
||||
return t;
|
||||
}, 0);
|
||||
}, [voteReactions]);
|
||||
|
||||
const myVote = reactions?.find((e) => e.pubkey === account?.pubkey);
|
||||
|
||||
const { requestSignature } = useSigningContext();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const addVote = useCallback(
|
||||
async (vote: string) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const draft = draftEventReaction(event, vote);
|
||||
|
||||
const signed = await requestSignature(draft);
|
||||
if (signed) {
|
||||
const writeRelays = clientRelaysService.getWriteUrls();
|
||||
const communityRelays = getCommunityRelays(community);
|
||||
new NostrPublishAction("Reaction", unique([...writeRelays, ...communityRelays]), signed);
|
||||
eventReactionsService.handleEvent(signed);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof Error) toast({ description: e.message, status: "error" });
|
||||
}
|
||||
setLoading(false);
|
||||
},
|
||||
[event, community, requestSignature],
|
||||
);
|
||||
|
||||
return (
|
||||
<Card direction="column" alignItems="center" borderRadius="lg">
|
||||
<IconButton
|
||||
aria-label="up vote"
|
||||
title="up vote"
|
||||
icon={<ChevronUpIcon boxSize={6} />}
|
||||
size="sm"
|
||||
variant={myVote?.content === "+" ? "solid" : "ghost"}
|
||||
isLoading={loading}
|
||||
onClick={() => addVote("+")}
|
||||
isDisabled={!account || !!myVote}
|
||||
colorScheme={myVote ? "primary" : "gray"}
|
||||
/>
|
||||
{voteReactions.length > 0 && <Text my="1">{vote}</Text>}
|
||||
<IconButton
|
||||
aria-label="down vote"
|
||||
title="down vote"
|
||||
icon={<ChevronDownIcon boxSize={6} />}
|
||||
size="sm"
|
||||
variant={myVote?.content === "-" ? "solid" : "ghost"}
|
||||
isLoading={loading}
|
||||
onClick={() => addVote("-")}
|
||||
isDisabled={!account || !!myVote}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
import { useCallback, useMemo, useRef, useState } from "react";
|
||||
import { Box, Card, Flex, IconButton, Text, useToast } from "@chakra-ui/react";
|
||||
import { useRef } from "react";
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { useOutletContext } from "react-router-dom";
|
||||
|
||||
import { unique } from "../../../helpers/array";
|
||||
@@ -20,85 +20,7 @@ import useSingleEvent from "../../../hooks/use-single-event";
|
||||
import { useAdditionalRelayContext } from "../../../providers/additional-relay-context";
|
||||
import IntersectionObserverProvider, { useRegisterIntersectionEntity } from "../../../providers/intersection-observer";
|
||||
import TimelineActionAndStatus from "../../../components/timeline-page/timeline-action-and-status";
|
||||
import { ChevronUpIcon } from "../../../components/icons";
|
||||
import { ChevronDownIcon } from "@chakra-ui/icons";
|
||||
import useEventReactions from "../../../hooks/use-event-reactions";
|
||||
import { useMeasure, useStartTyping } from "react-use";
|
||||
import { draftEventReaction } from "../../../helpers/nostr/reactions";
|
||||
import eventReactionsService from "../../../services/event-reactions";
|
||||
import NostrPublishAction from "../../../classes/nostr-publish-action";
|
||||
import clientRelaysService from "../../../services/client-relays";
|
||||
import { useSigningContext } from "../../../providers/signing-provider";
|
||||
import { useCurrentAccount } from "../../../hooks/use-current-account";
|
||||
|
||||
function ApprovalVoteButtons({ event, community }: { event: NostrEvent; community: NostrEvent }) {
|
||||
const account = useCurrentAccount();
|
||||
const reactions = useEventReactions(event.id);
|
||||
const toast = useToast();
|
||||
|
||||
const voteReactions = useMemo(() => {
|
||||
return reactions?.filter((r) => r.content === "+" || r.content === "-") ?? [];
|
||||
}, [reactions]);
|
||||
const vote = useMemo(() => {
|
||||
return voteReactions.reduce((t, r) => {
|
||||
if (r.content === "+") return t + 1;
|
||||
else if (r.content === "-") return t - 1;
|
||||
return t;
|
||||
}, 0);
|
||||
}, [voteReactions]);
|
||||
|
||||
const myVote = reactions?.find((e) => e.pubkey === account?.pubkey);
|
||||
|
||||
const { requestSignature } = useSigningContext();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const addVote = useCallback(
|
||||
async (vote: string) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const draft = draftEventReaction(event, vote);
|
||||
|
||||
const signed = await requestSignature(draft);
|
||||
if (signed) {
|
||||
const writeRelays = clientRelaysService.getWriteUrls();
|
||||
const communityRelays = getCommunityRelays(community);
|
||||
new NostrPublishAction("Reaction", unique([...writeRelays, ...communityRelays]), signed);
|
||||
eventReactionsService.handleEvent(signed);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof Error) toast({ description: e.message, status: "error" });
|
||||
}
|
||||
setLoading(false);
|
||||
},
|
||||
[event, community, requestSignature],
|
||||
);
|
||||
|
||||
return (
|
||||
<Card direction="column" alignItems="center" borderRadius="lg">
|
||||
<IconButton
|
||||
aria-label="up vote"
|
||||
title="up vote"
|
||||
icon={<ChevronUpIcon boxSize={6} />}
|
||||
size="sm"
|
||||
variant={myVote?.content === "+" ? "solid" : "ghost"}
|
||||
isLoading={loading}
|
||||
onClick={() => addVote("+")}
|
||||
isDisabled={!account || !!myVote}
|
||||
colorScheme={myVote ? "primary" : "gray"}
|
||||
/>
|
||||
{voteReactions.length > 0 && <Text my="1">{vote}</Text>}
|
||||
<IconButton
|
||||
aria-label="down vote"
|
||||
title="down vote"
|
||||
icon={<ChevronDownIcon boxSize={6} />}
|
||||
size="sm"
|
||||
variant={myVote?.content === "-" ? "solid" : "ghost"}
|
||||
isLoading={loading}
|
||||
onClick={() => addVote("-")}
|
||||
isDisabled={!account || !!myVote}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
import PostVoteButtons from "../components/post-vote-buttions";
|
||||
|
||||
function ApprovedEvent({ approval, community }: { approval: NostrEvent; community: NostrEvent }) {
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
@@ -116,7 +38,7 @@ function ApprovedEvent({ approval, community }: { approval: NostrEvent; communit
|
||||
if (!event) return;
|
||||
return (
|
||||
<Flex ref={ref} gap="2" alignItems="flex-start" overflow="hidden">
|
||||
<ApprovalVoteButtons event={event} community={community} />
|
||||
<PostVoteButtons event={event} community={community} />
|
||||
<EmbedEvent event={event} flex={1} />
|
||||
</Flex>
|
||||
);
|
||||
|
Reference in New Issue
Block a user