mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-09-26 19:47:25 +02:00
fix issue with editing community
allow user to edit banner image of community
This commit is contained in:
@@ -1,10 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Flex,
|
Flex,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormErrorMessage,
|
FormErrorMessage,
|
||||||
FormHelperText,
|
FormHelperText,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
|
IconButton,
|
||||||
|
Image,
|
||||||
Input,
|
Input,
|
||||||
Modal,
|
Modal,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
@@ -18,11 +21,18 @@ import {
|
|||||||
RadioGroup,
|
RadioGroup,
|
||||||
Stack,
|
Stack,
|
||||||
Textarea,
|
Textarea,
|
||||||
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { SubmitHandler, useForm } from "react-hook-form";
|
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 Upload01 from "../../../components/icons/upload-01";
|
||||||
|
import Upload02 from "../../../components/icons/upload-02";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { nostrBuildUploadImage } from "../../../helpers/nostr-build";
|
||||||
|
import { useSigningContext } from "../../../providers/signing-provider";
|
||||||
|
|
||||||
export type FormValues = {
|
export type FormValues = {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -46,11 +56,13 @@ export default function CommunityCreateModal({
|
|||||||
defaultValues?: FormValues;
|
defaultValues?: FormValues;
|
||||||
isUpdate?: boolean;
|
isUpdate?: boolean;
|
||||||
}) {
|
}) {
|
||||||
|
const toast = useToast();
|
||||||
const account = useCurrentAccount();
|
const account = useCurrentAccount();
|
||||||
|
const { requestSignature } = useSigningContext();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
formState: { errors },
|
formState: { errors, isSubmitting },
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
watch,
|
watch,
|
||||||
getValues,
|
getValues,
|
||||||
@@ -70,6 +82,27 @@ export default function CommunityCreateModal({
|
|||||||
|
|
||||||
watch("mods");
|
watch("mods");
|
||||||
watch("ranking");
|
watch("ranking");
|
||||||
|
watch("banner");
|
||||||
|
|
||||||
|
const [uploading, setUploading] = useState(false);
|
||||||
|
const uploadFile = useCallback(
|
||||||
|
async (file: File) => {
|
||||||
|
try {
|
||||||
|
if (!(file.type.includes("image") || file.type.includes("video") || file.type.includes("audio")))
|
||||||
|
throw new Error("Unsupported file type");
|
||||||
|
|
||||||
|
setUploading(true);
|
||||||
|
|
||||||
|
const response = await nostrBuildUploadImage(file, requestSignature);
|
||||||
|
const imageUrl = response.url;
|
||||||
|
setValue("banner", imageUrl, { shouldDirty: true, shouldValidate: true });
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof Error) toast({ description: e.message, status: "error" });
|
||||||
|
}
|
||||||
|
setUploading(false);
|
||||||
|
},
|
||||||
|
[setValue, getValues, requestSignature, toast],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onClose={onClose} size="2xl" {...props}>
|
<Modal isOpen={isOpen} onClose={onClose} size="2xl" {...props}>
|
||||||
@@ -92,6 +125,7 @@ export default function CommunityCreateModal({
|
|||||||
})}
|
})}
|
||||||
isReadOnly={isUpdate}
|
isReadOnly={isUpdate}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
|
placeholder="more-cat-pictures"
|
||||||
/>
|
/>
|
||||||
<FormHelperText>The name of your community (no-spaces)</FormHelperText>
|
<FormHelperText>The name of your community (no-spaces)</FormHelperText>
|
||||||
{errors.name?.message && <FormErrorMessage>{errors.name?.message}</FormErrorMessage>}
|
{errors.name?.message && <FormErrorMessage>{errors.name?.message}</FormErrorMessage>}
|
||||||
@@ -101,13 +135,56 @@ export default function CommunityCreateModal({
|
|||||||
<FormControl isInvalid={!!errors.description}>
|
<FormControl isInvalid={!!errors.description}>
|
||||||
<FormLabel>Description</FormLabel>
|
<FormLabel>Description</FormLabel>
|
||||||
<Textarea {...register("description")} autoComplete="off" />
|
<Textarea {...register("description")} autoComplete="off" />
|
||||||
<FormHelperText>short description about your community</FormHelperText>
|
<FormHelperText>Short description about your community</FormHelperText>
|
||||||
{errors.description?.message && <FormErrorMessage>{errors.description?.message}</FormErrorMessage>}
|
{errors.description?.message && <FormErrorMessage>{errors.description?.message}</FormErrorMessage>}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
|
<FormControl isInvalid={!!errors.banner}>
|
||||||
|
<FormLabel>Banner</FormLabel>
|
||||||
|
{getValues().banner && (
|
||||||
|
<Box
|
||||||
|
backgroundImage={getValues().banner}
|
||||||
|
backgroundRepeat="no-repeat"
|
||||||
|
backgroundPosition="center"
|
||||||
|
backgroundSize="cover"
|
||||||
|
aspectRatio={3 / 1}
|
||||||
|
mb="2"
|
||||||
|
borderRadius="lg"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Flex gap="2">
|
||||||
|
<Input
|
||||||
|
type="url"
|
||||||
|
{...register("banner")}
|
||||||
|
autoComplete="off"
|
||||||
|
placeholder="https://example.com/banner.png"
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
id="banner-upload"
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
display="none"
|
||||||
|
onChange={(e) => {
|
||||||
|
const img = e.target.files?.[0];
|
||||||
|
if (img) uploadFile(img);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
as="label"
|
||||||
|
htmlFor="banner-upload"
|
||||||
|
icon={<Upload01 />}
|
||||||
|
aria-label="Upload Image"
|
||||||
|
cursor="pointer"
|
||||||
|
tabIndex={0}
|
||||||
|
isLoading={uploading}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
{errors.banner?.message && <FormErrorMessage>{errors.banner?.message}</FormErrorMessage>}
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<FormControl isInvalid={!!errors.rules}>
|
<FormControl isInvalid={!!errors.rules}>
|
||||||
<FormLabel>Rules and Guidelines</FormLabel>
|
<FormLabel>Rules and Guidelines</FormLabel>
|
||||||
<Textarea {...register("rules")} autoComplete="off" />
|
<Textarea {...register("rules")} autoComplete="off" placeholder="don't be a jerk" />
|
||||||
<FormHelperText>Rules and posting guidelines</FormHelperText>
|
<FormHelperText>Rules and posting guidelines</FormHelperText>
|
||||||
{errors.rules?.message && <FormErrorMessage>{errors.rules?.message}</FormErrorMessage>}
|
{errors.rules?.message && <FormErrorMessage>{errors.rules?.message}</FormErrorMessage>}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@@ -140,7 +217,7 @@ export default function CommunityCreateModal({
|
|||||||
|
|
||||||
<ModalFooter p="4" display="flex" gap="2">
|
<ModalFooter p="4" display="flex" gap="2">
|
||||||
<Button onClick={onClose}>Cancel</Button>
|
<Button onClick={onClose}>Cancel</Button>
|
||||||
<Button colorScheme="primary" type="submit">
|
<Button colorScheme="primary" type="submit" isLoading={isSubmitting}>
|
||||||
{isUpdate ? "Update Community" : "Create Community"}
|
{isUpdate ? "Update Community" : "Create Community"}
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
@@ -35,7 +35,7 @@ function CommunitiesHomePage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const pubkey of values.mods) {
|
for (const pubkey of values.mods) {
|
||||||
draft.tags.push(["p", pubkey, "moderator"]);
|
draft.tags.push(["p", pubkey, "", "moderator"]);
|
||||||
}
|
}
|
||||||
for (const url of values.relays) {
|
for (const url of values.relays) {
|
||||||
draft.tags.push(["relay", url]);
|
draft.tags.push(["relay", url]);
|
||||||
|
@@ -52,7 +52,7 @@ export default function CommunityEditModal({
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const pubkey of values.mods) {
|
for (const pubkey of values.mods) {
|
||||||
draft.tags.push(["p", pubkey, "moderator"]);
|
draft.tags.push(["p", pubkey, "", "moderator"]);
|
||||||
}
|
}
|
||||||
for (const url of values.relays) {
|
for (const url of values.relays) {
|
||||||
draft.tags.push(["relay", url]);
|
draft.tags.push(["relay", url]);
|
||||||
@@ -70,6 +70,8 @@ export default function CommunityEditModal({
|
|||||||
);
|
);
|
||||||
|
|
||||||
replaceableEventLoaderService.handleEvent(signed);
|
replaceableEventLoaderService.handleEvent(signed);
|
||||||
|
|
||||||
|
onClose();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error) toast({ description: e.message, status: "error" });
|
if (e instanceof Error) toast({ description: e.message, status: "error" });
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@ function useCommunityPointer() {
|
|||||||
|
|
||||||
export default function CommunityView() {
|
export default function CommunityView() {
|
||||||
const pointer = useCommunityPointer();
|
const pointer = useCommunityPointer();
|
||||||
const community = useReplaceableEvent(pointer);
|
const community = useReplaceableEvent(pointer, [], { alwaysRequest: true });
|
||||||
|
|
||||||
if (!community) return <Spinner />;
|
if (!community) return <Spinner />;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user