From b72a770ec939430f8ab4731c48885addd0bc0ce3 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Fri, 10 Apr 2020 13:57:24 -0700 Subject: [PATCH] Don't execute unnecessary HTTP requests when browing a file directory --- .../server/files/FileManagerBreadcrumbs.tsx | 13 ++++--------- .../server/files/FileManagerContainer.tsx | 6 +++--- .../components/server/files/FileObjectRow.tsx | 8 ++++---- resources/scripts/helpers.ts | 2 ++ resources/scripts/routers/ServerRouter.tsx | 2 +- resources/scripts/state/server/files.ts | 5 +++-- 6 files changed, 17 insertions(+), 19 deletions(-) diff --git a/resources/scripts/components/server/files/FileManagerBreadcrumbs.tsx b/resources/scripts/components/server/files/FileManagerBreadcrumbs.tsx index bbe08149e..5e595a2e5 100644 --- a/resources/scripts/components/server/files/FileManagerBreadcrumbs.tsx +++ b/resources/scripts/components/server/files/FileManagerBreadcrumbs.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react'; import { ServerContext } from '@/state/server'; -import { NavLink, useParams } from 'react-router-dom'; +import { NavLink } from 'react-router-dom'; +import { cleanDirectoryPath } from '@/helpers'; interface Props { withinFileEditor?: boolean; @@ -8,21 +9,17 @@ interface Props { } export default ({ withinFileEditor, isNewFile }: Props) => { - const { action } = useParams(); const [ file, setFile ] = useState(null); const id = ServerContext.useStoreState(state => state.server.data!.id); const directory = ServerContext.useStoreState(state => state.files.directory); - const setDirectory = ServerContext.useStoreActions(actions => actions.files.setDirectory); useEffect(() => { - const parts = window.location.hash.replace(/^#(\/)*/, '/').split('/'); + const parts = cleanDirectoryPath(window.location.hash).split('/'); if (withinFileEditor && !isNewFile) { setFile(parts.pop() || null); } - - setDirectory(parts.join('/')); - }, [ withinFileEditor, isNewFile, setDirectory ]); + }, [ withinFileEditor, isNewFile ]); const breadcrumbs = (): { name: string; path?: string }[] => directory.split('/') .filter(directory => !!directory) @@ -39,7 +36,6 @@ export default ({ withinFileEditor, isNewFile }: Props) => { /home/ setDirectory('/')} className={'px-1 text-neutral-200 no-underline hover:text-neutral-100'} > container @@ -50,7 +46,6 @@ export default ({ withinFileEditor, isNewFile }: Props) => { setDirectory(crumb.path!)} className={'px-1 text-neutral-200 no-underline hover:text-neutral-100'} > {crumb.name} diff --git a/resources/scripts/components/server/files/FileManagerContainer.tsx b/resources/scripts/components/server/files/FileManagerContainer.tsx index 41adcd8e2..7328a94aa 100644 --- a/resources/scripts/components/server/files/FileManagerContainer.tsx +++ b/resources/scripts/components/server/files/FileManagerContainer.tsx @@ -22,20 +22,20 @@ export default () => { const [ loading, setLoading ] = useState(true); const { addError, clearFlashes } = useStoreActions((actions: Actions) => actions.flashes); const { id } = ServerContext.useStoreState(state => state.server.data!); - const { contents: files, directory } = ServerContext.useStoreState(state => state.files); + const { contents: files } = ServerContext.useStoreState(state => state.files); const { getDirectoryContents } = ServerContext.useStoreActions(actions => actions.files); useEffect(() => { setLoading(true); clearFlashes(); - getDirectoryContents(window.location.hash.replace(/^#(\/)*/, '/')) + getDirectoryContents(window.location.hash) .then(() => setLoading(false)) .catch(error => { console.error(error.message, { error }); addError({ message: httpErrorToHuman(error), key: 'files' }); }); - }, [ directory ]); + }, []); return (
diff --git a/resources/scripts/components/server/files/FileObjectRow.tsx b/resources/scripts/components/server/files/FileObjectRow.tsx index 76eac19bf..c393ae35f 100644 --- a/resources/scripts/components/server/files/FileObjectRow.tsx +++ b/resources/scripts/components/server/files/FileObjectRow.tsx @@ -2,7 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFileImport } from '@fortawesome/free-solid-svg-icons/faFileImport'; import { faFileAlt } from '@fortawesome/free-solid-svg-icons/faFileAlt'; import { faFolder } from '@fortawesome/free-solid-svg-icons/faFolder'; -import { bytesToHuman } from '@/helpers'; +import { bytesToHuman, cleanDirectoryPath } from '@/helpers'; import differenceInHours from 'date-fns/difference_in_hours'; import format from 'date-fns/format'; import distanceInWordsToNow from 'date-fns/distance_in_words_to_now'; @@ -16,7 +16,7 @@ import useRouter from 'use-react-router'; export default ({ file }: { file: FileObject }) => { const directory = ServerContext.useStoreState(state => state.files.directory); const setDirectory = ServerContext.useStoreActions(actions => actions.files.setDirectory); - const { match } = useRouter(); + const { match, history } = useRouter(); return (
{ `} > { // Don't rely on the onClick to work with the generated URL. Because of the way this @@ -38,7 +38,7 @@ export default ({ file }: { file: FileObject }) => { if (!file.isFile) { e.preventDefault(); - window.location.hash = `#${directory}/${file.name}`; + history.push(`#${cleanDirectoryPath(`${directory}/${file.name}`)}`); setDirectory(`${directory}/${file.name}`); } }} diff --git a/resources/scripts/helpers.ts b/resources/scripts/helpers.ts index ad9008d17..f8cf94848 100644 --- a/resources/scripts/helpers.ts +++ b/resources/scripts/helpers.ts @@ -11,3 +11,5 @@ export function bytesToHuman (bytes: number): string { export const bytesToMegabytes = (bytes: number) => Math.floor(bytes / 1000 / 1000); export const randomInt = (low: number, high: number) => Math.floor(Math.random() * (high - low) + low); + +export const cleanDirectoryPath = (path: string) => path.replace(/(^#\/*)|(\/(\/*))|(^$)/g, '/'); diff --git a/resources/scripts/routers/ServerRouter.tsx b/resources/scripts/routers/ServerRouter.tsx index c35614d06..48d3e6db6 100644 --- a/resources/scripts/routers/ServerRouter.tsx +++ b/resources/scripts/routers/ServerRouter.tsx @@ -64,7 +64,7 @@ const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>)
: - + { - state.directory = payload.length === 0 ? '/' : payload; + state.directory = cleanDirectoryPath(payload) }), };