mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-24 14:38:43 -05:00
fix: wait for background to load in survey loading indicator (#3011)
This commit is contained in:
committed by
GitHub
parent
3dc3edb83e
commit
3e25ef4b5a
@@ -1,6 +1,6 @@
|
||||
import { LegalFooter } from "@/app/s/[surveyId]/components/LegalFooter";
|
||||
import { SurveyLoadingAnimation } from "@/app/s/[surveyId]/components/SurveyLoadingAnimation";
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { TProduct, TProductStyling } from "@formbricks/types/product";
|
||||
import { TSurvey, TSurveyStyling } from "@formbricks/types/surveys/types";
|
||||
@@ -36,6 +36,13 @@ export const LinkSurveyWrapper = ({
|
||||
webAppUrl,
|
||||
}: LinkSurveyWrapperProps) => {
|
||||
//for embedded survey strip away all surrounding css
|
||||
const [isBackgroundLoaded, setIsBackgroundLoaded] = useState(false);
|
||||
|
||||
const handleBackgroundLoaded = (isLoaded: boolean) => {
|
||||
if (isLoaded) {
|
||||
setIsBackgroundLoaded(true);
|
||||
}
|
||||
};
|
||||
const styling = determineStyling();
|
||||
if (isEmbed)
|
||||
return (
|
||||
@@ -52,8 +59,8 @@ export const LinkSurveyWrapper = ({
|
||||
else
|
||||
return (
|
||||
<div>
|
||||
<SurveyLoadingAnimation survey={survey} />
|
||||
<MediaBackground survey={survey} product={product}>
|
||||
<SurveyLoadingAnimation survey={survey} isBackgroundLoaded={isBackgroundLoaded} />
|
||||
<MediaBackground survey={survey} product={product} onBackgroundLoaded={handleBackgroundLoaded}>
|
||||
<div className="flex max-h-dvh min-h-dvh items-end justify-center overflow-clip md:items-center">
|
||||
{!styling.isLogoHidden && product.logo?.url && <ClientLogo product={product} />}
|
||||
<div className="h-full w-full space-y-6 p-0 md:max-w-md">
|
||||
|
||||
@@ -7,14 +7,18 @@ import { LoadingSpinner } from "@formbricks/ui/LoadingSpinner";
|
||||
|
||||
interface SurveyLoadingAnimationProps {
|
||||
survey: TSurvey;
|
||||
isBackgroundLoaded?: boolean;
|
||||
}
|
||||
|
||||
export const SurveyLoadingAnimation = ({ survey }: SurveyLoadingAnimationProps) => {
|
||||
export const SurveyLoadingAnimation = ({
|
||||
survey,
|
||||
isBackgroundLoaded = true,
|
||||
}: SurveyLoadingAnimationProps) => {
|
||||
const [isHidden, setIsHidden] = useState(false);
|
||||
const [minTimePassed, setMinTimePassed] = useState(false);
|
||||
const [isMediaLoaded, setIsMediaLoaded] = useState(false); // Tracks if all media (images, iframes) are fully loaded
|
||||
const [isSurveyPackageLoaded, setIsSurveyPackageLoaded] = useState(false); // Tracks if the survey package has been loaded into the DOM
|
||||
|
||||
const isReadyToTransition = isMediaLoaded && minTimePassed && isBackgroundLoaded;
|
||||
const cardId = survey.welcomeCard.enabled ? `questionCard--1` : `questionCard-0`;
|
||||
|
||||
// Function to check if all media elements (images and iframes) within the survey card are loaded
|
||||
@@ -96,13 +100,13 @@ export const SurveyLoadingAnimation = ({ survey }: SurveyLoadingAnimationProps)
|
||||
<div
|
||||
className={cn(
|
||||
"absolute inset-0 z-[5000] flex items-center justify-center transition-colors duration-1000",
|
||||
isMediaLoaded && minTimePassed ? "bg-transparent" : "bg-white",
|
||||
isReadyToTransition ? "bg-transparent" : "bg-white",
|
||||
isHidden && "hidden"
|
||||
)}>
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col items-center space-y-4",
|
||||
isMediaLoaded && minTimePassed ? "animate-surveyExit" : "animate-surveyLoading"
|
||||
isReadyToTransition ? "animate-surveyExit" : "animate-surveyLoading"
|
||||
)}>
|
||||
<Image src={Logo} alt="Logo" className={cn("w-32 transition-all duration-1000 md:w-40")} />
|
||||
<LoadingSpinner />
|
||||
|
||||
@@ -13,6 +13,7 @@ interface MediaBackgroundProps {
|
||||
isEditorView?: boolean;
|
||||
isMobilePreview?: boolean;
|
||||
ContentRef?: React.RefObject<HTMLDivElement>;
|
||||
onBackgroundLoaded?: (isLoaded: boolean) => void;
|
||||
}
|
||||
|
||||
export const MediaBackground: React.FC<MediaBackgroundProps> = ({
|
||||
@@ -22,6 +23,7 @@ export const MediaBackground: React.FC<MediaBackgroundProps> = ({
|
||||
isEditorView = false,
|
||||
isMobilePreview = false,
|
||||
ContentRef,
|
||||
onBackgroundLoaded,
|
||||
}) => {
|
||||
const animatedBackgroundRef = useRef<HTMLVideoElement>(null);
|
||||
const [backgroundLoaded, setBackgroundLoaded] = useState(false);
|
||||
@@ -75,6 +77,12 @@ export const MediaBackground: React.FC<MediaBackgroundProps> = ({
|
||||
}
|
||||
}, [background?.bg, background?.bgType]);
|
||||
|
||||
useEffect(() => {
|
||||
if (backgroundLoaded && onBackgroundLoaded) {
|
||||
onBackgroundLoaded(true);
|
||||
}
|
||||
}, [backgroundLoaded, onBackgroundLoaded]);
|
||||
|
||||
const baseClasses = "absolute inset-0 h-full w-full transition-opacity duration-500";
|
||||
const loadedClass = backgroundLoaded ? "opacity-100" : "opacity-0";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user