diff --git a/fluxer_app/src/features/app/components/layout/AuthLayout.tsx b/fluxer_app/src/features/app/components/layout/AuthLayout.tsx index a01609923..25bde5d66 100644 --- a/fluxer_app/src/features/app/components/layout/AuthLayout.tsx +++ b/fluxer_app/src/features/app/components/layout/AuthLayout.tsx @@ -41,7 +41,7 @@ const AuthLayoutContent = observer(function AuthLayoutContent({children}: {child const registerFormDraftsRef = useRef>(new Map()); const scrollerRef = useRef(null); const location = useLocation(); - const {patternReady, splashLoaded, splashDimensions} = useAuthBackground(splashUrl, foodPatternUrl); + const {patternReady, splashDimensions} = useAuthBackground(splashUrl, foodPatternUrl); const handleSetSplashUrl = useCallback( (url: string | null) => { if (splashUrlRef.current === url) return; @@ -196,7 +196,6 @@ const AuthLayoutContent = observer(function AuthLayoutContent({children}: {child > ) => { @@ -20,7 +18,6 @@ const getSplashAlignmentStyles = (alignment: ValueOf = ({ splashUrl, - splashLoaded, splashDimensions, splashScale, patternReady, @@ -47,13 +43,7 @@ export const AuthBackground: React.FC = ({ if (useFullCover) { return (
- +
= ({ data-flx="auth.flow.auth-background.img" />
- +
); } return (
- = ({ data-flx="auth.flow.auth-background.img--2" />
- +
); } diff --git a/fluxer_app/src/features/auth/hooks/useAuthBackground.ts b/fluxer_app/src/features/auth/hooks/useAuthBackground.ts index 9c6e36711..77af62a48 100644 --- a/fluxer_app/src/features/auth/hooks/useAuthBackground.ts +++ b/fluxer_app/src/features/auth/hooks/useAuthBackground.ts @@ -1,5 +1,6 @@ // SPDX-License-Identifier: AGPL-3.0-or-later +import * as ImageCacheUtils from '@app/features/messaging/utils/ImageCacheUtils'; import {useEffect, useState} from 'react'; interface ImageDimensions { @@ -12,62 +13,53 @@ interface PatternImageLoaderResult { } interface SplashImageLoaderResult { - loaded: boolean; dimensions: ImageDimensions | null; } interface AuthBackgroundResult { patternReady: boolean; - splashLoaded: boolean; splashDimensions: ImageDimensions | null; } export function usePatternImageLoader(patternUrl: string): PatternImageLoaderResult { - const [patternReady, setPatternReady] = useState(false); + const [patternReady, setPatternReady] = useState(() => ImageCacheUtils.hasImage(patternUrl)); useEffect(() => { - const img = new Image(); - const handleLoad = () => setPatternReady(true); - img.addEventListener('load', handleLoad, {once: true}); - img.src = patternUrl; - return () => img.removeEventListener('load', handleLoad); + if (ImageCacheUtils.hasImage(patternUrl)) { + setPatternReady(true); + return; + } + setPatternReady(false); + return ImageCacheUtils.loadImage(patternUrl, () => setPatternReady(true)); }, [patternUrl]); return {patternReady}; } export function useSplashImageLoader(imageUrl: string | null): SplashImageLoaderResult { - const [loaded, setLoaded] = useState(false); - const [dimensions, setDimensions] = useState(null); + const [dimensions, setDimensions] = useState( + () => ImageCacheUtils.getImageSize(imageUrl) ?? null, + ); useEffect(() => { - if (!imageUrl) { - setLoaded(false); - setDimensions(null); + const cached = ImageCacheUtils.getImageSize(imageUrl); + if (cached) { + setDimensions(cached); return; } - let isMounted = true; - const img = new Image(); - const handleLoad = () => { - if (!isMounted) return; - setLoaded(true); - setDimensions({ - width: img.naturalWidth, - height: img.naturalHeight, - }); - }; - img.addEventListener('load', handleLoad, {once: true}); - img.src = imageUrl; - return () => { - isMounted = false; - }; + setDimensions(null); + if (!imageUrl) { + return; + } + return ImageCacheUtils.loadImage(imageUrl, () => { + setDimensions(ImageCacheUtils.getImageSize(imageUrl) ?? null); + }); }, [imageUrl]); - return {loaded, dimensions}; + return {dimensions}; } export function useAuthBackground(splashUrl: string | null, patternUrl: string): AuthBackgroundResult { const {patternReady} = usePatternImageLoader(patternUrl); - const {loaded: splashLoaded, dimensions: splashDimensions} = useSplashImageLoader(splashUrl); + const {dimensions: splashDimensions} = useSplashImageLoader(splashUrl); return { patternReady, - splashLoaded, splashDimensions, }; } diff --git a/fluxer_app/src/features/invite/components/modals/InvitePagePreviewModal.tsx b/fluxer_app/src/features/invite/components/modals/InvitePagePreviewModal.tsx index d1e85821a..5fbcb404c 100644 --- a/fluxer_app/src/features/invite/components/modals/InvitePagePreviewModal.tsx +++ b/fluxer_app/src/features/invite/components/modals/InvitePagePreviewModal.tsx @@ -61,7 +61,7 @@ export const InvitePagePreviewModal: React.FC = obs } return null; }, [previewSplashUrl, guild?.id, guild?.splash]); - const {patternReady, splashLoaded, splashDimensions} = useAuthBackground(splashUrl, foodPatternUrl); + const {patternReady, splashDimensions} = useAuthBackground(splashUrl, foodPatternUrl); const shouldShowSplash = Boolean(splashUrl && splashDimensions); const handleClose = useCallback(() => { ModalCommands.pop(); @@ -122,7 +122,6 @@ export const InvitePagePreviewModal: React.FC = obs