From fc32dd79cc86f64cf25241443cca3edcd8f6ccfc Mon Sep 17 00:00:00 2001 From: Stefan Forstenlechner Date: Wed, 21 Aug 2024 21:50:26 +0200 Subject: [PATCH] Refactor ImageGalleryLayout Split out main component Move useEffect to corresponding component --- .../src/ImageGallery/ImageGalleryDrawer.tsx | 13 ++- .../src/ImageGallery/ImageGalleryMain.tsx | 89 +++++++++++++++ .../src/ImageGalleryLayout.tsx | 104 +----------------- picture-gallery-client/src/index.tsx | 2 +- 4 files changed, 106 insertions(+), 102 deletions(-) create mode 100644 picture-gallery-client/src/ImageGallery/ImageGalleryMain.tsx diff --git a/picture-gallery-client/src/ImageGallery/ImageGalleryDrawer.tsx b/picture-gallery-client/src/ImageGallery/ImageGalleryDrawer.tsx index 7aa3675..7d966e9 100644 --- a/picture-gallery-client/src/ImageGallery/ImageGalleryDrawer.tsx +++ b/picture-gallery-client/src/ImageGallery/ImageGalleryDrawer.tsx @@ -132,16 +132,25 @@ const GenerateTreeView = ({ root }: { root: Folders }) => { export const ImageGalleryDrawer = ({ open, drawerWidth, - folders, handleDrawerToggle, }: { open: boolean; drawerWidth: number; - folders: Folders | undefined; handleDrawerToggle: () => void; }) => { const theme = useTheme(); const smallScreen = !useMediaQuery(smallScreenMediaQuery); + const [folders, setFolders] = useState(undefined); + + useEffect(() => { + fetch("/directories", { + headers: { + Accept: "application/json", + }, + }) + .then((res) => res.json()) + .then((data) => setFolders(data)); + }, []); const drawerContent = folders != undefined ? ( diff --git a/picture-gallery-client/src/ImageGallery/ImageGalleryMain.tsx b/picture-gallery-client/src/ImageGallery/ImageGalleryMain.tsx new file mode 100644 index 0000000..de3da49 --- /dev/null +++ b/picture-gallery-client/src/ImageGallery/ImageGalleryMain.tsx @@ -0,0 +1,89 @@ +import React, { useEffect, useState } from "react"; +import Box from "@mui/material/Box"; +import { useLocation, useNavigate } from "react-router-dom"; +import Toolbar from "@mui/material/Toolbar"; +import { Chip, Divider } from "@mui/material"; +import { FolderPreview, ImageWithThumbnail } from "./models"; +import { Spinner } from "./Spinner"; +import { FolderGallery } from "./FolderGallery"; +import { ImageGallery } from "./ImageGallery"; + +export const ImageGalleryMain = ({ + setError, +}: { + setError: (_: boolean) => void; +}) => { + const [imagesLoaded, setImagesLoaded] = useState(false); + const [images, setImages] = useState([]); + + const [foldersPreview, setFoldersPreview] = useState< + FolderPreview[] | undefined + >([]); + const location = useLocation(); + const navigate = useNavigate(); + + useEffect(() => { + setFoldersPreview(undefined); + setImages([]); + setError(false); + setImagesLoaded(false); + fetch(`/folderspreview${location.pathname}`, { + headers: { + Accept: "application/json", + }, + }) + .then((res) => res.json()) + .then((data) => { + setFoldersPreview(data); + }); + fetch(`/images${location.pathname}`, { + headers: { + Accept: "application/json", + }, + }) + .then((res) => res.json()) + .then((data) => { + if (data.images === undefined) { + if (location.pathname !== "/") { + navigate("/"); + } else { + setError(true); + } + } else { + setImages(data.images); + setImagesLoaded(true); + } + }); + }, [location.pathname]); + + return ( + + + {!imagesLoaded || !foldersPreview ? ( + + ) : ( + <> + {foldersPreview.length > 0 && ( + <> + + + + + + )} + {images.length > 0 && foldersPreview.length > 0 && ( + + + + )} + {images.length > 0 && } + {images.length == 0 && foldersPreview.length == 0 && ( +

+ No images available. You may want to add images to this directory. +

+ )} + + )} +
+ ); +}; diff --git a/picture-gallery-client/src/ImageGalleryLayout.tsx b/picture-gallery-client/src/ImageGalleryLayout.tsx index 8d578ed..05a5c31 100644 --- a/picture-gallery-client/src/ImageGalleryLayout.tsx +++ b/picture-gallery-client/src/ImageGalleryLayout.tsx @@ -1,84 +1,21 @@ -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import CssBaseline from "@mui/material/CssBaseline"; import Box from "@mui/material/Box"; -import { useLocation, useNavigate } from "react-router-dom"; -import { - FolderPreview, - Folders, - ImageWithThumbnail, -} from "./ImageGallery/models"; import { ImageGalleryAppBar } from "./ImageGallery/ImageGalleryAppBar"; import { ImageGalleryDrawer } from "./ImageGallery/ImageGalleryDrawer"; -import { ImageGallery } from "./ImageGallery/ImageGallery"; -import { Spinner } from "./ImageGallery/Spinner"; -import Toolbar from "@mui/material/Toolbar"; -import { Chip, Divider } from "@mui/material"; -import { FolderGallery } from "./ImageGallery/FolderGallery"; +import { ImageGalleryMain } from "./ImageGallery/ImageGalleryMain"; const drawerWidth = 240; export const smallScreenMediaQuery = `(min-width:${drawerWidth * 3}px)`; -function ImageGalleryLayout() { +export const ImageGalleryLayout = (): React.JSX.Element => { const [drawerOpen, setDrawerOpen] = useState(false); const [error, setError] = useState(false); - const [imagesLoaded, setImagesLoaded] = useState(false); - const [images, setImages] = useState([]); - - const [folders, setFolders] = useState(undefined); - const [foldersPreview, setFoldersPreview] = useState< - FolderPreview[] | undefined - >([]); - const location = useLocation(); - const navigate = useNavigate(); function handleDrawerToggle() { setDrawerOpen(!drawerOpen); } - useEffect(() => { - fetch("/directories", { - headers: { - Accept: "application/json", - }, - }) - .then((res) => res.json()) - .then((data) => setFolders(data)); - }, []); - - useEffect(() => { - setFoldersPreview(undefined); - setImages([]); - setError(false); - setImagesLoaded(false); - fetch(`/folderspreview${location.pathname}`, { - headers: { - Accept: "application/json", - }, - }) - .then((res) => res.json()) - .then((data) => { - setFoldersPreview(data); - }); - fetch(`/images${location.pathname}`, { - headers: { - Accept: "application/json", - }, - }) - .then((res) => res.json()) - .then((data) => { - if (data.images === undefined) { - if (location.pathname !== "/") { - navigate("/"); - } else { - setError(true); - } - } else { - setImages(data.images); - setImagesLoaded(true); - } - }); - }, [location.pathname]); - if (error) { return (

@@ -98,40 +35,9 @@ function ImageGalleryLayout() { - - - {!imagesLoaded || !foldersPreview ? ( - - ) : ( - <> - {foldersPreview.length > 0 && ( - <> - - - - - - )} - {images.length > 0 && foldersPreview.length > 0 && ( - - - - )} - {images.length > 0 && } - {images.length == 0 && foldersPreview.length == 0 && ( -

- No images available. You may want to add images to this - directory. -

- )} - - )} - + ); -} - -export default ImageGalleryLayout; +}; diff --git a/picture-gallery-client/src/index.tsx b/picture-gallery-client/src/index.tsx index bc3c0d4..0d91603 100644 --- a/picture-gallery-client/src/index.tsx +++ b/picture-gallery-client/src/index.tsx @@ -3,7 +3,7 @@ import ReactDOM from "react-dom/client"; import "./index.css"; import { BrowserRouter } from "react-router-dom"; import reportWebVitals from "./reportWebVitals"; -import ImageGalleryLayout from "./ImageGalleryLayout"; +import { ImageGalleryLayout } from "./ImageGalleryLayout"; import { setGalleryTitleAndFavicon } from "./env"; setGalleryTitleAndFavicon();