Move assets preview to component (#29)

This commit is contained in:
Arda Nakışçı 2022-08-09 16:18:32 +03:00 committed by GitHub
parent 0f0e68a285
commit b9c22ea425
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 121 additions and 82 deletions

View File

@ -0,0 +1,103 @@
import { useCallback, useMemo, useState } from 'react'
import { getAssetType } from 'utils/getAssetType'
interface AssetsPreviewProps {
assetFilesArray: File[]
updateMetadataFileIndex: (index: number) => void
}
const ITEM_NUMBER = 12
export const AssetsPreview = ({ assetFilesArray, updateMetadataFileIndex }: AssetsPreviewProps) => {
const [page, setPage] = useState(1)
const totalPages = useMemo(() => Math.ceil(assetFilesArray.length / ITEM_NUMBER), [assetFilesArray])
const videoPreviewElements = useMemo(() => {
const tempArray: JSX.Element[] = []
assetFilesArray.forEach((assetFile) => {
if (getAssetType(assetFile.name) === 'video') {
tempArray.push(
<video
key={assetFile.name}
className="absolute px-1 my-1 thumbnail"
id="video"
muted
onMouseEnter={(e) => {
void e.currentTarget.play()
}}
onMouseLeave={(e) => {
e.currentTarget.pause()
e.currentTarget.currentTime = 0
}}
src={URL.createObjectURL(assetFile)}
/>,
)
}
})
return tempArray
}, [assetFilesArray])
const renderImages = useCallback(() => {
return assetFilesArray.slice((page - 1) * ITEM_NUMBER, page * ITEM_NUMBER).map((assetSource, index) => (
<button
key={assetSource.name}
className="relative p-0 w-[100px] h-[100px] bg-transparent hover:bg-transparent border-0 btn modal-button"
onClick={() => {
updateMetadataFileIndex((page - 1) * ITEM_NUMBER + index)
}}
type="button"
>
<label
className="relative p-0 w-full h-full bg-transparent hover:bg-transparent border-0 btn modal-button"
htmlFor="my-modal-4"
>
{getAssetType(assetSource.name) === 'audio' && (
<div className="flex absolute flex-col items-center mt-4 ml-2">
<img key={`audio-${index}`} alt="audio_icon" className="mb-2 ml-1 w-6 h-6 thumbnail" src="/audio.png" />
<span className="flex self-center ">{assetSource.name}</span>
</div>
)}
{getAssetType(assetSource.name) === 'video' &&
videoPreviewElements.filter((videoPreviewElement) => videoPreviewElement.key === assetSource.name)}
{getAssetType(assetSource.name) === 'image' && (
<img
key={`image-${index}`}
alt="asset"
className="px-1 my-1 thumbnail"
src={URL.createObjectURL(assetSource)}
/>
)}
</label>
</button>
))
}, [page])
const nextPage = () => {
if (totalPages === page) return
setPage(page + 1)
}
const prevPage = () => {
if (page === 1) return
setPage(page - 1)
}
return (
<div className="flex flex-col items-center">
<div className="mt-2 w-[400px] h-[300px]">{renderImages()}</div>
<div className="mt-5 btn-group">
<button className="text-white bg-plumbus-light btn" onClick={prevPage} type="button">
«
</button>
<button className="text-white btn" type="button">
Page {page}/{totalPages}
</button>
<button className="text-white bg-plumbus-light btn" onClick={nextPage} type="button">
»
</button>
</div>
</div>
)
}

View File

@ -1,16 +1,16 @@
import clsx from 'clsx'
import { Alert } from 'components/Alert'
import Anchor from 'components/Anchor'
import { AssetsPreview } from 'components/AssetsPreview'
import { Conditional } from 'components/Conditional'
import { TextInput } from 'components/forms/FormInput'
import { useInputState } from 'components/forms/FormInput.hooks'
import { MetadataModal } from 'components/MetadataModal'
import { setBaseTokenUri, setImage, useCollectionStore } from 'contexts/collection'
import type { ChangeEvent } from 'react'
import { useEffect, useMemo, useState } from 'react'
import { useEffect, useState } from 'react'
import { toast } from 'react-hot-toast'
import type { UploadServiceType } from 'services/upload'
import { getAssetType } from 'utils/getAssetType'
import { naturalCompare } from 'utils/sort'
type UploadMethod = 'new' | 'existing'
@ -69,46 +69,48 @@ export const UploadDetails = ({ onChange }: UploadDetailsProps) => {
}
const selectAssets = (event: ChangeEvent<HTMLInputElement>) => {
setAssetFilesArray([])
setMetadataFilesArray([])
console.log(event.target.files)
const files: File[] = []
let reader: FileReader
if (event.target.files === null) return
setAssetFilesArray([])
setMetadataFilesArray([])
for (let i = 0; i < event.target.files.length; i++) {
reader = new FileReader()
reader.onload = (e) => {
if (!e.target?.result) return toast.error('Error parsing file.')
if (!event.target.files) return toast.error('No files selected.')
const assetFile = new File([e.target.result], event.target.files[i].name, { type: 'image/jpg' })
setAssetFilesArray((prev) => [...prev, assetFile])
files.push(assetFile)
}
if (!event.target.files) return toast.error('No file selected.')
reader.readAsArrayBuffer(event.target.files[i])
reader.onloadend = (e) => {
setAssetFilesArray((prev) => prev.sort((a, b) => naturalCompare(a.name, b.name)))
if (!event.target.files) return toast.error('No file selected.')
if (i === event.target.files.length - 1) {
setAssetFilesArray(files.sort((a, b) => naturalCompare(a.name, b.name)))
}
}
}
}
const selectMetadata = (event: ChangeEvent<HTMLInputElement>) => {
setMetadataFilesArray([])
console.log(assetFilesArray)
console.log(event.target.files)
const files: File[] = []
let reader: FileReader
if (event.target.files === null) return toast.error('No files selected.')
setMetadataFilesArray([])
for (let i = 0; i < event.target.files.length; i++) {
reader = new FileReader()
reader.onload = (e) => {
if (!e.target?.result) return toast.error('Error parsing file.')
if (!event.target.files) return toast.error('No files selected.')
const metadataFile = new File([e.target.result], event.target.files[i].name, { type: 'application/json' })
setMetadataFilesArray((prev) => [...prev, metadataFile])
files.push(metadataFile)
}
if (!event.target.files) return toast.error('No file selected.')
reader.readAsText(event.target.files[i], 'utf8')
reader.onloadend = (e) => {
setMetadataFilesArray((prev) => prev.sort((a, b) => naturalCompare(a.name, b.name)))
console.log(metadataFilesArray)
if (!event.target.files) return toast.error('No file selected.')
if (i === event.target.files.length - 1) {
setMetadataFilesArray(files.sort((a, b) => naturalCompare(a.name, b.name)))
}
}
}
}
@ -124,31 +126,6 @@ export const UploadDetails = ({ onChange }: UploadDetailsProps) => {
console.log(JSON.parse(await metadataFilesArray[metadataFileArrayIndex]?.text()))
}
const videoPreviewElements = useMemo(() => {
const tempArray: JSX.Element[] = []
assetFilesArray.forEach((assetFile) => {
if (getAssetType(assetFile.name) === 'video') {
tempArray.push(
<video
key={assetFile.name}
className="absolute px-1 my-1 thumbnail"
id="video"
muted
onMouseEnter={(e) => {
void e.currentTarget.play()
}}
onMouseLeave={(e) => {
e.currentTarget.pause()
e.currentTarget.currentTime = 0
}}
src={URL.createObjectURL(assetFile)}
/>,
)
}
})
return tempArray
}, [assetFilesArray])
useEffect(() => {
try {
const data: UploadDetailsDataProps = {
@ -400,48 +377,7 @@ export const UploadDetails = ({ onChange }: UploadDetailsProps) => {
</div>
<Conditional test={assetFilesArray.length > 0}>
<div className="overflow-auto mt-2 mr-10 ml-20 w-4/5 h-96">
{assetFilesArray.map((assetSource, index) => (
<button
key={assetSource.name}
className="relative p-0 w-[100px] h-[100px] bg-transparent hover:bg-transparent border-0 btn modal-button"
onClick={() => {
updateMetadataFileIndex(index)
}}
type="button"
>
<label
className="relative p-0 w-full h-full bg-transparent hover:bg-transparent border-0 btn modal-button"
htmlFor="my-modal-4"
>
{getAssetType(assetSource.name) === 'audio' && (
<div className="flex absolute flex-col items-center mt-4 ml-2">
<img
key={`audio-${index}`}
alt="audio_icon"
className="mb-2 ml-1 w-6 h-6 thumbnail"
src="/audio.png"
/>
<span className="flex self-center ">{assetSource.name}</span>
</div>
)}
{getAssetType(assetSource.name) === 'video' &&
videoPreviewElements.filter(
(videoPreviewElement) => videoPreviewElement.key === assetSource.name,
)}
{getAssetType(assetSource.name) === 'image' && (
<img
key={`image-${index}`}
alt="asset"
className="px-1 my-1 thumbnail"
src={URL.createObjectURL(assetSource)}
/>
)}
</label>
</button>
))}
</div>
<AssetsPreview assetFilesArray={assetFilesArray} updateMetadataFileIndex={updateMetadataFileIndex} />
</Conditional>
</div>
</div>