fix: state and rendering
This commit is contained in:
parent
b0809c65f3
commit
94406b7f13
|
@ -54,7 +54,17 @@ export const DashboardLayout = ({ children }: React.PropsWithChildren<{}>) => {
|
||||||
<p>Privacy</p>
|
<p>Privacy</p>
|
||||||
<p>Ownership</p>
|
<p>Ownership</p>
|
||||||
</span>
|
</span>
|
||||||
<UploadFileModal />
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button size={"lg"} className="w-[calc(100%-3rem)] font-semibold">
|
||||||
|
<CloudUploadIcon className="w-6 h-6 -ml-3 mr-4" />
|
||||||
|
Upload Files
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent>
|
||||||
|
<UploadFileForm />
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
|
@ -89,97 +99,92 @@ export const DashboardLayout = ({ children }: React.PropsWithChildren<{}>) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const UploadFileModal = () => {
|
const UploadFileForm = () => {
|
||||||
const { getRootProps, getInputProps, files, upload, removeFile, cancelAll } =
|
const {
|
||||||
useUppy({
|
getRootProps,
|
||||||
uploader: "tus",
|
getInputProps,
|
||||||
endpoint: import.meta.env.VITE_PUBLIC_TUS_ENDPOINT
|
getFiles,
|
||||||
})
|
upload,
|
||||||
|
state,
|
||||||
|
removeFile,
|
||||||
|
cancelAll
|
||||||
|
} = useUppy({
|
||||||
|
uploader: "tus",
|
||||||
|
endpoint: import.meta.env.VITE_PUBLIC_TUS_ENDPOINT
|
||||||
|
})
|
||||||
|
|
||||||
const isUploading =
|
console.log({ state, files: getFiles() })
|
||||||
files.length > 0
|
|
||||||
? files.map((file) => file.progress?.uploadStarted != null).includes(true)
|
const isUploading = state === "uploading"
|
||||||
: false
|
const isCompleted = state === "completed"
|
||||||
const isCompleted =
|
const hasStarted = state !== "idle" && state !== "initializing"
|
||||||
files.length > 0
|
|
||||||
? files
|
|
||||||
.map((file) => file.progress?.uploadComplete)
|
|
||||||
.reduce((acc, cur) => acc && cur, true)
|
|
||||||
: false
|
|
||||||
const hasStarted = isUploading || isCompleted
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog>
|
<>
|
||||||
<DialogTrigger asChild>
|
<DialogHeader className="mb-6">
|
||||||
<Button size={"lg"} className="w-[calc(100%-3rem)] font-semibold">
|
<DialogTitle>Upload Files</DialogTitle>
|
||||||
<CloudUploadIcon className="w-6 h-6 -ml-3 mr-4" />
|
</DialogHeader>
|
||||||
Upload Files
|
{!hasStarted ? (
|
||||||
</Button>
|
<div
|
||||||
</DialogTrigger>
|
{...getRootProps()}
|
||||||
<DialogContent>
|
className="border border-border rounded text-primary-2 bg-primary-dark h-48 flex flex-col items-center justify-center"
|
||||||
<DialogHeader className="mb-6">
|
>
|
||||||
<DialogTitle>Upload Files</DialogTitle>
|
<input
|
||||||
</DialogHeader>
|
hidden
|
||||||
{!hasStarted ? (
|
aria-hidden
|
||||||
<div
|
name="uppyFiles[]"
|
||||||
{...getRootProps()}
|
key={new Date().toISOString()}
|
||||||
className="border border-border rounded text-primary-2 bg-primary-dark h-48 flex flex-col items-center justify-center"
|
multiple
|
||||||
>
|
{...getInputProps()}
|
||||||
<input
|
/>
|
||||||
hidden
|
<CloudUploadIcon className="w-24 h-24 stroke stroke-primary-dark" />
|
||||||
aria-hidden
|
<p>Drag & Drop Files or Browse</p>
|
||||||
name="uppyFiles[]"
|
|
||||||
key={new Date().toISOString()}
|
|
||||||
multiple
|
|
||||||
{...getInputProps()}
|
|
||||||
/>
|
|
||||||
<CloudUploadIcon className="w-24 h-24 stroke stroke-primary-dark" />
|
|
||||||
<p>Drag & Drop Files or Browse</p>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<div className="w-full space-y-3 max-h-48 overflow-y-auto">
|
|
||||||
{files.map((file) => (
|
|
||||||
<UploadFileItem
|
|
||||||
key={file.id}
|
|
||||||
file={file}
|
|
||||||
onRemove={(id) => {
|
|
||||||
removeFile(id)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
{hasStarted ? (
|
<div className="w-full space-y-3 max-h-48 overflow-y-auto">
|
||||||
<div className="flex flex-col items-center gap-y-2 w-full text-primary-1">
|
{getFiles().map((file) => (
|
||||||
<CloudCheckIcon className="w-32 h-32" />
|
<UploadFileItem
|
||||||
{isCompleted
|
key={file.id}
|
||||||
? "Upload completed"
|
file={file}
|
||||||
: `${files.length} being uploaded`}
|
onRemove={(id) => {
|
||||||
</div>
|
removeFile(id)
|
||||||
) : null}
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
{hasStarted ? (
|
{hasStarted ? (
|
||||||
<DialogClose asChild onClick={cancelAll}>
|
<div className="flex flex-col items-center gap-y-2 w-full text-primary-1">
|
||||||
<Button size={"lg"} className="mt-6">
|
<CloudCheckIcon className="w-32 h-32" />
|
||||||
Cancel
|
{isCompleted
|
||||||
</Button>
|
? "Upload completed"
|
||||||
</DialogClose>
|
: `${getFiles().length} files being uploaded`}
|
||||||
) : (
|
</div>
|
||||||
<Button size={"lg"} className="mt-6" onClick={upload}>
|
) : null}
|
||||||
Upload
|
|
||||||
|
{isUploading ? (
|
||||||
|
<DialogClose asChild onClick={cancelAll}>
|
||||||
|
<Button size={"lg"} className="mt-6">
|
||||||
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
</DialogClose>
|
||||||
|
) : null}
|
||||||
|
|
||||||
{hasStarted && isCompleted ? (
|
{isCompleted ? (
|
||||||
<DialogClose asChild>
|
<DialogClose asChild>
|
||||||
<Button size={"lg"} className="mt-6">
|
<Button size={"lg"} className="mt-6">
|
||||||
Close
|
Close
|
||||||
</Button>
|
</Button>
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
) : null}
|
) : null}
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
{!hasStarted && !isCompleted && !isUploading ? (
|
||||||
|
<Button size={"lg"} className="mt-6" onClick={upload}>
|
||||||
|
Upload
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,10 @@ export function useUppy({
|
||||||
(element: HTMLElement | null) => _setTargetRef(element),
|
(element: HTMLElement | null) => _setTargetRef(element),
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
const [state, setState] = useState<State>()
|
const [uppyState, setUppyState] = useState<State>()
|
||||||
|
const [state, setState] = useState<
|
||||||
|
"completed" | "idle" | "initializing" | "error" | "uploading"
|
||||||
|
>("initializing")
|
||||||
|
|
||||||
const [inputProps, setInputProps] = useState<
|
const [inputProps, setInputProps] = useState<
|
||||||
| {
|
| {
|
||||||
|
@ -71,7 +74,7 @@ export function useUppy({
|
||||||
[targetRef, uppyInstance]
|
[targetRef, uppyInstance]
|
||||||
)
|
)
|
||||||
const cancelAll = useCallback(
|
const cancelAll = useCallback(
|
||||||
() => uppyInstance.current?.cancelAll(),
|
() => uppyInstance.current?.cancelAll({ reason: "user" }),
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
[targetRef, uppyInstance]
|
[targetRef, uppyInstance]
|
||||||
)
|
)
|
||||||
|
@ -116,36 +119,53 @@ export function useUppy({
|
||||||
uppy.on("complete", (result) => {
|
uppy.on("complete", (result) => {
|
||||||
if (result.failed.length === 0) {
|
if (result.failed.length === 0) {
|
||||||
console.log("Upload successful üòÄ")
|
console.log("Upload successful üòÄ")
|
||||||
|
setState("completed")
|
||||||
} else {
|
} else {
|
||||||
console.warn("Upload failed üòû")
|
console.warn("Upload failed üòû")
|
||||||
|
setState("error")
|
||||||
}
|
}
|
||||||
console.log("successful files:", result.successful)
|
console.log("successful files:", result.successful)
|
||||||
console.log("failed files:", result.failed)
|
console.log("failed files:", result.failed)
|
||||||
})
|
})
|
||||||
|
|
||||||
const setStateCb = () => {
|
const setStateCb = (event: (typeof LISTENING_EVENTS)[number]) => {
|
||||||
setState(uppy.getState())
|
switch (event) {
|
||||||
|
case "upload":
|
||||||
|
setState("uploading")
|
||||||
|
break
|
||||||
|
case "upload-error":
|
||||||
|
setState("error")
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
setUppyState(uppy.getState())
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const event of LISTENING_EVENTS) {
|
for (const event of LISTENING_EVENTS) {
|
||||||
uppy.on(event, setStateCb)
|
uppy.on(event, function cb() {
|
||||||
|
setStateCb(event)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
setState("idle")
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
for (const event of ["complete", ...LISTENING_EVENTS]) {
|
// for (const event of ["complete", ...LISTENING_EVENTS]) {
|
||||||
uppyInstance.current?.off(
|
// uppyInstance.current?.off(
|
||||||
event as "complete" & keyof typeof LISTENING_EVENTS,
|
// event as "complete" & keyof typeof LISTENING_EVENTS,
|
||||||
//@ts-expect-error -- huh? typescript wtf
|
// //@ts-expect-error -- huh? typescript wtf
|
||||||
setStateCb
|
// setStateCb
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
uppyInstance.current?.close()
|
// uppyInstance.current?.cancelAll({ reason: "unmount" })
|
||||||
uppyInstance.current = undefined
|
// uppyInstance.current?.logout()
|
||||||
|
// uppyInstance.current?.close()
|
||||||
|
// uppyInstance.current = undefined
|
||||||
}
|
}
|
||||||
}, [targetRef, endpoint, uploader])
|
}, [targetRef, endpoint, uploader])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
files: uppyInstance.current?.getFiles() ?? [],
|
getFiles: () => uppyInstance.current?.getFiles() ?? [],
|
||||||
error: uppyInstance.current?.getState,
|
error: uppyInstance.current?.getState,
|
||||||
state,
|
state,
|
||||||
upload: () =>
|
upload: () =>
|
||||||
|
@ -154,6 +174,6 @@ export function useUppy({
|
||||||
getInputProps: () => inputProps,
|
getInputProps: () => inputProps,
|
||||||
getRootProps,
|
getRootProps,
|
||||||
removeFile,
|
removeFile,
|
||||||
cancelAll,
|
cancelAll
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue