feat: add metadata and preview (#292)
* chore: upload flow uses metadata object and has preview * chore: remove SwarmFile * feat: upload metadata and file preview * feat: add metadata and preview on download * fix: package the meta and preview files * fix: upload websites that are inside a folder (#296) * fix: upload websites that are inside a folder * docs: few comments to clarify what is going on * refactor: decrease local variables and fix state order to detect websites properly Co-authored-by: Cafe137 <aron@aronsoos.com>
This commit is contained in:
@@ -1,99 +1,55 @@
|
||||
import { Box, Grid, Typography } from '@material-ui/core'
|
||||
import { Web } from '@material-ui/icons'
|
||||
import { ReactElement, useEffect, useState } from 'react'
|
||||
import { ReactElement } from 'react'
|
||||
import { File, Folder } from 'react-feather'
|
||||
import { FitImage } from '../../components/FitImage'
|
||||
import { detectIndexHtml, getAssetNameFromFiles, getHumanReadableFileSize } from '../../utils/file'
|
||||
import { SwarmFile } from '../../utils/SwarmFile'
|
||||
import { getHumanReadableFileSize } from '../../utils/file'
|
||||
import { AssetIcon } from './AssetIcon'
|
||||
import { shortenHash } from '../../utils/hash'
|
||||
|
||||
interface Props {
|
||||
assetName?: string
|
||||
files: SwarmFile[]
|
||||
previewUri?: string
|
||||
metadata?: Metadata
|
||||
}
|
||||
|
||||
// TODO: add optional prop for indexDocument when it is already known (e.g. downloading a manifest)
|
||||
|
||||
export function AssetPreview({ assetName, files }: Props): ReactElement {
|
||||
const [previewComponent, setPreviewComponent] = useState<ReactElement | undefined>(undefined)
|
||||
const [previewUri, setPreviewUri] = useState<string | undefined>(undefined)
|
||||
export function AssetPreview({ metadata, previewUri }: Props): ReactElement | null {
|
||||
let previewComponent = <File />
|
||||
let type = metadata?.type
|
||||
|
||||
useEffect(() => {
|
||||
if (files.length === 1) {
|
||||
// single image
|
||||
if (files[0].type.startsWith('image/')) {
|
||||
files[0].arrayBuffer().then(value => {
|
||||
const blob = new Blob([value])
|
||||
setPreviewUri(URL.createObjectURL(blob))
|
||||
})
|
||||
// single non-image
|
||||
} else {
|
||||
setPreviewUri(undefined)
|
||||
setPreviewComponent(<AssetIcon icon={<File />} />)
|
||||
}
|
||||
// collection
|
||||
} else if (detectIndexHtml(files)) {
|
||||
setPreviewUri(undefined)
|
||||
setPreviewComponent(<AssetIcon icon={<Web />} />)
|
||||
} else {
|
||||
setPreviewUri(undefined)
|
||||
setPreviewComponent(<AssetIcon icon={<Folder />} />)
|
||||
}
|
||||
}, [files])
|
||||
|
||||
const getPrimaryText = () => {
|
||||
const name = getAssetNameFromFiles(files)
|
||||
|
||||
if (files.length === 1) {
|
||||
return 'Filename: ' + (assetName || name)
|
||||
}
|
||||
|
||||
return 'Folder name: ' + (assetName || name)
|
||||
if (metadata?.isWebsite) {
|
||||
previewComponent = <Web />
|
||||
type = 'Website'
|
||||
} else if (metadata?.type === 'folder') {
|
||||
previewComponent = <Folder />
|
||||
type = 'Folder'
|
||||
}
|
||||
|
||||
const getKind = () => {
|
||||
if (files.length === 1) {
|
||||
return files[0].type
|
||||
}
|
||||
|
||||
if (detectIndexHtml(files)) {
|
||||
return 'Website'
|
||||
}
|
||||
|
||||
return 'Folder'
|
||||
}
|
||||
|
||||
const isFolder = () => ['Folder', 'Website'].includes(getKind())
|
||||
|
||||
const getSize = () => {
|
||||
const bytes = files.reduce((total, item) => total + item.size, 0)
|
||||
|
||||
return getHumanReadableFileSize(bytes)
|
||||
}
|
||||
|
||||
const size = getSize()
|
||||
|
||||
return (
|
||||
<Box mb={4}>
|
||||
<Box bgcolor="background.paper">
|
||||
<Grid container direction="row">
|
||||
{previewComponent ? (
|
||||
previewComponent
|
||||
) : (
|
||||
{previewUri ? (
|
||||
<FitImage maxWidth="250px" maxHeight="175px" alt="Upload Preview" src={previewUri} />
|
||||
) : (
|
||||
<AssetIcon icon={previewComponent} />
|
||||
)}
|
||||
<Box p={2}>
|
||||
<Typography>{getPrimaryText()}</Typography>
|
||||
<Typography>Kind: {getKind()}</Typography>
|
||||
{size !== '0 bytes' && <Typography>Size: {size}</Typography>}
|
||||
{metadata?.hash && <Typography>Swarm Hash: {shortenHash(metadata.hash)}</Typography>}
|
||||
<Typography>
|
||||
{metadata?.type === 'folder' ? 'Folder Name' : 'Filename'}: {metadata?.name}
|
||||
</Typography>
|
||||
<Typography>Kind: {type}</Typography>
|
||||
{metadata?.size && <Typography>Size: {getHumanReadableFileSize(metadata.size)}</Typography>}
|
||||
</Box>
|
||||
</Grid>
|
||||
</Box>
|
||||
{isFolder() && (
|
||||
{metadata?.type === 'folder' && metadata.count && (
|
||||
<Box mt={0.25} p={2} bgcolor="background.paper">
|
||||
<Grid container justifyContent="space-between" alignItems="center" direction="row">
|
||||
<Typography variant="subtitle2">Folder content</Typography>
|
||||
<Typography variant="subtitle2">{files.length} items</Typography>
|
||||
<Typography variant="subtitle2">{metadata.count} items</Typography>
|
||||
</Grid>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user