Skip to content

Commit b0fc137

Browse files
committed
file input updates
1 parent 9bfe509 commit b0fc137

File tree

39 files changed

+484
-381
lines changed

39 files changed

+484
-381
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export function fileToBlobUrl(file: File) {
2+
const blob = new Blob([file], { type: file.type });
3+
return URL.createObjectURL(blob);
4+
}

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/BatchMetadata.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,11 @@ function UploadMetadataNFTSection(props: {
199199
<div className="flex flex-col gap-6 lg:flex-row">
200200
{/* Left */}
201201
<div className="shrink-0 lg:w-[300px]">
202-
<NFTMediaFormGroup form={form} previewMaxWidth="300px" />
202+
<NFTMediaFormGroup
203+
form={form}
204+
previewMaxWidth="300px"
205+
client={props.client}
206+
/>
203207
</div>
204208

205209
{/* Right */}

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/Mintable.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,11 @@ function MintNFTSection(props: {
397397
<div className="flex flex-col gap-6 lg:flex-row">
398398
{/* Left */}
399399
<div className="shrink-0 lg:w-[300px]">
400-
<NFTMediaFormGroup form={form} previewMaxWidth="300px" />
400+
<NFTMediaFormGroup
401+
form={form}
402+
previewMaxWidth="300px"
403+
client={props.client}
404+
/>
401405
</div>
402406

403407
{/* Right */}

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/nft/NFTMediaFormGroup.tsx

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"use client";
22
import { FormFieldSetup } from "@/components/blocks/FormFieldSetup";
33
import { FileInput } from "components/shared/FileInput";
4-
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
54
import type { UseFormReturn } from "react-hook-form";
5+
import type { ThirdwebClient } from "thirdweb";
66
import type { NFTInput } from "thirdweb/utils";
77

88
type NFTMediaFormGroupValues = {
@@ -14,6 +14,7 @@ type NFTMediaFormGroupValues = {
1414
export function NFTMediaFormGroup<T extends NFTMediaFormGroupValues>(props: {
1515
form: UseFormReturn<T>;
1616
previewMaxWidth?: string;
17+
client: ThirdwebClient;
1718
}) {
1819
// T contains all properties of NFTMediaFormGroupValues, so this is a-ok
1920
const form = props.form as unknown as UseFormReturn<NFTMediaFormGroupValues>;
@@ -50,26 +51,20 @@ export function NFTMediaFormGroup<T extends NFTMediaFormGroupValues>(props: {
5051
}
5152
};
5253

53-
const animation_url = form.watch("animation_url");
54-
const image = form.watch("image");
55-
const errors = form.formState.errors;
54+
const _animation_url = form.watch("animation_url");
55+
const _image = form.watch("image");
56+
const _media = _animation_url || _image;
5657

57-
const imageUrl = useImageFileOrUrl(image as File | string);
58-
const showCoverImageUpload = animation_url instanceof File;
58+
const media =
59+
_media instanceof File || typeof _media === "string" ? _media : undefined;
5960

60-
const mediaFileUrl =
61-
animation_url instanceof File
62-
? animation_url
63-
: image instanceof File
64-
? imageUrl
65-
: undefined;
61+
const image =
62+
_image instanceof File || typeof _image === "string" ? _image : undefined;
6663

6764
const mediaFileError =
68-
animation_url instanceof File
69-
? errors?.animation_url
70-
: image instanceof File
71-
? errors?.image
72-
: undefined;
65+
form.formState.errors?.animation_url || form.formState.errors?.image;
66+
67+
const showCoverImageUpload = !!_animation_url;
7368

7469
const previewMaxWidth = props.previewMaxWidth ?? "200px";
7570
return (
@@ -85,11 +80,12 @@ export function NFTMediaFormGroup<T extends NFTMediaFormGroupValues>(props: {
8580
</p>
8681
<FileInput
8782
previewMaxWidth={previewMaxWidth}
88-
value={mediaFileUrl as File | string}
83+
value={media}
8984
showPreview={true}
9085
setValue={setFile}
9186
className="max-sm:!max-w-full rounded border border-border transition-all duration-200"
9287
selectOrUpload="Upload"
88+
client={props.client}
9389
helperText="Media"
9490
/>
9591
</FormFieldSetup>
@@ -100,12 +96,13 @@ export function NFTMediaFormGroup<T extends NFTMediaFormGroupValues>(props: {
10096
htmlFor="cover-image"
10197
label="Cover Image"
10298
tooltip="You can optionally upload an image as the cover of your NFT."
103-
isRequired
99+
isRequired={false}
104100
>
105101
<FileInput
106102
previewMaxWidth={previewMaxWidth}
103+
client={props.client}
107104
accept={{ "image/*": [] }}
108-
value={imageUrl}
105+
value={image}
109106
showUploadButton
110107
setValue={(file) => {
111108
form.setValue("image", file);

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx

Lines changed: 22 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { TransactionButton } from "components/buttons/TransactionButton";
1515
import { PropertiesFormControl } from "components/contract-pages/forms/properties.shared";
1616
import { FileInput } from "components/shared/FileInput";
1717
import { useTrack } from "hooks/analytics/useTrack";
18-
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
1918
import { useTxNotifications } from "hooks/useTxNotifications";
2019
import { type Dispatch, type SetStateAction, useMemo } from "react";
2120
import { useForm } from "react-hook-form";
@@ -38,7 +37,6 @@ import {
3837
FormLabel,
3938
Heading,
4039
} from "tw-components";
41-
import { NFTMediaWithEmptyState } from "tw-components/nft-media";
4240
import type { NFTMetadataInputLimited } from "types/modified-types";
4341
import { parseAttributes } from "utils/parseAttributes";
4442

@@ -126,25 +124,20 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
126124
}
127125
};
128126

129-
const imageUrl = useImageFileOrUrl(watch("image") as File | string);
130-
const animationUrlFormValue = watch("animation_url");
131-
const imageUrlFormValue = watch("image");
127+
const _animation_url = watch("animation_url");
128+
const _image = watch("image");
129+
const _media = _animation_url || _image;
132130

133-
const mediaFileUrl =
134-
watch("animation_url") instanceof File
135-
? watch("animation_url")
136-
: watch("image") instanceof File
137-
? imageUrl
138-
: undefined;
131+
const media =
132+
_media instanceof File || typeof _media === "string" ? _media : undefined;
139133

140-
const mediaFileError =
141-
watch("animation_url") instanceof File
142-
? errors?.animation_url
143-
: watch("image") instanceof File
144-
? errors?.image
145-
: undefined;
134+
const image =
135+
_image instanceof File || typeof _image === "string" ? _image : undefined;
136+
137+
const mediaFileError = errors?.animation_url || errors?.image;
138+
139+
const showCoverImageUpload = !!_animation_url;
146140

147-
const showCoverImageUpload = watch("animation_url") instanceof File;
148141
const sendAndConfirmTx = useSendAndConfirmTransaction();
149142
const updateMetadataNotifications = useTxNotifications(
150143
"NFT metadata updated successfully",
@@ -230,37 +223,20 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
230223
<Input autoFocus {...register("name")} />
231224
<FormErrorMessage>{errors?.name?.message}</FormErrorMessage>
232225
</FormControl>
226+
233227
<FormControl isInvalid={!!mediaFileError}>
234228
<FormLabel>Media</FormLabel>
235229
<div className="flex flex-row flex-wrap gap-3">
236-
{nft?.metadata && !mediaFileUrl && (
237-
<NFTMediaWithEmptyState
238-
client={contract.client}
239-
metadata={{
240-
name: nft.metadata.name,
241-
animation_url:
242-
typeof animationUrlFormValue === "string"
243-
? animationUrlFormValue
244-
: nft.metadata.animation_url,
245-
image:
246-
typeof imageUrlFormValue === "string"
247-
? imageUrlFormValue
248-
: nft.metadata.image,
249-
}}
250-
width="200px"
251-
height="200px"
252-
/>
253-
)}
254-
255230
<FileInput
256231
previewMaxWidth="200px"
257-
value={mediaFileUrl as File | string}
232+
value={media}
258233
showUploadButton
259-
showPreview={nft?.metadata ? !!mediaFileUrl : true}
234+
showPreview
260235
setValue={setFile}
261236
className="shrink-0 rounded border border-border transition-all duration-200"
262237
selectOrUpload="Upload"
263238
helperText={nft?.metadata ? "New Media" : "Media"}
239+
client={contract.client}
264240
/>
265241
</div>
266242

@@ -272,13 +248,15 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
272248
{mediaFileError?.message as unknown as string}
273249
</FormErrorMessage>
274250
</FormControl>
251+
275252
{showCoverImageUpload && (
276253
<FormControl isInvalid={!!errors.image}>
277254
<FormLabel>Cover Image</FormLabel>
278255
<FileInput
279256
previewMaxWidth="200px"
257+
client={contract.client}
280258
accept={{ "image/*": [] }}
281-
value={imageUrl}
259+
value={image}
282260
showUploadButton
283261
setValue={(file) => setValue("image", file)}
284262
className="rounded border border-border transition-all"
@@ -303,6 +281,7 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
303281
control={control}
304282
register={register}
305283
setValue={setValue}
284+
client={contract.client}
306285
/>
307286

308287
<Accordion
@@ -344,9 +323,7 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
344323
<FormControl isInvalid={!!errors.image}>
345324
<FormLabel>Image URL</FormLabel>
346325
<Input
347-
value={
348-
typeof imageUrlFormValue === "string" ? imageUrlFormValue : ""
349-
}
326+
value={typeof _image === "string" ? _image : ""}
350327
onChange={(e) => {
351328
setValue("image", e.target.value);
352329
}}
@@ -360,11 +337,7 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
360337
<FormControl isInvalid={!!errors.animation_url}>
361338
<FormLabel>Animation URL</FormLabel>
362339
<Input
363-
value={
364-
typeof animationUrlFormValue === "string"
365-
? animationUrlFormValue
366-
: ""
367-
}
340+
value={typeof _animation_url === "string" ? _animation_url : ""}
368341
onChange={(e) => {
369342
setValue("animation_url", e.target.value);
370343
}}
@@ -396,7 +369,7 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
396369
isPending={sendAndConfirmTx.isPending}
397370
form={UPDATE_METADATA_FORM_ID}
398371
type="submit"
399-
disabled={!isDirty && imageUrl === nft?.metadata.image}
372+
disabled={!isDirty}
400373
>
401374
Update NFT
402375
</TransactionButton>

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/lazy-mint-form.tsx

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { TransactionButton } from "components/buttons/TransactionButton";
1717
import { PropertiesFormControl } from "components/contract-pages/forms/properties.shared";
1818
import { FileInput } from "components/shared/FileInput";
1919
import { useTrack } from "hooks/analytics/useTrack";
20-
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
2120
import { useTxNotifications } from "hooks/useTxNotifications";
2221
import type { Dispatch, SetStateAction } from "react";
2322
import { useForm } from "react-hook-form";
@@ -94,25 +93,19 @@ export const LazyMintNftForm: React.FC<LazyMintNftFormParams> = ({
9493
}
9594
};
9695

97-
const imageUrl = useImageFileOrUrl(watch("image") as File | string);
98-
const animationUrlFormValue = watch("animation_url");
99-
const imageUrlFormValue = watch("image");
96+
const _animation_url = watch("animation_url");
97+
const _image = watch("image");
98+
const _media = _animation_url || _image;
10099

101-
const mediaFileUrl =
102-
watch("animation_url") instanceof File
103-
? watch("animation_url")
104-
: watch("image") instanceof File
105-
? imageUrl
106-
: undefined;
100+
const media =
101+
_media instanceof File || typeof _media === "string" ? _media : undefined;
107102

108-
const mediaFileError =
109-
watch("animation_url") instanceof File
110-
? errors?.animation_url
111-
: watch("image") instanceof File
112-
? errors?.image
113-
: undefined;
103+
const image =
104+
_image instanceof File || typeof _image === "string" ? _image : undefined;
114105

115-
const showCoverImageUpload = watch("animation_url") instanceof File;
106+
const mediaFileError = errors?.animation_url || errors?.image;
107+
108+
const showCoverImageUpload = !!_animation_url;
116109

117110
const lazyMintNotifications = useTxNotifications(
118111
"NFT lazy minted successfully",
@@ -180,13 +173,14 @@ export const LazyMintNftForm: React.FC<LazyMintNftFormParams> = ({
180173
<div>
181174
<FileInput
182175
previewMaxWidth="200px"
183-
value={mediaFileUrl as File | string}
176+
value={media}
184177
showUploadButton
185178
showPreview={true}
186179
setValue={setFile}
187180
className="rounded border border-border transition-all duration-200"
188181
selectOrUpload="Upload"
189182
helperText="Media"
183+
client={contract.client}
190184
/>
191185
</div>
192186
<FormHelperText>
@@ -202,8 +196,9 @@ export const LazyMintNftForm: React.FC<LazyMintNftFormParams> = ({
202196
<FormLabel>Cover Image</FormLabel>
203197
<FileInput
204198
previewMaxWidth="200px"
199+
client={contract.client}
205200
accept={{ "image/*": [] }}
206-
value={imageUrl}
201+
value={image}
207202
showUploadButton
208203
setValue={(file) => setValue("image", file)}
209204
className="rounded border border-border transition-all"
@@ -228,6 +223,7 @@ export const LazyMintNftForm: React.FC<LazyMintNftFormParams> = ({
228223
control={control}
229224
register={register}
230225
setValue={setValue}
226+
client={contract.client}
231227
/>
232228
<Accordion
233229
allowToggle={!(errors.background_color || errors.external_url)}
@@ -271,11 +267,7 @@ export const LazyMintNftForm: React.FC<LazyMintNftFormParams> = ({
271267
<FormLabel>Image URL</FormLabel>
272268
<Input
273269
{...register("image")}
274-
value={
275-
typeof imageUrlFormValue === "string"
276-
? imageUrlFormValue
277-
: ""
278-
}
270+
value={typeof _image === "string" ? _image : ""}
279271
onChange={(e) => {
280272
setValue("image", e.target.value);
281273
}}
@@ -291,9 +283,7 @@ export const LazyMintNftForm: React.FC<LazyMintNftFormParams> = ({
291283
<Input
292284
{...register("animation_url")}
293285
value={
294-
typeof animationUrlFormValue === "string"
295-
? animationUrlFormValue
296-
: ""
286+
typeof _animation_url === "string" ? _animation_url : ""
297287
}
298288
onChange={(e) => {
299289
setValue("animation_url", e.target.value);

0 commit comments

Comments
 (0)