stargaze-studio/components/AssetsPreview.tsx
2023-11-22 23:23:51 +03:00

171 lines
5.5 KiB
TypeScript

import clsx from 'clsx'
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={clsx('absolute px-1 my-1 max-h-24 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 getOverlaySize = () => {
if (assetFilesArray.length < 100) return 'w-[22px] h-[22px]'
if (assetFilesArray.length > 100 && assetFilesArray.length <= 1000 && page < 9) return 'w-[22px] h-[22px]'
else if (page < 84) return 'w-[27px] h-[27px]'
return 'w-[35px] h-[35px]'
}
const renderImages = useCallback(() => {
return assetFilesArray.slice((page - 1) * ITEM_NUMBER, page * ITEM_NUMBER).map((assetSource, index) => (
<button
key={assetSource.name}
className={clsx(
'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"
>
<div
className={clsx(
'flex absolute right-20 bottom-20 justify-center items-center',
'text-sm text-white bg-stargaze rounded-full',
getOverlaySize(),
)}
>
{(page - 1) * 12 + (index + 1)}
</div>
{getAssetType(assetSource.name) === 'audio' && (
<div className="flex absolute flex-col items-center mt-4 ml-2">
<img
key={`audio-${index}`}
alt="audio_icon"
className={clsx('mb-2 ml-1 w-6 h-6 thumbnail')}
src="/audio.png"
/>
<span className="flex self-center ">{assetSource.name}</span>
</div>
)}
{getAssetType(assetSource.name) === 'document' && (
<div className="flex absolute flex-col items-center mt-4 ml-2">
<img
key={`document-${index}`}
alt="document_icon"
className={clsx('mb-2 ml-1 w-6 h-6 thumbnail')}
src="/pdf.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' && (
<div>
<img
key={`image-${index}`}
alt="asset"
className={clsx('px-1 my-1 max-h-24 thumbnail')}
src={URL.createObjectURL(assetSource)}
/>
</div>
)}
{getAssetType(assetSource.name) === 'html' && (
<div className="flex absolute flex-col items-center mt-4 ml-2">
<img
key={`html-${index}`}
alt="html_icon"
className={clsx('mb-2 ml-1 w-10 h-10 thumbnail')}
src="/html.png"
/>
<span className="flex self-center">{assetSource.name.toLowerCase()}</span>
</div>
)}
</label>
</button>
))
}, [page])
const nextPage = () => {
if (totalPages === page) return
setPage(page + 1)
}
const prevPage = () => {
if (page === 1) return
setPage(page - 1)
}
const multiplePrevPage = () => {
if (page - 10 <= 1) return setPage(1)
setPage(page - 10)
}
const multipleNextPage = () => {
if (page + 10 >= totalPages) return setPage(totalPages)
setPage(page + 10)
}
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={multiplePrevPage} type="button">
««
</button>
<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>
<button className="text-white bg-plumbus-light btn" onClick={multipleNextPage} type="button">
»»
</button>
</div>
</div>
)
}