2022-07-28 13:38:43 +00:00
|
|
|
/* eslint-disable eslint-comments/disable-enable-pair */
|
2022-08-03 06:31:35 +00:00
|
|
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
2022-07-28 13:38:43 +00:00
|
|
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
2022-12-26 13:17:09 +00:00
|
|
|
|
2022-07-28 13:38:43 +00:00
|
|
|
import { useMetadataAttributesState } from 'components/forms/MetadataAttributes.hooks'
|
|
|
|
import { useEffect, useState } from 'react'
|
2022-08-10 06:57:20 +00:00
|
|
|
import toast from 'react-hot-toast'
|
2022-07-28 13:38:43 +00:00
|
|
|
|
2022-10-31 07:03:21 +00:00
|
|
|
import { Alert } from './Alert'
|
2022-08-15 08:50:15 +00:00
|
|
|
import { Button } from './Button'
|
2022-10-31 07:03:21 +00:00
|
|
|
import { Conditional } from './Conditional'
|
2022-07-28 13:38:43 +00:00
|
|
|
import { TextInput } from './forms/FormInput'
|
|
|
|
import { useInputState } from './forms/FormInput.hooks'
|
|
|
|
import { MetadataAttributes } from './forms/MetadataAttributes'
|
2022-08-01 09:51:54 +00:00
|
|
|
import { MetadataFormGroup } from './MetadataFormGroup'
|
2022-07-28 13:38:43 +00:00
|
|
|
|
|
|
|
export interface MetadataModalProps {
|
2022-08-03 06:31:35 +00:00
|
|
|
assetFile: File
|
2022-07-28 13:38:43 +00:00
|
|
|
metadataFile: File
|
|
|
|
updateMetadata: (metadataFile: File) => void
|
|
|
|
refresher: boolean
|
|
|
|
}
|
|
|
|
|
|
|
|
export const MetadataModal = (props: MetadataModalProps) => {
|
|
|
|
const metadataFile: File = props.metadataFile
|
|
|
|
const [metadata, setMetadata] = useState<any>(null)
|
|
|
|
|
|
|
|
let parsedMetadata: any
|
|
|
|
const parseMetadata = async () => {
|
|
|
|
if (metadataFile) {
|
|
|
|
attributesState.reset()
|
|
|
|
parsedMetadata = JSON.parse(await metadataFile.text())
|
|
|
|
|
2022-08-04 11:22:13 +00:00
|
|
|
if (!parsedMetadata.attributes || parsedMetadata.attributes.length === 0) {
|
2022-07-28 13:38:43 +00:00
|
|
|
attributesState.add({
|
2022-08-04 11:22:13 +00:00
|
|
|
trait_type: '',
|
|
|
|
value: '',
|
2022-07-28 13:38:43 +00:00
|
|
|
})
|
2022-08-04 11:22:13 +00:00
|
|
|
} else {
|
|
|
|
for (let i = 0; i < parsedMetadata.attributes.length; i++) {
|
|
|
|
attributesState.add({
|
|
|
|
trait_type: parsedMetadata.attributes[i].trait_type,
|
|
|
|
value: parsedMetadata.attributes[i].value,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!parsedMetadata.name) {
|
|
|
|
nameState.onChange('')
|
|
|
|
} else {
|
|
|
|
nameState.onChange(parsedMetadata.name)
|
|
|
|
}
|
|
|
|
if (!parsedMetadata.description) {
|
|
|
|
descriptionState.onChange('')
|
|
|
|
} else {
|
|
|
|
descriptionState.onChange(parsedMetadata.description)
|
|
|
|
}
|
|
|
|
if (!parsedMetadata.external_url) {
|
|
|
|
externalUrlState.onChange('')
|
|
|
|
} else {
|
|
|
|
externalUrlState.onChange(parsedMetadata.external_url)
|
|
|
|
}
|
|
|
|
if (!parsedMetadata.youtube_url) {
|
|
|
|
youtubeUrlState.onChange('')
|
|
|
|
} else {
|
|
|
|
youtubeUrlState.onChange(parsedMetadata.youtube_url)
|
2022-07-28 13:38:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
setMetadata(parsedMetadata)
|
2022-10-31 07:03:21 +00:00
|
|
|
} else {
|
|
|
|
attributesState.reset()
|
|
|
|
nameState.onChange('')
|
|
|
|
descriptionState.onChange('')
|
|
|
|
externalUrlState.onChange('')
|
|
|
|
youtubeUrlState.onChange('')
|
|
|
|
setMetadata(null)
|
2022-07-28 13:38:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const nameState = useInputState({
|
|
|
|
id: 'name',
|
|
|
|
name: 'name',
|
|
|
|
title: 'Name',
|
|
|
|
placeholder: 'Token name',
|
|
|
|
defaultValue: metadata?.name,
|
|
|
|
})
|
|
|
|
|
|
|
|
const descriptionState = useInputState({
|
|
|
|
id: 'description',
|
|
|
|
name: 'description',
|
|
|
|
title: 'Description',
|
|
|
|
placeholder: 'Token description',
|
|
|
|
defaultValue: metadata?.description,
|
|
|
|
})
|
|
|
|
|
|
|
|
const externalUrlState = useInputState({
|
|
|
|
id: 'externalUrl',
|
|
|
|
name: 'externalUrl',
|
|
|
|
title: 'External URL',
|
|
|
|
placeholder: 'https://',
|
|
|
|
defaultValue: metadata?.external_url,
|
|
|
|
})
|
|
|
|
|
2022-08-04 11:22:13 +00:00
|
|
|
const youtubeUrlState = useInputState({
|
|
|
|
id: 'youtubeUrl',
|
|
|
|
name: 'youtubeUrl',
|
|
|
|
title: 'Youtube URL',
|
|
|
|
placeholder: 'https://',
|
|
|
|
defaultValue: metadata?.youtube_url,
|
|
|
|
})
|
|
|
|
|
2022-07-28 13:38:43 +00:00
|
|
|
const attributesState = useMetadataAttributesState()
|
|
|
|
|
|
|
|
const generateUpdatedMetadata = () => {
|
|
|
|
metadata.attributes = Object.values(attributesState)[1]
|
|
|
|
metadata.attributes = metadata.attributes.filter((attribute: { trait_type: string }) => attribute.trait_type !== '')
|
|
|
|
|
2022-08-09 09:08:10 +00:00
|
|
|
if (nameState.value === '') delete metadata.name
|
|
|
|
else metadata.name = nameState.value
|
|
|
|
if (descriptionState.value === '') delete metadata.description
|
|
|
|
else metadata.description = descriptionState.value
|
|
|
|
if (externalUrlState.value === '') delete metadata.external_url
|
2022-10-31 06:31:23 +00:00
|
|
|
else metadata.external_url = externalUrlState.value
|
2022-08-09 09:08:10 +00:00
|
|
|
if (youtubeUrlState.value === '') delete metadata.youtube_url
|
|
|
|
else metadata.youtube_url = youtubeUrlState.value
|
2022-07-28 13:38:43 +00:00
|
|
|
|
|
|
|
const metadataFileBlob = new Blob([JSON.stringify(metadata)], {
|
|
|
|
type: 'application/json',
|
|
|
|
})
|
|
|
|
|
|
|
|
const editedMetadataFile = new File([metadataFileBlob], metadataFile.name, { type: 'application/json' })
|
|
|
|
props.updateMetadata(editedMetadataFile)
|
2022-08-10 06:57:20 +00:00
|
|
|
toast.success('Metadata updated successfully.')
|
2022-07-28 13:38:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
void parseMetadata()
|
|
|
|
}, [props.metadataFile, props.refresher])
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<input className="modal-toggle" id="my-modal-4" type="checkbox" />
|
|
|
|
<label className="cursor-pointer modal" htmlFor="my-modal-4">
|
2022-08-01 09:51:54 +00:00
|
|
|
<label
|
|
|
|
className="absolute top-5 bottom-5 w-full max-w-5xl max-h-full border-2 no-scrollbar modal-box"
|
|
|
|
htmlFor="temp"
|
|
|
|
>
|
|
|
|
<MetadataFormGroup
|
2022-08-03 06:31:35 +00:00
|
|
|
relatedAsset={props.assetFile}
|
|
|
|
subtitle={`Asset filename: ${props.assetFile?.name}`}
|
2022-08-01 09:51:54 +00:00
|
|
|
title="Update Metadata"
|
|
|
|
>
|
2022-10-31 07:03:21 +00:00
|
|
|
<TextInput
|
|
|
|
{...nameState}
|
|
|
|
disabled={!props.metadataFile}
|
|
|
|
onChange={(e) => nameState.onChange(e.target.value)}
|
|
|
|
/>
|
|
|
|
<TextInput
|
|
|
|
{...descriptionState}
|
|
|
|
disabled={!props.metadataFile}
|
|
|
|
onChange={(e) => descriptionState.onChange(e.target.value)}
|
|
|
|
/>
|
|
|
|
<TextInput
|
|
|
|
{...externalUrlState}
|
|
|
|
disabled={!props.metadataFile}
|
|
|
|
onChange={(e) => externalUrlState.onChange(e.target.value)}
|
|
|
|
/>
|
|
|
|
<TextInput
|
|
|
|
{...youtubeUrlState}
|
|
|
|
disabled={!props.metadataFile}
|
|
|
|
onChange={(e) => youtubeUrlState.onChange(e.target.value)}
|
2022-07-28 13:38:43 +00:00
|
|
|
/>
|
2022-10-31 07:03:21 +00:00
|
|
|
<Conditional test={props.metadataFile !== null}>
|
|
|
|
<MetadataAttributes
|
|
|
|
attributes={attributesState.entries}
|
|
|
|
onAdd={attributesState.add}
|
|
|
|
onChange={attributesState.update}
|
|
|
|
onRemove={attributesState.remove}
|
|
|
|
subtitle="Enter trait types and values"
|
|
|
|
title="Attributes"
|
|
|
|
/>
|
|
|
|
</Conditional>
|
2022-08-01 09:28:12 +00:00
|
|
|
<Button isDisabled={!props.metadataFile} onClick={generateUpdatedMetadata}>
|
|
|
|
Update Metadata
|
|
|
|
</Button>
|
2022-10-31 07:03:21 +00:00
|
|
|
<Conditional test={Boolean(!props.metadataFile)}>
|
|
|
|
<Alert type="info">No metadata file to preview. Please select metadata files.</Alert>
|
|
|
|
</Conditional>
|
2022-08-01 09:51:54 +00:00
|
|
|
</MetadataFormGroup>
|
2022-07-28 13:38:43 +00:00
|
|
|
</label>
|
|
|
|
</label>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|