mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-30 10:19:51 -06:00
fix: Autoclose issue (#2216)
This commit is contained in:
committed by
GitHub
parent
94a419249b
commit
29a9b7e23e
@@ -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>
|
||||
) : (
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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%;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user