Use "animation_url" in the uploaded metadata for storing media file URIs (#27)
* Remove image and animation_url from metadata modal * Use animation_url for storing audio and video asset URIs * Use image and animation_url keys together for audio/video assets * Delete empty metadata keys * Post-review update
This commit is contained in:
parent
afe2928a9e
commit
986777b73d
@ -15,13 +15,11 @@ export interface MetadataModalProps {
|
|||||||
assetFile: File
|
assetFile: File
|
||||||
metadataFile: File
|
metadataFile: File
|
||||||
updateMetadata: (metadataFile: File) => void
|
updateMetadata: (metadataFile: File) => void
|
||||||
updatedMetadataFile: File
|
|
||||||
refresher: boolean
|
refresher: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MetadataModal = (props: MetadataModalProps) => {
|
export const MetadataModal = (props: MetadataModalProps) => {
|
||||||
const metadataFile: File = props.metadataFile
|
const metadataFile: File = props.metadataFile
|
||||||
const updatedMetadataFile: File = props.updatedMetadataFile
|
|
||||||
const [metadata, setMetadata] = useState<any>(null)
|
const [metadata, setMetadata] = useState<any>(null)
|
||||||
const [imageURL, setImageURL] = useState<string>('')
|
const [imageURL, setImageURL] = useState<string>('')
|
||||||
|
|
||||||
@ -59,11 +57,6 @@ export const MetadataModal = (props: MetadataModalProps) => {
|
|||||||
} else {
|
} else {
|
||||||
externalUrlState.onChange(parsedMetadata.external_url)
|
externalUrlState.onChange(parsedMetadata.external_url)
|
||||||
}
|
}
|
||||||
if (!parsedMetadata.animation_url) {
|
|
||||||
animationUrlState.onChange('')
|
|
||||||
} else {
|
|
||||||
animationUrlState.onChange(parsedMetadata.animation_url)
|
|
||||||
}
|
|
||||||
if (!parsedMetadata.youtube_url) {
|
if (!parsedMetadata.youtube_url) {
|
||||||
youtubeUrlState.onChange('')
|
youtubeUrlState.onChange('')
|
||||||
} else {
|
} else {
|
||||||
@ -72,10 +65,6 @@ export const MetadataModal = (props: MetadataModalProps) => {
|
|||||||
|
|
||||||
setMetadata(parsedMetadata)
|
setMetadata(parsedMetadata)
|
||||||
}
|
}
|
||||||
if (updatedMetadataFile) {
|
|
||||||
const parsedUpdatedMetadata = JSON.parse(await updatedMetadataFile.text())
|
|
||||||
setImageURL(parsedUpdatedMetadata.image)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const nameState = useInputState({
|
const nameState = useInputState({
|
||||||
@ -102,14 +91,6 @@ export const MetadataModal = (props: MetadataModalProps) => {
|
|||||||
defaultValue: metadata?.external_url,
|
defaultValue: metadata?.external_url,
|
||||||
})
|
})
|
||||||
|
|
||||||
const animationUrlState = useInputState({
|
|
||||||
id: 'animationUrl',
|
|
||||||
name: 'animationlUrl',
|
|
||||||
title: 'Animation URL',
|
|
||||||
placeholder: 'https://',
|
|
||||||
defaultValue: metadata?.animation_url,
|
|
||||||
})
|
|
||||||
|
|
||||||
const youtubeUrlState = useInputState({
|
const youtubeUrlState = useInputState({
|
||||||
id: 'youtubeUrl',
|
id: 'youtubeUrl',
|
||||||
name: 'youtubeUrl',
|
name: 'youtubeUrl',
|
||||||
@ -118,14 +99,6 @@ export const MetadataModal = (props: MetadataModalProps) => {
|
|||||||
defaultValue: metadata?.youtube_url,
|
defaultValue: metadata?.youtube_url,
|
||||||
})
|
})
|
||||||
|
|
||||||
const imageState = useInputState({
|
|
||||||
id: 'image',
|
|
||||||
name: 'image',
|
|
||||||
title: 'Image',
|
|
||||||
placeholder: 'Not uploaded yet.',
|
|
||||||
defaultValue: imageURL,
|
|
||||||
})
|
|
||||||
|
|
||||||
const attributesState = useMetadataAttributesState()
|
const attributesState = useMetadataAttributesState()
|
||||||
|
|
||||||
const generateUpdatedMetadata = () => {
|
const generateUpdatedMetadata = () => {
|
||||||
@ -135,11 +108,14 @@ export const MetadataModal = (props: MetadataModalProps) => {
|
|||||||
metadata.attributes = Object.values(attributesState)[1]
|
metadata.attributes = Object.values(attributesState)[1]
|
||||||
metadata.attributes = metadata.attributes.filter((attribute: { trait_type: string }) => attribute.trait_type !== '')
|
metadata.attributes = metadata.attributes.filter((attribute: { trait_type: string }) => attribute.trait_type !== '')
|
||||||
|
|
||||||
metadata.name = nameState.value
|
if (nameState.value === '') delete metadata.name
|
||||||
metadata.description = descriptionState.value
|
else metadata.name = nameState.value
|
||||||
metadata.external_url = externalUrlState.value
|
if (descriptionState.value === '') delete metadata.description
|
||||||
metadata.animation_url = animationUrlState.value
|
else metadata.description = descriptionState.value
|
||||||
metadata.youtube_url = youtubeUrlState.value
|
if (externalUrlState.value === '') delete metadata.external_url
|
||||||
|
else metadata.externalUrl = externalUrlState.value
|
||||||
|
if (youtubeUrlState.value === '') delete metadata.youtube_url
|
||||||
|
else metadata.youtube_url = youtubeUrlState.value
|
||||||
|
|
||||||
const metadataFileBlob = new Blob([JSON.stringify(metadata)], {
|
const metadataFileBlob = new Blob([JSON.stringify(metadata)], {
|
||||||
type: 'application/json',
|
type: 'application/json',
|
||||||
@ -147,6 +123,7 @@ export const MetadataModal = (props: MetadataModalProps) => {
|
|||||||
|
|
||||||
const editedMetadataFile = new File([metadataFileBlob], metadataFile.name, { type: 'application/json' })
|
const editedMetadataFile = new File([metadataFileBlob], metadataFile.name, { type: 'application/json' })
|
||||||
props.updateMetadata(editedMetadataFile)
|
props.updateMetadata(editedMetadataFile)
|
||||||
|
console.log(editedMetadataFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -169,9 +146,7 @@ export const MetadataModal = (props: MetadataModalProps) => {
|
|||||||
<TextInput {...nameState} onChange={(e) => nameState.onChange(e.target.value)} />
|
<TextInput {...nameState} onChange={(e) => nameState.onChange(e.target.value)} />
|
||||||
<TextInput {...descriptionState} onChange={(e) => descriptionState.onChange(e.target.value)} />
|
<TextInput {...descriptionState} onChange={(e) => descriptionState.onChange(e.target.value)} />
|
||||||
<TextInput {...externalUrlState} onChange={(e) => externalUrlState.onChange(e.target.value)} />
|
<TextInput {...externalUrlState} onChange={(e) => externalUrlState.onChange(e.target.value)} />
|
||||||
<TextInput {...animationUrlState} onChange={(e) => animationUrlState.onChange(e.target.value)} />
|
|
||||||
<TextInput {...youtubeUrlState} onChange={(e) => youtubeUrlState.onChange(e.target.value)} />
|
<TextInput {...youtubeUrlState} onChange={(e) => youtubeUrlState.onChange(e.target.value)} />
|
||||||
<TextInput {...imageState} disabled value={imageURL} />
|
|
||||||
<MetadataAttributes
|
<MetadataAttributes
|
||||||
attributes={attributesState.entries}
|
attributes={attributesState.entries}
|
||||||
onAdd={attributesState.add}
|
onAdd={attributesState.add}
|
||||||
|
@ -32,7 +32,6 @@ export const UploadDetails = ({ onChange }: UploadDetailsProps) => {
|
|||||||
const baseTokenURI = useCollectionStore().base_token_uri
|
const baseTokenURI = useCollectionStore().base_token_uri
|
||||||
const [assetFilesArray, setAssetFilesArray] = useState<File[]>([])
|
const [assetFilesArray, setAssetFilesArray] = useState<File[]>([])
|
||||||
const [metadataFilesArray, setMetadataFilesArray] = useState<File[]>([])
|
const [metadataFilesArray, setMetadataFilesArray] = useState<File[]>([])
|
||||||
const [updatedMetadataFilesArray, setUpdatedMetadataFilesArray] = useState<File[]>([])
|
|
||||||
const [uploadMethod, setUploadMethod] = useState<UploadMethod>('new')
|
const [uploadMethod, setUploadMethod] = useState<UploadMethod>('new')
|
||||||
const [uploadService, setUploadService] = useState<UploadServiceType>('nft-storage')
|
const [uploadService, setUploadService] = useState<UploadServiceType>('nft-storage')
|
||||||
const [metadataFileArrayIndex, setMetadataFileArrayIndex] = useState(0)
|
const [metadataFileArrayIndex, setMetadataFileArrayIndex] = useState(0)
|
||||||
@ -72,7 +71,6 @@ export const UploadDetails = ({ onChange }: UploadDetailsProps) => {
|
|||||||
const selectAssets = (event: ChangeEvent<HTMLInputElement>) => {
|
const selectAssets = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
setAssetFilesArray([])
|
setAssetFilesArray([])
|
||||||
setMetadataFilesArray([])
|
setMetadataFilesArray([])
|
||||||
setUpdatedMetadataFilesArray([])
|
|
||||||
console.log(event.target.files)
|
console.log(event.target.files)
|
||||||
let reader: FileReader
|
let reader: FileReader
|
||||||
if (event.target.files === null) return
|
if (event.target.files === null) return
|
||||||
@ -94,7 +92,6 @@ export const UploadDetails = ({ onChange }: UploadDetailsProps) => {
|
|||||||
|
|
||||||
const selectMetadata = (event: ChangeEvent<HTMLInputElement>) => {
|
const selectMetadata = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
setMetadataFilesArray([])
|
setMetadataFilesArray([])
|
||||||
setUpdatedMetadataFilesArray([])
|
|
||||||
console.log(assetFilesArray)
|
console.log(assetFilesArray)
|
||||||
console.log(event.target.files)
|
console.log(event.target.files)
|
||||||
let reader: FileReader
|
let reader: FileReader
|
||||||
@ -405,7 +402,6 @@ export const UploadDetails = ({ onChange }: UploadDetailsProps) => {
|
|||||||
metadataFile={metadataFilesArray[metadataFileArrayIndex]}
|
metadataFile={metadataFilesArray[metadataFileArrayIndex]}
|
||||||
refresher={refreshMetadata}
|
refresher={refreshMetadata}
|
||||||
updateMetadata={updateMetadataFileArray}
|
updateMetadata={updateMetadataFileArray}
|
||||||
updatedMetadataFile={updatedMetadataFilesArray[metadataFileArrayIndex]}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ import { MINTER_CODE_ID, SG721_CODE_ID, WHITELIST_CODE_ID } from 'utils/constant
|
|||||||
import { withMetadata } from 'utils/layout'
|
import { withMetadata } from 'utils/layout'
|
||||||
import { links } from 'utils/links'
|
import { links } from 'utils/links'
|
||||||
|
|
||||||
|
import { getAssetType } from '../../utils/getAssetType'
|
||||||
|
|
||||||
const CollectionCreationPage: NextPage = () => {
|
const CollectionCreationPage: NextPage = () => {
|
||||||
const wallet = useWallet()
|
const wallet = useWallet()
|
||||||
const { minter: minterContract, whitelist: whitelistContract } = useContracts()
|
const { minter: minterContract, whitelist: whitelistContract } = useContracts()
|
||||||
@ -158,6 +160,12 @@ const CollectionCreationPage: NextPage = () => {
|
|||||||
reader = new FileReader()
|
reader = new FileReader()
|
||||||
reader.onload = (e) => {
|
reader.onload = (e) => {
|
||||||
const data: any = JSON.parse(e.target?.result as string)
|
const data: any = JSON.parse(e.target?.result as string)
|
||||||
|
if (
|
||||||
|
getAssetType(uploadDetails.assetFiles[i].name) === 'audio' ||
|
||||||
|
getAssetType(uploadDetails.assetFiles[i].name) === 'video'
|
||||||
|
) {
|
||||||
|
data.animation_url = `ipfs://${assetUri}/${uploadDetails.assetFiles[i].name}`
|
||||||
|
}
|
||||||
data.image = `ipfs://${assetUri}/${uploadDetails.assetFiles[i].name}`
|
data.image = `ipfs://${assetUri}/${uploadDetails.assetFiles[i].name}`
|
||||||
const metadataFileBlob = new Blob([JSON.stringify(data)], {
|
const metadataFileBlob = new Blob([JSON.stringify(data)], {
|
||||||
type: 'application/json',
|
type: 'application/json',
|
||||||
|
@ -4,7 +4,7 @@ export type AssetType = 'image' | 'audio' | 'video' | 'unknown'
|
|||||||
|
|
||||||
export const getAssetType = (assetFileName: string): AssetType => {
|
export const getAssetType = (assetFileName: string): AssetType => {
|
||||||
const assetType = assetFileName?.split('.').pop() || 'unknown'
|
const assetType = assetFileName?.split('.').pop() || 'unknown'
|
||||||
if (assetType === 'png' || assetType === 'jpg' || assetType === 'jpeg') return 'image'
|
if (assetType === 'png' || assetType === 'jpg' || assetType === 'jpeg' || assetType === 'svg') return 'image'
|
||||||
if (assetType === 'mp3' || assetType === 'wav') return 'audio'
|
if (assetType === 'mp3' || assetType === 'wav') return 'audio'
|
||||||
if (assetType === 'mp4') return 'video'
|
if (assetType === 'mp4') return 'video'
|
||||||
return 'unknown'
|
return 'unknown'
|
||||||
|
Loading…
Reference in New Issue
Block a user