diff --git a/src/components/embed-event/event-types/embedded-community.tsx b/src/components/embed-event/event-types/embedded-community.tsx index 1d267aae3..39f8e955d 100644 --- a/src/components/embed-event/event-types/embedded-community.tsx +++ b/src/components/embed-event/event-types/embedded-community.tsx @@ -17,6 +17,7 @@ export default function EmbeddedCommunity({ & { - + {/* - + */} by diff --git a/src/views/communities/index.tsx b/src/views/communities/index.tsx index 76ea6afec..b6f5de382 100644 --- a/src/views/communities/index.tsx +++ b/src/views/communities/index.tsx @@ -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 {nip19.naddrEncode(pointer)}; + return ; +} function CommunitiesHomePage() { const account = useCurrentAccount()!; @@ -22,8 +32,8 @@ function CommunitiesHomePage() { {communities.length > 0 ? ( {communities.map((pointer) => ( - - + + ))} diff --git a/src/views/community/components/post-vote-buttions.tsx b/src/views/community/components/post-vote-buttions.tsx new file mode 100644 index 000000000..aac28e42c --- /dev/null +++ b/src/views/community/components/post-vote-buttions.tsx @@ -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 ( + + } + size="sm" + variant={myVote?.content === "+" ? "solid" : "ghost"} + isLoading={loading} + onClick={() => addVote("+")} + isDisabled={!account || !!myVote} + colorScheme={myVote ? "primary" : "gray"} + /> + {voteReactions.length > 0 && {vote}} + } + size="sm" + variant={myVote?.content === "-" ? "solid" : "ghost"} + isLoading={loading} + onClick={() => addVote("-")} + isDisabled={!account || !!myVote} + /> + + ); +} diff --git a/src/views/community/views/newest.tsx b/src/views/community/views/newest.tsx index 2f97398db..0bd45b3bb 100644 --- a/src/views/community/views/newest.tsx +++ b/src/views/community/views/newest.tsx @@ -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 ( - - } - size="sm" - variant={myVote?.content === "+" ? "solid" : "ghost"} - isLoading={loading} - onClick={() => addVote("+")} - isDisabled={!account || !!myVote} - colorScheme={myVote ? "primary" : "gray"} - /> - {voteReactions.length > 0 && {vote}} - } - size="sm" - variant={myVote?.content === "-" ? "solid" : "ghost"} - isLoading={loading} - onClick={() => addVote("-")} - isDisabled={!account || !!myVote} - /> - - ); -} +import PostVoteButtons from "../components/post-vote-buttions"; function ApprovedEvent({ approval, community }: { approval: NostrEvent; community: NostrEvent }) { const ref = useRef(null); @@ -116,7 +38,7 @@ function ApprovedEvent({ approval, community }: { approval: NostrEvent; communit if (!event) return; return ( - + );