f4013142af
* 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>
72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
|
|
import { createContext, ReactChild, ReactElement, useState, useEffect } from 'react'
|
|
import { getMetadata } from '../utils/file'
|
|
import { resize } from '../utils/image'
|
|
import { PREVIEW_DIMENSIONS } from '../constants'
|
|
|
|
export type UploadOrigin = { origin: 'UPLOAD' | 'FEED'; uuid?: string }
|
|
|
|
export const defaultUploadOrigin: UploadOrigin = { origin: 'UPLOAD' }
|
|
|
|
interface ContextInterface {
|
|
files: FilePath[]
|
|
setFiles: (files: FilePath[]) => void
|
|
uploadOrigin: UploadOrigin
|
|
setUploadOrigin: (uploadOrigin: UploadOrigin) => void
|
|
metadata?: Metadata
|
|
previewUri?: string
|
|
previewBlob?: Blob
|
|
}
|
|
|
|
const initialValues: ContextInterface = {
|
|
files: [],
|
|
setFiles: () => {},
|
|
uploadOrigin: defaultUploadOrigin,
|
|
setUploadOrigin: () => {},
|
|
}
|
|
|
|
export const Context = createContext<ContextInterface>(initialValues)
|
|
export const Consumer = Context.Consumer
|
|
|
|
interface Props {
|
|
children: ReactChild
|
|
}
|
|
|
|
export function Provider({ children }: Props): ReactElement {
|
|
const [files, setFiles] = useState<FilePath[]>(initialValues.files)
|
|
const [uploadOrigin, setUploadOrigin] = useState<UploadOrigin>(initialValues.uploadOrigin)
|
|
const [metadata, setMetadata] = useState<Metadata | undefined>(undefined)
|
|
const [previewUri, setPreviewUri] = useState<string | undefined>(undefined)
|
|
const [previewBlob, setPreviewBlob] = useState<Blob | undefined>(undefined)
|
|
|
|
useEffect(() => {
|
|
setMetadata(getMetadata(files))
|
|
|
|
if (previewUri) {
|
|
URL.revokeObjectURL(previewUri) // Clear the preview from memory
|
|
setPreviewUri(undefined)
|
|
setPreviewBlob(undefined)
|
|
}
|
|
|
|
if (files.length !== 1 || !files[0].type.startsWith('image')) return
|
|
|
|
resize(files[0], PREVIEW_DIMENSIONS.maxWidth, PREVIEW_DIMENSIONS.maxHeight).then(blob => {
|
|
setPreviewUri(URL.createObjectURL(blob)) // NOTE: Until it is cleared with URL.revokeObjectURL, the file stays allocated in memory
|
|
setPreviewBlob(blob)
|
|
})
|
|
|
|
return () => {
|
|
if (previewUri) {
|
|
URL.revokeObjectURL(previewUri)
|
|
}
|
|
}
|
|
}, [files]) // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
return (
|
|
<Context.Provider value={{ files, setFiles, uploadOrigin, setUploadOrigin, metadata, previewUri, previewBlob }}>
|
|
{children}
|
|
</Context.Provider>
|
|
)
|
|
}
|