fix: Autoclose issue (#2216)

This commit is contained in:
Dhruwang Jariwala
2024-03-13 14:36:57 +05:30
committed by GitHub
parent 94a419249b
commit 29a9b7e23e
4 changed files with 73 additions and 44 deletions

View File

@@ -70,8 +70,7 @@ export default function PreviewSurvey({
const [previewMode, setPreviewMode] = useState("desktop");
const [previewPosition, setPreviewPosition] = useState("relative");
const ContentRef = useRef<HTMLDivElement | null>(null);
const [shrink, setshrink] = useState(false);
const [shrink, setShrink] = useState(false);
const { productOverwrites } = survey || {};
const previewScreenVariants: Variants = {
@@ -141,7 +140,7 @@ export default function PreviewSurvey({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [survey]);
function resetQuestionProgress() {
const resetQuestionProgress = () => {
let storePreviewMode = previewMode;
setPreviewMode("null");
setTimeout(() => {
@@ -149,7 +148,7 @@ export default function PreviewSurvey({
}, 10);
setActiveQuestionId(survey.welcomeCard.enabled ? "start" : survey?.questions[0]?.id);
}
};
useEffect(() => {
if (environment && environment.widgetSetupCompleted) {
@@ -159,6 +158,13 @@ export default function PreviewSurvey({
}
}, [environment]);
const handlePreviewModalClose = () => {
setIsModalOpen(false);
setTimeout(() => {
setIsModalOpen(true);
}, 1000);
};
if (!previewType) {
previewType = widgetSetupCompleted ? "modal" : "fullwidth";
@@ -208,6 +214,7 @@ export default function PreviewSurvey({
onActiveQuestionChange={setActiveQuestionId}
isRedirectDisabled={true}
onFileUpload={onFileUpload}
onClose={handlePreviewModalClose}
/>
</Modal>
) : (
@@ -244,7 +251,7 @@ export default function PreviewSurvey({
<ShrinkIcon
className="mr-2 h-4 w-4 cursor-pointer"
onClick={() => {
setshrink(true);
setShrink(true);
setPreviewPosition("relative");
setTimeout(() => setIsFullScreenPreview(false), 300);
}}
@@ -253,7 +260,7 @@ export default function PreviewSurvey({
<ExpandIcon
className="mr-2 h-4 w-4 cursor-pointer"
onClick={() => {
setshrink(false);
setShrink(false);
setIsFullScreenPreview(true);
setTimeout(() => setPreviewPosition("fixed"), 300);
}}
@@ -278,6 +285,7 @@ export default function PreviewSurvey({
onActiveQuestionChange={setActiveQuestionId}
isRedirectDisabled={true}
onFileUpload={onFileUpload}
onClose={handlePreviewModalClose}
/>
</Modal>
) : (

View File

@@ -0,0 +1,16 @@
interface AutoCloseProgressBarProps {
autoCloseTimeout: number;
}
export function AutoCloseProgressBar({ autoCloseTimeout }: AutoCloseProgressBarProps) {
return (
<div className="bg-accent-bg h-2 w-full overflow-hidden rounded-full">
<div
key={autoCloseTimeout}
className="bg-brand z-20 h-2 rounded-full"
style={{
animation: `shrink-width-to-zero ${autoCloseTimeout}s linear forwards`,
}}></div>
</div>
);
}

View File

@@ -1,59 +1,55 @@
import { AutoCloseProgressBar } from "@/components/general/AutoCloseProgressBar";
import React from "preact/compat";
import { useEffect, useRef, useState } from "preact/hooks";
import { TSurvey } from "@formbricks/types/surveys";
import Progress from "../general/Progress";
interface AutoCloseProps {
survey: TSurvey;
onClose: () => void;
children: any;
children: React.ReactNode;
}
export function AutoCloseWrapper({ survey, onClose, children }: AutoCloseProps) {
const [countdownProgress, setCountdownProgress] = useState(100);
const [countdownStop, setCountdownStop] = useState(false);
const startRef = useRef(performance.now());
const frameRef = useRef<number | null>(null);
const [countDownActive, setCountDownActive] = useState(true);
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const showAutoCloseProgressBar = countDownActive && survey.type === "web";
const handleStopCountdown = () => {
if (frameRef.current !== null) {
setCountdownStop(true);
cancelAnimationFrame(frameRef.current);
frameRef.current = null;
const startCountdown = () => {
if (!survey.autoClose) return;
if (timeoutRef.current) {
stopCountdown();
}
setCountDownActive(true);
timeoutRef.current = setTimeout(() => {
onClose();
setCountDownActive(false);
}, survey.autoClose * 1000);
};
const stopCountdown = () => {
setCountDownActive(false);
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
};
useEffect(() => {
if (!survey.autoClose) return;
const updateCountdown = () => {
const timeout = survey.autoClose! * 1000;
const elapsed = performance.now() - startRef.current;
const remaining = Math.max(0, timeout - elapsed);
setCountdownProgress(remaining / timeout);
if (remaining > 0) {
frameRef.current = requestAnimationFrame(updateCountdown);
} else {
handleStopCountdown();
onClose();
}
};
setCountdownProgress(1);
frameRef.current = requestAnimationFrame(updateCountdown);
return () => handleStopCountdown();
}, [survey.autoClose, onClose]);
startCountdown();
return stopCountdown;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [survey.autoClose]);
return (
<>
{!countdownStop && survey.autoClose && <Progress progress={countdownProgress} />}
<div onClick={handleStopCountdown} onMouseOver={handleStopCountdown} className="h-full w-full">
<div>
{survey.autoClose && showAutoCloseProgressBar && (
<AutoCloseProgressBar autoCloseTimeout={survey.autoClose} />
)}
<div onClick={stopCountdown} onMouseOver={stopCountdown} className="h-full w-full">
{children}
</div>
</>
</div>
);
}

View File

@@ -82,3 +82,12 @@ p.fb-editor-paragraph {
--fb-close-btn-color: var(--slate-500);
--fb-close-btn-color-hover: var(--slate-700);
}
@keyframes shrink-width-to-zero {
from {
width: 100%;
}
to {
width: 0%;
}
}