mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-10-05 17:55:01 +02:00
allow user to edit community relays
This commit is contained in:
@@ -19,6 +19,9 @@ export function getCommunityMods(community: NostrEvent) {
|
|||||||
export function getCommunityRelays(community: NostrEvent) {
|
export function getCommunityRelays(community: NostrEvent) {
|
||||||
return community.tags.filter((t) => t[0] === "relay" && t[1]).map((t) => t[1]) as string[];
|
return community.tags.filter((t) => t[0] === "relay" && t[1]).map((t) => t[1]) as string[];
|
||||||
}
|
}
|
||||||
|
export function getCommunityLinks(community: NostrEvent) {
|
||||||
|
return community.tags.filter((t) => t[0] === "r" && t[1]).map((t) => t[1]) as string[];
|
||||||
|
}
|
||||||
|
|
||||||
export function getCommunityImage(community: NostrEvent) {
|
export function getCommunityImage(community: NostrEvent) {
|
||||||
return community.tags.find((t) => t[0] === "image")?.[1];
|
return community.tags.find((t) => t[0] === "image")?.[1];
|
||||||
|
@@ -9,6 +9,7 @@ import {
|
|||||||
IconButton,
|
IconButton,
|
||||||
Image,
|
Image,
|
||||||
Input,
|
Input,
|
||||||
|
Link,
|
||||||
Modal,
|
Modal,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
ModalCloseButton,
|
ModalCloseButton,
|
||||||
@@ -20,6 +21,7 @@ import {
|
|||||||
Radio,
|
Radio,
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
Stack,
|
Stack,
|
||||||
|
Text,
|
||||||
Textarea,
|
Textarea,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
@@ -27,12 +29,15 @@ import { SubmitHandler, useForm } from "react-hook-form";
|
|||||||
import { useCurrentAccount } from "../../../hooks/use-current-account";
|
import { useCurrentAccount } from "../../../hooks/use-current-account";
|
||||||
import UserAvatar from "../../../components/user-avatar";
|
import UserAvatar from "../../../components/user-avatar";
|
||||||
import { UserLink } from "../../../components/user-link";
|
import { UserLink } from "../../../components/user-link";
|
||||||
import { UploadImageIcon } from "../../../components/icons";
|
import { TrashIcon, UploadImageIcon } from "../../../components/icons";
|
||||||
import Upload01 from "../../../components/icons/upload-01";
|
import Upload01 from "../../../components/icons/upload-01";
|
||||||
import Upload02 from "../../../components/icons/upload-02";
|
import Upload02 from "../../../components/icons/upload-02";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { nostrBuildUploadImage } from "../../../helpers/nostr-build";
|
import { nostrBuildUploadImage } from "../../../helpers/nostr-build";
|
||||||
import { useSigningContext } from "../../../providers/signing-provider";
|
import { useSigningContext } from "../../../providers/signing-provider";
|
||||||
|
import { RelayUrlInput } from "../../../components/relay-url-input";
|
||||||
|
import { normalizeRelayUrl, safeRelayUrl } from "../../../helpers/url";
|
||||||
|
import { RelayFavicon } from "../../../components/relay-favicon";
|
||||||
|
|
||||||
export type FormValues = {
|
export type FormValues = {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -41,6 +46,7 @@ export type FormValues = {
|
|||||||
rules: string;
|
rules: string;
|
||||||
mods: string[];
|
mods: string[];
|
||||||
relays: string[];
|
relays: string[];
|
||||||
|
links: string[];
|
||||||
ranking: string;
|
ranking: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -76,6 +82,7 @@ export default function CommunityCreateModal({
|
|||||||
rules: "",
|
rules: "",
|
||||||
mods: account ? [account.pubkey] : [],
|
mods: account ? [account.pubkey] : [],
|
||||||
relays: [],
|
relays: [],
|
||||||
|
links: [],
|
||||||
ranking: "votes",
|
ranking: "votes",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -83,6 +90,8 @@ export default function CommunityCreateModal({
|
|||||||
watch("mods");
|
watch("mods");
|
||||||
watch("ranking");
|
watch("ranking");
|
||||||
watch("banner");
|
watch("banner");
|
||||||
|
watch("links");
|
||||||
|
watch("relays");
|
||||||
|
|
||||||
const [uploading, setUploading] = useState(false);
|
const [uploading, setUploading] = useState(false);
|
||||||
const uploadFile = useCallback(
|
const uploadFile = useCallback(
|
||||||
@@ -104,6 +113,22 @@ export default function CommunityCreateModal({
|
|||||||
[setValue, getValues, requestSignature, toast],
|
[setValue, getValues, requestSignature, toast],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [relayInput, setRelayInput] = useState("");
|
||||||
|
const addRelay = () => {
|
||||||
|
if (!relayInput) return;
|
||||||
|
const url = safeRelayUrl(relayInput);
|
||||||
|
if (url) {
|
||||||
|
setValue("relays", getValues("relays").concat(url));
|
||||||
|
}
|
||||||
|
setRelayInput("");
|
||||||
|
};
|
||||||
|
const removeRelay = (url: string) => {
|
||||||
|
setValue(
|
||||||
|
"relays",
|
||||||
|
getValues("relays").filter((r) => r !== url),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onClose={onClose} size="2xl" {...props}>
|
<Modal isOpen={isOpen} onClose={onClose} size="2xl" {...props}>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
@@ -213,6 +238,55 @@ export default function CommunityCreateModal({
|
|||||||
<FormHelperText>The default by posts are ranked when viewing the community</FormHelperText>
|
<FormHelperText>The default by posts are ranked when viewing the community</FormHelperText>
|
||||||
{errors.rules?.message && <FormErrorMessage>{errors.rules?.message}</FormErrorMessage>}
|
{errors.rules?.message && <FormErrorMessage>{errors.rules?.message}</FormErrorMessage>}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
|
<FormControl isInvalid={!!errors.mods}>
|
||||||
|
<FormLabel>Relays</FormLabel>
|
||||||
|
<FormHelperText>A Short list of recommended relays for the community</FormHelperText>
|
||||||
|
<Flex direction="column" gap="2" py="2">
|
||||||
|
{getValues().relays.map((url) => (
|
||||||
|
<Flex key={url} alignItems="center" gap="2">
|
||||||
|
<RelayFavicon relay={url} size="sm" />
|
||||||
|
<Text fontWeight="bold" isTruncated>
|
||||||
|
{url}
|
||||||
|
</Text>
|
||||||
|
<IconButton
|
||||||
|
icon={<TrashIcon />}
|
||||||
|
aria-label={`Remove ${url}`}
|
||||||
|
title={`Remove ${url}`}
|
||||||
|
onClick={() => removeRelay(url)}
|
||||||
|
size="sm"
|
||||||
|
colorScheme="red"
|
||||||
|
variant="ghost"
|
||||||
|
ml="auto"
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
{errors.rules?.message && <FormErrorMessage>{errors.rules?.message}</FormErrorMessage>}
|
||||||
|
<Flex gap="2">
|
||||||
|
<RelayUrlInput value={relayInput} onChange={(v) => setRelayInput(v)} />
|
||||||
|
<Button isDisabled={!relayInput} onClick={addRelay}>
|
||||||
|
Add
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
{/* <FormControl isInvalid={!!errors.mods}>
|
||||||
|
<FormLabel>Links</FormLabel>
|
||||||
|
<Flex direction="column">
|
||||||
|
{getValues().links.map((link) => (
|
||||||
|
<Flex key={link}>
|
||||||
|
<Link href={link}>{link}</Link>
|
||||||
|
<IconButton icon={<TrashIcon />} aria-label="Remove Link" title="Remove Link" />
|
||||||
|
</Flex>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
{errors.rules?.message && <FormErrorMessage>{errors.rules?.message}</FormErrorMessage>}
|
||||||
|
<Flex gap="2">
|
||||||
|
<Input placeholder="https://example.com/useful-resources.html" />
|
||||||
|
<Button>Add Link</Button>
|
||||||
|
</Flex>
|
||||||
|
</FormControl> */}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter p="4" display="flex" gap="2">
|
<ModalFooter p="4" display="flex" gap="2">
|
||||||
|
@@ -8,6 +8,7 @@ import {
|
|||||||
COMMUNITY_DEFINITION_KIND,
|
COMMUNITY_DEFINITION_KIND,
|
||||||
getCommunityDescription,
|
getCommunityDescription,
|
||||||
getCommunityImage,
|
getCommunityImage,
|
||||||
|
getCommunityLinks,
|
||||||
getCommunityMods,
|
getCommunityMods,
|
||||||
getCommunityName,
|
getCommunityName,
|
||||||
getCommunityRanking,
|
getCommunityRanking,
|
||||||
@@ -38,6 +39,7 @@ export default function CommunityEditModal({
|
|||||||
rules: getCommunityRules(community) || "",
|
rules: getCommunityRules(community) || "",
|
||||||
mods: getCommunityMods(community) || [],
|
mods: getCommunityMods(community) || [],
|
||||||
relays: getCommunityRelays(community) || [],
|
relays: getCommunityRelays(community) || [],
|
||||||
|
links: getCommunityLinks(community) || [],
|
||||||
ranking: getCommunityRanking(community) || "votes",
|
ranking: getCommunityRanking(community) || "votes",
|
||||||
}),
|
}),
|
||||||
[community],
|
[community],
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
import { Box, ButtonGroup, Card, CardProps, Flex, Heading, Text, useDisclosure } from "@chakra-ui/react";
|
import { Box, ButtonGroup, Card, CardProps, Flex, Heading, Link, Text, useDisclosure } from "@chakra-ui/react";
|
||||||
|
import { Link as RouterLink } from "react-router-dom";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getCommunityDescription,
|
getCommunityDescription,
|
||||||
getCommunityMods,
|
getCommunityMods,
|
||||||
@@ -8,13 +10,13 @@ import {
|
|||||||
import CommunityDescription from "../../communities/components/community-description";
|
import CommunityDescription from "../../communities/components/community-description";
|
||||||
import UserAvatarLink from "../../../components/user-avatar-link";
|
import UserAvatarLink from "../../../components/user-avatar-link";
|
||||||
import { UserLink } from "../../../components/user-link";
|
import { UserLink } from "../../../components/user-link";
|
||||||
import { RelayIconStack } from "../../../components/relay-icon-stack";
|
|
||||||
import { NostrEvent } from "../../../types/nostr-event";
|
import { NostrEvent } from "../../../types/nostr-event";
|
||||||
import CommunityJoinButton from "../../communities/components/community-subscribe-button";
|
import CommunityJoinButton from "../../communities/components/community-subscribe-button";
|
||||||
import CommunityMenu from "./community-menu";
|
import CommunityMenu from "./community-menu";
|
||||||
import useCountCommunityMembers from "../../../hooks/use-count-community-members";
|
import useCountCommunityMembers from "../../../hooks/use-count-community-members";
|
||||||
import CommunityMembersModal from "./community-members-modal";
|
import CommunityMembersModal from "./community-members-modal";
|
||||||
import { readablizeSats } from "../../../helpers/bolt11";
|
import { readablizeSats } from "../../../helpers/bolt11";
|
||||||
|
import { RelayFavicon } from "../../../components/relay-favicon";
|
||||||
|
|
||||||
export default function VerticalCommunityDetails({
|
export default function VerticalCommunityDetails({
|
||||||
community,
|
community,
|
||||||
@@ -77,7 +79,14 @@ export default function VerticalCommunityDetails({
|
|||||||
Relays
|
Relays
|
||||||
</Heading>
|
</Heading>
|
||||||
<Flex direction="column" gap="2">
|
<Flex direction="column" gap="2">
|
||||||
<RelayIconStack relays={communityRelays} />
|
{communityRelays.map((url) => (
|
||||||
|
<Flex key={url} alignItems="center" gap="2">
|
||||||
|
<RelayFavicon relay={url} size="xs" />
|
||||||
|
<Link as={RouterLink} to={`/r/${encodeURIComponent(url)}`} fontWeight="bold" isTruncated>
|
||||||
|
{url}
|
||||||
|
</Link>
|
||||||
|
</Flex>
|
||||||
|
))}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
Reference in New Issue
Block a user