From fd869698f5fe09bafe448bf7ac396a749dccf45b Mon Sep 17 00:00:00 2001 From: spencerwooo Date: Wed, 15 Dec 2021 17:02:06 +0800 Subject: [PATCH] fix a few style issues with toast and checkbox --- components/FileListing.tsx | 83 ++++++++++++++++++++------------------ components/Navbar.tsx | 2 +- utils/tools.ts | 13 +++++- 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/components/FileListing.tsx b/components/FileListing.tsx index 33b5501..4a86a49 100644 --- a/components/FileListing.tsx +++ b/components/FileListing.tsx @@ -4,7 +4,7 @@ import emojiRegex from 'emoji-regex' import { useClipboard } from 'use-clipboard-copy' import { ParsedUrlQuery } from 'querystring' -import { FunctionComponent, MouseEventHandler, useEffect, useRef, useState } from 'react' +import { FunctionComponent, MouseEventHandler, SetStateAction, useEffect, useRef, useState } from 'react' import { ImageDecorator } from 'react-viewer/lib/ViewerProps' import { useRouter } from 'next/router' @@ -12,7 +12,7 @@ import dynamic from 'next/dynamic' import { getExtension, getFileIcon, hasKey } from '../utils/getFileIcon' import { extensions, preview } from '../utils/getPreviewType' -import { getBaseUrl, saveFiles, useProtectedSWRInfinite } from '../utils/tools' +import { getBaseUrl, downloadMultipleFiles, useProtectedSWRInfinite } from '../utils/tools' import { VideoPreview } from './previews/VideoPreview' import { AudioPreview } from './previews/AudioPreview' @@ -100,9 +100,13 @@ const FileListItem: FunctionComponent<{ } const Checkbox: FunctionComponent<{ - checked: 0 | 1 | 2, onChange: () => void, title: string, indeterminate?: boolean + checked: 0 | 1 | 2 + onChange: () => void + title: string + indeterminate?: boolean }> = ({ checked, onChange, title, indeterminate }) => { const ref = useRef(null) + useEffect(() => { if (ref.current) { ref.current.checked = Boolean(checked) @@ -111,7 +115,8 @@ const Checkbox: FunctionComponent<{ } } }, [ref, checked, indeterminate]) - const handleClick: MouseEventHandler = (e) => { + + const handleClick: MouseEventHandler = e => { if (ref.current) { if (e.target === ref.current) { e.stopPropagation() @@ -223,10 +228,11 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = const genTotalSelected = (selected: { [key: string]: boolean }) => { const selectInfo = getFiles().map((c: any) => Boolean(selected[c.id])) const [hasT, hasF] = [selectInfo.some(i => i), selectInfo.some(i => !i)] - return hasT && hasF ? 1 : (!hasF ? 2 : 0) + return hasT && hasF ? 1 : !hasF ? 2 : 0 } + const toggleItemSelected = (id: string) => { - let val + let val: SetStateAction<{ [key: string]: boolean }> if (selected[id]) { val = { ...selected } delete val[id] @@ -236,6 +242,7 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = setSelected(val) setTotalSelected(genTotalSelected(val)) } + const toggleTotalSelected = () => { if (genTotalSelected(selected) == 2) { setSelected({}) @@ -248,11 +255,12 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = // Selected file download const handleSelectedDownload = () => { - const folderName = path.substr(path.lastIndexOf('/') + 1) - const folder = folderName ? folderName : undefined + const folderName = path.substring(path.lastIndexOf('/') + 1) + const folder = folderName ? decodeURIComponent(folderName) : undefined const files = getFiles() .filter((c: any) => selected[c.id]) .map((c: any) => ({ name: c.name, url: c['@microsoft.graph.downloadUrl'] })) + if (files.length == 1) { const el = document.createElement('a') el.style.display = 'none' @@ -262,22 +270,24 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = el.remove() } else if (files.length > 1) { setTotalGenerating(true) - const toastId = toast.loading('Downloading selected files. This may be slow...') - saveFiles(files, folder).then(() => { - setTotalGenerating(false) - toast.dismiss(toastId) - toast.success('Finished to download selected files.') - }).catch(() => { - setTotalGenerating(false) - toast.dismiss(toastId) - toast.error('Failed to download selected files.') - }) + const toastId = toast.loading('Downloading selected files. Refresh to cancle, this may take some time...') + downloadMultipleFiles(files, folder) + .then(() => { + setTotalGenerating(false) + toast.dismiss(toastId) + toast.success('Finished downloading selected files.') + }) + .catch(() => { + setTotalGenerating(false) + toast.dismiss(toastId) + toast.error('Failed to download selected files.') + }) } } return (
-
+
Name
Last Modified
Size
@@ -288,14 +298,10 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = checked={totalSelected} onChange={toggleTotalSelected} indeterminate={true} - title={"Select files"} + title={'Select files'} /> {totalGenerating ? ( - + = ({ query }) = /> - ) : (totalSelected ? ( + ) : totalSelected ? ( = ({ query }) = > - ) : '')} + ) : ( + '' + )}
- + {imagesInFolder.length !== 0 && ( = ({ query }) = render: , onClick: i => { clipboard.copy(i.alt ? `${getBaseUrl()}/api?path=${path + '/' + i.alt}&raw=true` : '') - toast.success('Copied image permanent link to clipboard.') + toast('Copied image permanent link to clipboard.', { icon: '👌' }) }, }, ]) @@ -395,7 +396,7 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = className="hover:bg-gray-300 dark:hover:bg-gray-600 p-2 rounded cursor-pointer" onClick={() => { clipboard.copy(`${getBaseUrl()}${path === '/' ? '' : path}/${encodeURIComponent(c.name)}`) - toast.success('Copied folder permalink.') + toast('Copied folder permalink.', { icon: '👌' }) }} > @@ -407,7 +408,9 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = title="Copy raw file permalink" className="hover:bg-gray-300 dark:hover:bg-gray-600 p-2 rounded cursor-pointer" onClick={() => { - clipboard.copy(`${getBaseUrl()}/api?path=${path === '/' ? '' : path}/${encodeURIComponent(c.name)}&raw=true`) + clipboard.copy( + `${getBaseUrl()}/api?path=${path === '/' ? '' : path}/${encodeURIComponent(c.name)}&raw=true` + ) toast.success('Copied raw file permalink.') }} > @@ -423,7 +426,9 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = )}
- {c.folder || c.name === '.password' ? '' : ( + {c.folder || c.name === '.password' ? ( + '' + ) : ( toggleItemSelected(c.id)} diff --git a/components/Navbar.tsx b/components/Navbar.tsx index 5003b23..c5bef6e 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -42,7 +42,7 @@ const Navbar = () => { return (
-
+
diff --git a/utils/tools.ts b/utils/tools.ts index e134db5..b97de21 100644 --- a/utils/tools.ts +++ b/utils/tools.ts @@ -130,16 +130,25 @@ export const matchProtectedRoute = (route: string) => { * @param files Files to be downloaded * @param folder Optional folder name to hold files, otherwise flatten files in the zip */ -export const saveFiles = async (files: { name: string, url: string }[], folder?: string) => { +export const downloadMultipleFiles = async (files: { name: string; url: string }[], folder?: string) => { const zip = new JSZip() const dir = folder ? zip.folder(folder)! : zip + + // Add selected file blobs to zip files.forEach(({ name, url }) => { - dir.file(name, fetch(url).then(r => r.blob())) + dir.file( + name, + fetch(url).then(r => r.blob()) + ) }) + + // Create zip file and prepare for download const b = await dir.generateAsync({ type: 'blob' }) const el = document.createElement('a') el.style.display = 'none' document.body.appendChild(el) + + // Download zip file const bUrl = window.URL.createObjectURL(b) el.href = bUrl el.download = folder ? folder + '.zip' : 'download.zip'