From 7174e6ef7d4ded79f62de97153780ac516c29bcd Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa <72977554+Cristhianzl@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:57:46 -0300 Subject: [PATCH] fix: show loading component state while images arent fully loaded (#2609) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ (ProfilePictureForm): add loading state to handle initial loading state * ♻️ (use-get-profile-pictures.ts): refactor profile pictures query to process data on the server side ♻️ (ProfilePictureForm): simplify state management by removing redundant loading state * ♻️ (use-get-profile-pictures.ts): rename ProfilePicturesResponse to ProfilePicturesQueryResponse for clarity ♻️ (use-preload-images.tsx): add loading check to useEffect to prevent unnecessary execution ♻️ (profilePictureChooserComponent): update profilePictures prop type to handle undefined and add loading to usePreloadImages ♻️ (ProfilePictureForm): remove unnecessary state and use response directly from useGetProfilePicturesQuery * 🐛 (use-preload-images.tsx): add missing dependency 'loading' to useEffect dependency array to ensure images are preloaded correctly --- .../queries/files/use-get-profile-pictures.ts | 43 +++++++++++++------ .../hooks/use-preload-images.tsx | 4 +- .../profilePictureChooserComponent/index.tsx | 8 ++-- .../components/ProfilePictureForm/index.tsx | 29 ++----------- 4 files changed, 39 insertions(+), 45 deletions(-) diff --git a/src/frontend/src/controllers/API/queries/files/use-get-profile-pictures.ts b/src/frontend/src/controllers/API/queries/files/use-get-profile-pictures.ts index 69e7d0fb4..b2f1da135 100644 --- a/src/frontend/src/controllers/API/queries/files/use-get-profile-pictures.ts +++ b/src/frontend/src/controllers/API/queries/files/use-get-profile-pictures.ts @@ -6,31 +6,46 @@ import { UseRequestProcessor } from "../../services/request-processor"; interface ProfilePicturesQueryParams {} -export interface ProfilePicturesResponse { +export interface ProfilePicturesQueryResponse { files: string[]; } export const useGetProfilePicturesQuery: useQueryFunctionType< ProfilePicturesQueryParams, - ProfilePicturesResponse + { [key: string]: string[] } > = () => { const { query } = UseRequestProcessor(); - const getProfilePicturesFn = async () => { - const response = await api.get( - `${getURL("FILES")}/profile_pictures/list`, - ); + const getProfilePicturesFn = + async (): Promise => { + const response = await api.get( + `${getURL("FILES")}/profile_pictures/list`, + ); - return response.data; + return response.data; + }; + + const responseFn = async () => { + const data = await getProfilePicturesFn(); + + const profilePictures = {}; + + data?.files?.forEach((profile_picture) => { + const [folder, path] = profile_picture.split("/"); + + if (profilePictures[folder]) { + profilePictures[folder].push(path); + } else { + profilePictures[folder] = [path]; + } + }); + + return profilePictures; }; - const queryResult = query( - ["useGetProfilePicturesQuery"], - getProfilePicturesFn, - { - placeholderData: keepPreviousData, - }, - ); + const queryResult = query(["useGetProfilePicturesQuery"], responseFn, { + placeholderData: keepPreviousData, + }); return queryResult; }; diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx index df1ee2dd2..08cedee8b 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx @@ -4,6 +4,7 @@ import { BASE_URL_API } from "../../../../../../../../../constants/constants"; const usePreloadImages = ( profilePictures: { [key: string]: string[] }, setImagesLoaded: (value: boolean) => void, + loading: boolean, ) => { const preloadImages = async (imageUrls) => { return Promise.all( @@ -20,6 +21,7 @@ const usePreloadImages = ( }; useEffect(() => { + if (loading) return; const imageArray: string[] = []; Object.keys(profilePictures).flatMap((folder) => @@ -33,7 +35,7 @@ const usePreloadImages = ( preloadImages(imageArray).then(() => { setImagesLoaded(true); }); - }, [profilePictures]); + }, [profilePictures, loading]); return; }; diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx index 3b00d2365..923222bbf 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx @@ -7,7 +7,7 @@ import { cn } from "../../../../../../../../utils/utils"; import usePreloadImages from "./hooks/use-preload-images"; type ProfilePictureChooserComponentProps = { - profilePictures: { [key: string]: string[] }; + profilePictures: { [key: string]: string[] } | undefined; loading: boolean; value: string; onChange: (value: string) => void; @@ -29,21 +29,21 @@ export default function ProfilePictureChooserComponent({ } }, [ref, value]); - usePreloadImages(profilePictures, setImagesLoaded); + usePreloadImages(profilePictures!, setImagesLoaded, loading); return (
{loading || !imagesLoaded ? ( ) : ( - Object.keys(profilePictures).map((folder, idx) => ( + Object.keys(profilePictures!).map((folder, idx) => (
{folder}
- {profilePictures[folder].map((path, idx) => ( + {profilePictures![folder].map((path, idx) => (