From d72f1af36193200f71f5f0e52aef3d68204cc535 Mon Sep 17 00:00:00 2001 From: Timothy Carambat <rambat1010@gmail.com> Date: Fri, 26 Apr 2024 17:41:42 -0700 Subject: [PATCH] Improve uploader experience (#1205) * Improve uploader expierence - Wipe upload container (fadeout) after uploading - debounce fetchKeys by 1s * patch unneded exports --- .../UploadFile/FileUploadProgress/index.jsx | 38 ++++++++++++-- .../Documents/UploadFile/index.jsx | 14 +++--- frontend/src/index.css | 50 +++++++++++++++++++ 3 files changed, 91 insertions(+), 11 deletions(-) diff --git a/frontend/src/components/Modals/MangeWorkspace/Documents/UploadFile/FileUploadProgress/index.jsx b/frontend/src/components/Modals/MangeWorkspace/Documents/UploadFile/FileUploadProgress/index.jsx index e1f4651eb..104d45a16 100644 --- a/frontend/src/components/Modals/MangeWorkspace/Documents/UploadFile/FileUploadProgress/index.jsx +++ b/frontend/src/components/Modals/MangeWorkspace/Documents/UploadFile/FileUploadProgress/index.jsx @@ -7,7 +7,9 @@ import PreLoader from "../../../../../Preloader"; function FileUploadProgressComponent({ slug, + uuid, file, + setFiles, rejected = false, reason = null, onUploadSuccess, @@ -18,6 +20,19 @@ function FileUploadProgressComponent({ const [timerMs, setTimerMs] = useState(10); const [status, setStatus] = useState("pending"); const [error, setError] = useState(""); + const [isFadingOut, setIsFadingOut] = useState(false); + + const fadeOut = (cb) => { + setIsFadingOut(true); + cb?.(); + }; + + const beginFadeOut = () => { + setIsFadingOut(false); + setFiles((prev) => { + return prev.filter((item) => item.uid !== uuid); + }); + }; useEffect(() => { async function uploadFile() { @@ -44,13 +59,22 @@ function FileUploadProgressComponent({ clearInterval(timer); onUploadSuccess(); } + + // Begin fadeout timer to clear uploader queue. + setTimeout(() => { + fadeOut(() => setTimeout(() => beginFadeOut(), 300)); + }, 5000); } !!file && !rejected && uploadFile(); }, []); if (rejected) { return ( - <div className="h-14 px-2 py-2 flex items-center gap-x-4 rounded-lg bg-white/5 border border-white/40"> + <div + className={`${ + isFadingOut ? "file-upload-fadeout" : "file-upload" + } h-14 px-2 py-2 flex items-center gap-x-4 rounded-lg bg-white/5 border border-white/40`} + > <div className="w-6 h-6 flex-shrink-0"> <XCircle className="w-6 h-6 stroke-white bg-red-500 rounded-full p-1 w-full h-full" /> </div> @@ -66,7 +90,11 @@ function FileUploadProgressComponent({ if (status === "failed") { return ( - <div className="h-14 px-2 py-2 flex items-center gap-x-4 rounded-lg bg-white/5 border border-white/40 overflow-y-auto"> + <div + className={`${ + isFadingOut ? "file-upload-fadeout" : "file-upload" + } h-14 px-2 py-2 flex items-center gap-x-4 rounded-lg bg-white/5 border border-white/40 overflow-y-auto`} + > <div className="w-6 h-6 flex-shrink-0"> <XCircle className="w-6 h-6 stroke-white bg-red-500 rounded-full p-1 w-full h-full" /> </div> @@ -81,7 +109,11 @@ function FileUploadProgressComponent({ } return ( - <div className="h-14 px-2 py-2 flex items-center gap-x-4 rounded-lg bg-white/5 border border-white/40"> + <div + className={`${ + isFadingOut ? "file-upload-fadeout" : "file-upload" + } h-14 px-2 py-2 flex items-center gap-x-4 rounded-lg bg-white/5 border border-white/40`} + > <div className="w-6 h-6 flex-shrink-0"> {status !== "complete" ? ( <div className="flex items-center justify-center"> diff --git a/frontend/src/components/Modals/MangeWorkspace/Documents/UploadFile/index.jsx b/frontend/src/components/Modals/MangeWorkspace/Documents/UploadFile/index.jsx index e57997a83..8996829c1 100644 --- a/frontend/src/components/Modals/MangeWorkspace/Documents/UploadFile/index.jsx +++ b/frontend/src/components/Modals/MangeWorkspace/Documents/UploadFile/index.jsx @@ -6,6 +6,7 @@ import { useDropzone } from "react-dropzone"; import { v4 } from "uuid"; import FileUploadProgress from "./FileUploadProgress"; import Workspace from "../../../../../models/workspace"; +import debounce from "lodash.debounce"; export default function UploadFile({ workspace, @@ -39,14 +40,9 @@ export default function UploadFile({ setFetchingUrl(false); }; - const handleUploadSuccess = () => { - fetchKeys(true); - showToast("File uploaded successfully", "success", { clear: true }); - }; - - const handleUploadError = (message) => { - showToast(`Error uploading file: ${message}`, "error"); - }; + // Don't spam fetchKeys, wait 1s between calls at least. + const handleUploadSuccess = debounce(() => fetchKeys(true), 1000); + const handleUploadError = (_msg) => null; // stubbed. const onDrop = async (acceptedFiles, rejections) => { const newAccepted = acceptedFiles.map((file) => { @@ -115,6 +111,8 @@ export default function UploadFile({ <FileUploadProgress key={file.uid} file={file.file} + uuid={file.uid} + setFiles={setFiles} slug={workspace.slug} rejected={file?.rejected} reason={file?.reason} diff --git a/frontend/src/index.css b/frontend/src/index.css index e5066f679..35159b3f1 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -692,3 +692,53 @@ does not extend the close button beyond the viewport. */ .text-tremor-content { padding-bottom: 10px; } + +.file-upload { + -webkit-animation: fadein 0.3s linear forwards; + animation: fadein 0.3s linear forwards; +} + +.file-upload-fadeout { + -webkit-animation: fadeout 0.3s linear forwards; + animation: fadeout 0.3s linear forwards; +} + +@-webkit-keyframes fadein { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes fadein { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@-webkit-keyframes fadeout { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@keyframes fadeout { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} -- GitLab