From eb26063b3f8820e7cd6bf660a16390df94a8222d Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 30 Aug 2023 10:49:13 +0800 Subject: [PATCH 1/7] chore: add util method to retrieve image path --- src/utils/images.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/utils/images.ts diff --git a/src/utils/images.ts b/src/utils/images.ts new file mode 100644 index 000000000..2082b6468 --- /dev/null +++ b/src/utils/images.ts @@ -0,0 +1,10 @@ +/** + * Util method to retrieve image path from /images folder from the relative file path, + * e.g. "/images/album/picture.jpg" -> "album/picture.jpg" + */ +export const getImagePath = (imageLink: string) => { + const cleanImagePath = decodeURI(imageLink).replace(/^\//, "") + const filePathArr = cleanImagePath.split("/") + const filePath = filePathArr[filePathArr.length - 1] + return filePath +} From 6ebb78deb948259afcc2d21c98185ffdcfc3db20 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 30 Aug 2023 10:49:48 +0800 Subject: [PATCH 2/7] fix: replace image retrieval in homepage template components with updated v2 endpoint --- src/templates/homepage/HeroSection.jsx | 26 +++++++++++------- src/templates/homepage/InfopicLeftSection.jsx | 27 ++++++++++++------- .../homepage/InfopicRightSection.jsx | 26 +++++++++++------- 3 files changed, 49 insertions(+), 30 deletions(-) diff --git a/src/templates/homepage/HeroSection.jsx b/src/templates/homepage/HeroSection.jsx index 6591d95df..4c74c8d2e 100644 --- a/src/templates/homepage/HeroSection.jsx +++ b/src/templates/homepage/HeroSection.jsx @@ -4,14 +4,15 @@ /* eslint-disable jsx-a11y/anchor-is-valid */ import PropTypes from "prop-types" -import { forwardRef } from "react" -import { useQuery } from "react-query" +import { forwardRef, useState, useEffect } from "react" + +import { useGetMediaHook } from "hooks/mediaHooks" import editorStyles from "styles/isomer-cms/pages/Editor.module.scss" import { getClassNames } from "templates/utils/stylingUtils" -import { fetchImageURL } from "utils" +import { getImagePath } from "utils/images" /* eslint react/no-array-index-key: 0 @@ -178,14 +179,19 @@ const TemplateHeroSection = ( { hero, siteName, dropdownIsActive, toggleDropdown }, ref ) => { - const { data: loadedImageURL } = useQuery( - `${siteName}/${hero.background}`, - () => fetchImageURL(siteName, decodeURI(hero.background)), - { - refetchOnWindowFocus: false, - staleTime: Infinity, // Never automatically refetch image unless query is invalidated + const [loadedImageURL, setLoadedImageURL] = useState("") + const fileName = getImagePath(hero.background) + const { data: mediaData } = useGetMediaHook({ + siteName, + mediaDirectoryName: "images", + fileName, + }) + + useEffect(() => { + if (mediaData) { + setLoadedImageURL(mediaData.mediaUrl) } - ) + }, [mediaData]) const heroStyle = { // See j08691's answer at https://stackoverflow.com/questions/21388712/background-size-doesnt-work diff --git a/src/templates/homepage/InfopicLeftSection.jsx b/src/templates/homepage/InfopicLeftSection.jsx index 3dbc9b127..b4797acba 100644 --- a/src/templates/homepage/InfopicLeftSection.jsx +++ b/src/templates/homepage/InfopicLeftSection.jsx @@ -1,12 +1,14 @@ import PropTypes from "prop-types" -import { forwardRef } from "react" -import { useQuery } from "react-query" +import { forwardRef, useState, useEffect } from "react" + +import { useGetMediaHook } from "hooks/mediaHooks" import editorStyles from "styles/isomer-cms/pages/Editor.module.scss" import { getClassNames } from "templates/utils/stylingUtils" -import { fetchImageURL } from "utils" +import { getImagePath } from "utils/images" + /* eslint react/no-array-index-key: 0 */ @@ -28,14 +30,19 @@ const TemplateInfopicLeftSection = ( e.target.src = "/placeholder_no_image.png" } - const { data: loadedImageURL } = useQuery( - `${siteName}/${imageUrl}`, - () => fetchImageURL(siteName, decodeURI(imageUrl)), - { - refetchOnWindowFocus: false, - staleTime: Infinity, // Never automatically refetch image unless query is invalidated + const [loadedImageURL, setLoadedImageURL] = useState("") + const fileName = getImagePath(imageUrl) + const { data: mediaData } = useGetMediaHook({ + siteName, + mediaDirectoryName: "images", + fileName, + }) + + useEffect(() => { + if (mediaData) { + setLoadedImageURL(mediaData.mediaUrl) } - ) + }, [mediaData]) return (
diff --git a/src/templates/homepage/InfopicRightSection.jsx b/src/templates/homepage/InfopicRightSection.jsx index 098eb3c95..c6164c9c5 100644 --- a/src/templates/homepage/InfopicRightSection.jsx +++ b/src/templates/homepage/InfopicRightSection.jsx @@ -1,12 +1,13 @@ import PropTypes from "prop-types" -import { forwardRef } from "react" -import { useQuery } from "react-query" +import { forwardRef, useState, useEffect } from "react" + +import { useGetMediaHook } from "hooks/mediaHooks" import editorStyles from "styles/isomer-cms/pages/Editor.module.scss" import { getClassNames } from "templates/utils/stylingUtils" -import { fetchImageURL } from "utils" +import { getImagePath } from "utils/images" /* eslint react/no-array-index-key: 0 @@ -29,14 +30,19 @@ const TemplateInfopicRightSection = ( e.target.src = "/placeholder_no_image.png" } - const { data: loadedImageURL } = useQuery( - `${siteName}/${imageUrl}`, - () => fetchImageURL(siteName, decodeURI(imageUrl)), - { - refetchOnWindowFocus: false, - staleTime: Infinity, // Never automatically refetch image unless query is invalidated + const [loadedImageURL, setLoadedImageURL] = useState("") + const fileName = getImagePath(imageUrl) + const { data: mediaData } = useGetMediaHook({ + siteName, + mediaDirectoryName: "images", + fileName, + }) + + useEffect(() => { + if (mediaData) { + setLoadedImageURL(mediaData.mediaUrl) } - ) + }, [mediaData]) return (
From 62d436c34d3bc02653de03ff1ae39fa2a27bf7b6 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 30 Aug 2023 14:14:52 +0800 Subject: [PATCH 3/7] fix: change return of util method to handle nested --- src/templates/homepage/HeroSection.jsx | 6 +++--- src/templates/homepage/InfopicLeftSection.jsx | 6 +++--- .../homepage/InfopicRightSection.jsx | 6 +++--- src/utils/images.ts | 20 +++++++++++++------ 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/templates/homepage/HeroSection.jsx b/src/templates/homepage/HeroSection.jsx index 4c74c8d2e..e2fa66c4c 100644 --- a/src/templates/homepage/HeroSection.jsx +++ b/src/templates/homepage/HeroSection.jsx @@ -12,7 +12,7 @@ import editorStyles from "styles/isomer-cms/pages/Editor.module.scss" import { getClassNames } from "templates/utils/stylingUtils" -import { getImagePath } from "utils/images" +import { getImageDetails } from "utils/images" /* eslint react/no-array-index-key: 0 @@ -180,10 +180,10 @@ const TemplateHeroSection = ( ref ) => { const [loadedImageURL, setLoadedImageURL] = useState("") - const fileName = getImagePath(hero.background) + const { fileName, imageDirectory } = getImageDetails(hero.background) const { data: mediaData } = useGetMediaHook({ siteName, - mediaDirectoryName: "images", + mediaDirectoryName: imageDirectory || "images", fileName, }) diff --git a/src/templates/homepage/InfopicLeftSection.jsx b/src/templates/homepage/InfopicLeftSection.jsx index b4797acba..6de2ca417 100644 --- a/src/templates/homepage/InfopicLeftSection.jsx +++ b/src/templates/homepage/InfopicLeftSection.jsx @@ -7,7 +7,7 @@ import editorStyles from "styles/isomer-cms/pages/Editor.module.scss" import { getClassNames } from "templates/utils/stylingUtils" -import { getImagePath } from "utils/images" +import { getImageDetails } from "utils/images" /* eslint react/no-array-index-key: 0 @@ -31,10 +31,10 @@ const TemplateInfopicLeftSection = ( } const [loadedImageURL, setLoadedImageURL] = useState("") - const fileName = getImagePath(imageUrl) + const { fileName, imageDirectory } = getImageDetails(imageUrl) const { data: mediaData } = useGetMediaHook({ siteName, - mediaDirectoryName: "images", + mediaDirectoryName: imageDirectory || "images", fileName, }) diff --git a/src/templates/homepage/InfopicRightSection.jsx b/src/templates/homepage/InfopicRightSection.jsx index c6164c9c5..8aae829d3 100644 --- a/src/templates/homepage/InfopicRightSection.jsx +++ b/src/templates/homepage/InfopicRightSection.jsx @@ -7,7 +7,7 @@ import editorStyles from "styles/isomer-cms/pages/Editor.module.scss" import { getClassNames } from "templates/utils/stylingUtils" -import { getImagePath } from "utils/images" +import { getImageDetails } from "utils/images" /* eslint react/no-array-index-key: 0 @@ -31,10 +31,10 @@ const TemplateInfopicRightSection = ( } const [loadedImageURL, setLoadedImageURL] = useState("") - const fileName = getImagePath(imageUrl) + const { fileName, imageDirectory } = getImageDetails(imageUrl) const { data: mediaData } = useGetMediaHook({ siteName, - mediaDirectoryName: "images", + mediaDirectoryName: imageDirectory || "images", fileName, }) diff --git a/src/utils/images.ts b/src/utils/images.ts index 2082b6468..bb4f8630d 100644 --- a/src/utils/images.ts +++ b/src/utils/images.ts @@ -1,10 +1,18 @@ /** - * Util method to retrieve image path from /images folder from the relative file path, - * e.g. "/images/album/picture.jpg" -> "album/picture.jpg" + * Util method to retrieve image details from /images folder from the relative file path, + * e.g. "/images/album%/picture$.jpg" -> { imageDirectory: "images%2Falbum%24", fileName: "picture%24.jpg" } */ -export const getImagePath = (imageLink: string) => { +export const getImageDetails = (imageLink: string) => { const cleanImagePath = decodeURI(imageLink).replace(/^\//, "") - const filePathArr = cleanImagePath.split("/") - const filePath = filePathArr[filePathArr.length - 1] - return filePath + const filePathArr = cleanImagePath + .split("/") + .map((segment) => encodeURIComponent(segment)) + const fileName = filePathArr[filePathArr.length - 1] + const imageDirectory = filePathArr + .slice(0, filePathArr.length - 1) + .join("%2F") + return { + fileName, + imageDirectory, + } } From 8db4dc6532c3a05fcb44d412e1295d24728495b5 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 30 Aug 2023 15:25:45 +0800 Subject: [PATCH 4/7] Update src/utils/images.ts Co-authored-by: Qilu Xie --- src/utils/images.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/images.ts b/src/utils/images.ts index bb4f8630d..7bf6b9d72 100644 --- a/src/utils/images.ts +++ b/src/utils/images.ts @@ -2,7 +2,7 @@ * Util method to retrieve image details from /images folder from the relative file path, * e.g. "/images/album%/picture$.jpg" -> { imageDirectory: "images%2Falbum%24", fileName: "picture%24.jpg" } */ -export const getImageDetails = (imageLink: string) => { +export const getImageDetails = (imageLink: string): { fileName: string; imageDirectory: string } => { const cleanImagePath = decodeURI(imageLink).replace(/^\//, "") const filePathArr = cleanImagePath .split("/") From 112304a57e4362f18adc402eeb243ff398701ad7 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 30 Aug 2023 15:26:11 +0800 Subject: [PATCH 5/7] Update src/utils/images.ts Co-authored-by: Qilu Xie --- src/utils/images.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/images.ts b/src/utils/images.ts index 7bf6b9d72..19f42a4bd 100644 --- a/src/utils/images.ts +++ b/src/utils/images.ts @@ -1,6 +1,6 @@ /** * Util method to retrieve image details from /images folder from the relative file path, - * e.g. "/images/album%/picture$.jpg" -> { imageDirectory: "images%2Falbum%24", fileName: "picture%24.jpg" } + * e.g. "/images/album%/picture$.jpg" -> { imageDirectory: "images%2Falbum%25", fileName: "picture%24.jpg" } */ export const getImageDetails = (imageLink: string): { fileName: string; imageDirectory: string } => { const cleanImagePath = decodeURI(imageLink).replace(/^\//, "") From ac625de783a2ac4fe525c84d617ab150c4ffcd0a Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 30 Aug 2023 16:20:41 +0800 Subject: [PATCH 6/7] chore: fix styling --- src/utils/images.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/images.ts b/src/utils/images.ts index 19f42a4bd..a9e8bc194 100644 --- a/src/utils/images.ts +++ b/src/utils/images.ts @@ -2,7 +2,9 @@ * Util method to retrieve image details from /images folder from the relative file path, * e.g. "/images/album%/picture$.jpg" -> { imageDirectory: "images%2Falbum%25", fileName: "picture%24.jpg" } */ -export const getImageDetails = (imageLink: string): { fileName: string; imageDirectory: string } => { +export const getImageDetails = ( + imageLink: string +): { fileName: string; imageDirectory: string } => { const cleanImagePath = decodeURI(imageLink).replace(/^\//, "") const filePathArr = cleanImagePath .split("/") From 5cb437acfd02601fd8e030b1cb3871a413ba6f73 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 30 Aug 2023 16:39:28 +0800 Subject: [PATCH 7/7] refactor: move image fetching to separate hook --- src/hooks/useFetchPreviewMedia.ts | 25 +++++++++++++++ src/layouts/EditHomepage/HomepagePreview.tsx | 3 -- src/templates/homepage/HeroSection.jsx | 23 +++---------- src/templates/homepage/InfopicLeftSection.jsx | 32 +++---------------- .../homepage/InfopicRightSection.jsx | 32 +++---------------- 5 files changed, 37 insertions(+), 78 deletions(-) create mode 100644 src/hooks/useFetchPreviewMedia.ts diff --git a/src/hooks/useFetchPreviewMedia.ts b/src/hooks/useFetchPreviewMedia.ts new file mode 100644 index 000000000..1639d226c --- /dev/null +++ b/src/hooks/useFetchPreviewMedia.ts @@ -0,0 +1,25 @@ +import { useState, useEffect } from "react" +import { useParams } from "react-router-dom" + +import { getImageDetails } from "utils/images" + +import { useGetMediaHook } from "./mediaHooks" + +export const useFetchPreviewMedia = (imageUrl = ""): string => { + const { siteName } = useParams<{ siteName: string }>() + const [loadedImageURL, setLoadedImageURL] = useState(imageUrl) + const { fileName, imageDirectory } = getImageDetails(imageUrl) + const { data: mediaData } = useGetMediaHook({ + siteName, + mediaDirectoryName: imageDirectory || "images", + fileName, + }) + + useEffect(() => { + if (mediaData) { + setLoadedImageURL(mediaData.mediaUrl) + } + }, [mediaData]) + + return loadedImageURL +} diff --git a/src/layouts/EditHomepage/HomepagePreview.tsx b/src/layouts/EditHomepage/HomepagePreview.tsx index 88528f3e4..aaf401745 100644 --- a/src/layouts/EditHomepage/HomepagePreview.tsx +++ b/src/layouts/EditHomepage/HomepagePreview.tsx @@ -103,7 +103,6 @@ export const HomepagePreview = ({ ) : ( @@ -163,7 +161,6 @@ export const HomepagePreview = ({ imageAlt={section.infopic.alt} button={section.infopic.button} sectionIndex={sectionIndex} - siteName={siteName} ref={scrollRefs[sectionIndex]} /> )} diff --git a/src/templates/homepage/HeroSection.jsx b/src/templates/homepage/HeroSection.jsx index e2fa66c4c..ddb5e2c8e 100644 --- a/src/templates/homepage/HeroSection.jsx +++ b/src/templates/homepage/HeroSection.jsx @@ -4,16 +4,14 @@ /* eslint-disable jsx-a11y/anchor-is-valid */ import PropTypes from "prop-types" -import { forwardRef, useState, useEffect } from "react" +import { forwardRef } from "react" -import { useGetMediaHook } from "hooks/mediaHooks" +import { useFetchPreviewMedia } from "hooks/useFetchPreviewMedia" import editorStyles from "styles/isomer-cms/pages/Editor.module.scss" import { getClassNames } from "templates/utils/stylingUtils" -import { getImageDetails } from "utils/images" - /* eslint react/no-array-index-key: 0 */ @@ -176,22 +174,10 @@ const KeyHighlights = ({ highlights }) => ( ) const TemplateHeroSection = ( - { hero, siteName, dropdownIsActive, toggleDropdown }, + { hero, dropdownIsActive, toggleDropdown }, ref ) => { - const [loadedImageURL, setLoadedImageURL] = useState("") - const { fileName, imageDirectory } = getImageDetails(hero.background) - const { data: mediaData } = useGetMediaHook({ - siteName, - mediaDirectoryName: imageDirectory || "images", - fileName, - }) - - useEffect(() => { - if (mediaData) { - setLoadedImageURL(mediaData.mediaUrl) - } - }, [mediaData]) + const loadedImageURL = useFetchPreviewMedia(hero.background) const heroStyle = { // See j08691's answer at https://stackoverflow.com/questions/21388712/background-size-doesnt-work @@ -337,7 +323,6 @@ TemplateHeroSection.propTypes = { }) ), }).isRequired, - siteName: PropTypes.string.isRequired, dropdownIsActive: PropTypes.bool.isRequired, toggleDropdown: PropTypes.func.isRequired, } diff --git a/src/templates/homepage/InfopicLeftSection.jsx b/src/templates/homepage/InfopicLeftSection.jsx index 6de2ca417..7d1eb77ca 100644 --- a/src/templates/homepage/InfopicLeftSection.jsx +++ b/src/templates/homepage/InfopicLeftSection.jsx @@ -1,48 +1,25 @@ import PropTypes from "prop-types" -import { forwardRef, useState, useEffect } from "react" +import { forwardRef } from "react" -import { useGetMediaHook } from "hooks/mediaHooks" +import { useFetchPreviewMedia } from "hooks/useFetchPreviewMedia" import editorStyles from "styles/isomer-cms/pages/Editor.module.scss" import { getClassNames } from "templates/utils/stylingUtils" -import { getImageDetails } from "utils/images" - /* eslint react/no-array-index-key: 0 */ const TemplateInfopicLeftSection = ( - { - title, - subtitle, - description, - button, - sectionIndex, - imageUrl, - imageAlt, - siteName, - }, + { title, subtitle, description, button, sectionIndex, imageUrl, imageAlt }, ref ) => { const addDefaultSrc = (e) => { e.target.src = "/placeholder_no_image.png" } - const [loadedImageURL, setLoadedImageURL] = useState("") - const { fileName, imageDirectory } = getImageDetails(imageUrl) - const { data: mediaData } = useGetMediaHook({ - siteName, - mediaDirectoryName: imageDirectory || "images", - fileName, - }) - - useEffect(() => { - if (mediaData) { - setLoadedImageURL(mediaData.mediaUrl) - } - }, [mediaData]) + const loadedImageURL = useFetchPreviewMedia(imageUrl) return (
@@ -269,7 +246,6 @@ TemplateInfopicLeftSection.propTypes = { imageUrl: PropTypes.string, imageAlt: PropTypes.string, sectionIndex: PropTypes.number.isRequired, - siteName: PropTypes.string.isRequired, } TemplateInfopicLeftSection.defaultProps = { diff --git a/src/templates/homepage/InfopicRightSection.jsx b/src/templates/homepage/InfopicRightSection.jsx index 8aae829d3..b41dec6a0 100644 --- a/src/templates/homepage/InfopicRightSection.jsx +++ b/src/templates/homepage/InfopicRightSection.jsx @@ -1,48 +1,25 @@ import PropTypes from "prop-types" -import { forwardRef, useState, useEffect } from "react" +import { forwardRef } from "react" -import { useGetMediaHook } from "hooks/mediaHooks" +import { useFetchPreviewMedia } from "hooks/useFetchPreviewMedia" import editorStyles from "styles/isomer-cms/pages/Editor.module.scss" import { getClassNames } from "templates/utils/stylingUtils" -import { getImageDetails } from "utils/images" - /* eslint react/no-array-index-key: 0 */ const TemplateInfopicRightSection = ( - { - title, - subtitle, - description, - button, - sectionIndex, - imageUrl, - imageAlt, - siteName, - }, + { title, subtitle, description, button, sectionIndex, imageUrl, imageAlt }, ref ) => { const addDefaultSrc = (e) => { e.target.src = "/placeholder_no_image.png" } - const [loadedImageURL, setLoadedImageURL] = useState("") - const { fileName, imageDirectory } = getImageDetails(imageUrl) - const { data: mediaData } = useGetMediaHook({ - siteName, - mediaDirectoryName: imageDirectory || "images", - fileName, - }) - - useEffect(() => { - if (mediaData) { - setLoadedImageURL(mediaData.mediaUrl) - } - }, [mediaData]) + const loadedImageURL = useFetchPreviewMedia(imageUrl) return (
@@ -269,7 +246,6 @@ TemplateInfopicRightSection.propTypes = { imageUrl: PropTypes.string, imageAlt: PropTypes.string, sectionIndex: PropTypes.number.isRequired, - siteName: PropTypes.string.isRequired, } TemplateInfopicRightSection.defaultProps = {