diff --git a/resources/scripts/components/server/files/FileManagerContainer.tsx b/resources/scripts/components/server/files/FileManagerContainer.tsx index 8003a8d9c..7d1f5403f 100644 --- a/resources/scripts/components/server/files/FileManagerContainer.tsx +++ b/resources/scripts/components/server/files/FileManagerContainer.tsx @@ -5,36 +5,28 @@ import { Actions, useStoreActions } from 'easy-peasy'; import { ApplicationStore } from '@/state'; import { httpErrorToHuman } from '@/api/http'; import { CSSTransition } from 'react-transition-group'; -import { Link } from 'react-router-dom'; import Spinner from '@/components/elements/Spinner'; import FileObjectRow from '@/components/server/files/FileObjectRow'; export default () => { const [ loading, setLoading ] = useState(true); const { addError, clearFlashes } = useStoreActions((actions: Actions) => actions.flashes); - const { contents: files } = ServerContext.useStoreState(state => state.files); - const getDirectoryContents = ServerContext.useStoreActions(actions => actions.files.getDirectoryContents); - - const urlDirectory = window.location.hash.replace(/^#(\/)+/, '/'); + const { contents: files, directory } = ServerContext.useStoreState(state => state.files); + const { setDirectory, getDirectoryContents } = ServerContext.useStoreActions(actions => actions.files); const load = () => { setLoading(true); clearFlashes(); - getDirectoryContents(urlDirectory) + getDirectoryContents(window.location.hash.replace(/^#(\/)*/, '/')) .then(() => setLoading(false)) .catch(error => { - if (error.response && error.response.status === 404) { - window.location.hash = '#/'; - return; - } - console.error(error.message, { error }); addError({ message: httpErrorToHuman(error), key: 'files' }); }); }; - const breadcrumbs = (): { name: string; path?: string }[] => urlDirectory.split('/') + const breadcrumbs = (): { name: string; path?: string }[] => directory.split('/') .filter(directory => !!directory) .map((directory, index, dirs) => { if (index === dirs.length - 1) { @@ -44,27 +36,32 @@ export default () => { return { name: directory, path: `/${dirs.slice(0, index + 1).join('/')}` }; }); - useEffect(() => load(), []); + useEffect(() => load(), [ directory ]); return (
- +
/home/ - + setDirectory('/')} + className={'px-1 text-neutral-200 no-underline hover:text-neutral-100'} + > container - / + / { breadcrumbs().map((crumb, index) => ( crumb.path ? - setDirectory(crumb.path!)} className={'px-1 text-neutral-200 no-underline hover:text-neutral-100'} > {crumb.name} - / + / : {crumb.name} diff --git a/resources/scripts/components/server/files/FileObjectRow.tsx b/resources/scripts/components/server/files/FileObjectRow.tsx index 7980c425a..55fadbf3c 100644 --- a/resources/scripts/components/server/files/FileObjectRow.tsx +++ b/resources/scripts/components/server/files/FileObjectRow.tsx @@ -13,6 +13,7 @@ import { ServerContext } from '@/state/server'; export default ({ file }: { file: FileObject }) => { const directory = ServerContext.useStoreState(state => state.files.directory); + const setDirectory = ServerContext.useStoreActions(actions => actions.files.setDirectory); return (
{ href={file.isFile ? undefined : `#${directory}/${file.name}`} className={'flex flex-1 text-neutral-300 no-underline'} onClick={e => { - file.isFile && e.preventDefault(); + e.preventDefault(); + + // Don't rely on the onClick to work with the generated URL. Because of the way this + // component re-renders you'll get redirected into a nested directory structure since + // it'll cause the directory variable to update right away when you click. + // + // Just trust me future me, leave this be. + if (!file.isFile) { + window.location.hash = `#${directory}/${file.name}`; + setDirectory(`${directory}/${file.name}`); + } }} >
diff --git a/resources/scripts/state/server/files.ts b/resources/scripts/state/server/files.ts index 8d9814484..cae75623c 100644 --- a/resources/scripts/state/server/files.ts +++ b/resources/scripts/state/server/files.ts @@ -13,7 +13,7 @@ export interface ServerFileStore { } const files: ServerFileStore = { - directory: '', + directory: '/', contents: [], getDirectoryContents: thunk(async (actions, payload, { getStoreState }) => {