327 lines
11 KiB
TypeScript
327 lines
11 KiB
TypeScript
import { useSelector } from "react-redux";
|
|
import styles from "./styles.module.scss";
|
|
import { selectors } from "@/store";
|
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
import { IPalmistryLine } from "@/api/resources/Palmistry";
|
|
import Title from "@/components/Title";
|
|
import { ICompatibilityV2FingerLocal } from "@/store/compatibilityV2";
|
|
import { useNavigate } from "react-router-dom";
|
|
import routes from "@/routes";
|
|
import ScannedPhotoElement from "@/components/palmistry/scanned-photo/scanned-photo";
|
|
import { useTranslations } from "@/hooks/translations";
|
|
import { ELocalesPlacement } from "@/locales";
|
|
import ProgressBarLine from "@/components/ui/ProgressBarLine";
|
|
import Modal from "@/components/Modal";
|
|
import { useAuthentication } from "@/hooks/authentication/use-authentication";
|
|
import { ESourceAuthorization } from "@/api/resources/User";
|
|
|
|
const drawElementChangeDelay = 1500;
|
|
const startDelay = 500;
|
|
|
|
interface IPoint {
|
|
title1: string;
|
|
title2: string;
|
|
modal: {
|
|
title: string;
|
|
description: string;
|
|
answerLeft: string;
|
|
answerRight: string;
|
|
}
|
|
}
|
|
|
|
function ScannedPhoto() {
|
|
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
|
const navigate = useNavigate();
|
|
const photo = useSelector(selectors.selectCompatibilityV2Photo);
|
|
const fingers = useSelector(selectors.selectCompatibilityV2Fingers);
|
|
const lines = useSelector(selectors.selectCompatibilityV2Lines);
|
|
|
|
const changeTitleTimeOut = useRef<NodeJS.Timeout>();
|
|
|
|
const [currentElementIndex, setCurrentElementIndex] = useState(0);
|
|
const [title, setTitle] = useState("");
|
|
const [shouldDisplayPalmLines, setShouldDisplayPalmLines] = useState(false);
|
|
const [smallPhotoState, setSmallPhotoState] = useState(false);
|
|
const [isDecorationShown, setIsDecorationShown] = useState(true);
|
|
const [classNameScannedPhoto, setClassNameScannedPhoto] = useState("");
|
|
|
|
const feature = useSelector(selectors.selectFeature);
|
|
const isIOSPath = useMemo(() => feature?.toLowerCase()?.includes("ios"), [feature]);
|
|
const authCode = useSelector(selectors.selectAuthCode);
|
|
|
|
const { authorization } = useAuthentication();
|
|
|
|
const drawElements = useMemo(() => [...fingers, ...lines], [fingers, lines]);
|
|
|
|
const { relationshipStatus } = useSelector(selectors.selectCompatibilityV2Answers)
|
|
|
|
const loadingProfilePoints: IPoint[] = useMemo(() => {
|
|
const prefix = relationshipStatus === "single" ? "without-partner" : "with-partner";
|
|
return [
|
|
{
|
|
title1: `/scanned-photo.${prefix}.loaders.title-1-1`,
|
|
title2: `/scanned-photo.${prefix}.loaders.title-1-2`,
|
|
modal: {
|
|
title: `/scanned-photo.${prefix}.modals.title-1`,
|
|
description: `/scanned-photo.${prefix}.modals.description-1`,
|
|
answerLeft: `/scanned-photo.${prefix}.modals.answer-1-left`,
|
|
answerRight: `/scanned-photo.${prefix}.modals.answer-1-right`,
|
|
}
|
|
},
|
|
{
|
|
title1: `/scanned-photo.${prefix}.loaders.title-2-1`,
|
|
title2: `/scanned-photo.${prefix}.loaders.title-2-2`,
|
|
modal: {
|
|
title: `/scanned-photo.${prefix}.modals.title-2`,
|
|
description: `/scanned-photo.${prefix}.modals.description-2`,
|
|
answerLeft: `/scanned-photo.${prefix}.modals.answer-2-left`,
|
|
answerRight: `/scanned-photo.${prefix}.modals.answer-2-right`,
|
|
}
|
|
},
|
|
{
|
|
title1: `/scanned-photo.${prefix}.loaders.title-3-1`,
|
|
title2: `/scanned-photo.${prefix}.loaders.title-3-2`,
|
|
modal: {
|
|
title: `/scanned-photo.${prefix}.modals.title-3`,
|
|
description: `/scanned-photo.${prefix}.modals.description-3`,
|
|
answerLeft: `/scanned-photo.${prefix}.modals.answer-3-left`,
|
|
answerRight: `/scanned-photo.${prefix}.modals.answer-3-right`,
|
|
}
|
|
},
|
|
]
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (isIOSPath) {
|
|
(async () => {
|
|
await authorization("", ESourceAuthorization["aura.compatibility.v2"], true);
|
|
})();
|
|
}
|
|
}, [isIOSPath, authorization])
|
|
|
|
useEffect(() => {
|
|
if (!drawElements[currentElementIndex]) return;
|
|
changeTitleTimeOut.current = setTimeout(() => {
|
|
const title =
|
|
(drawElements[currentElementIndex] as ICompatibilityV2FingerLocal)
|
|
.fingerName || drawElements[currentElementIndex].name;
|
|
setTitle(title);
|
|
if (currentElementIndex < drawElements.length - 1) {
|
|
setCurrentElementIndex((prevState) => prevState + 1);
|
|
}
|
|
}, drawElementChangeDelay);
|
|
|
|
return () => {
|
|
if (changeTitleTimeOut.current) {
|
|
clearTimeout(changeTitleTimeOut.current);
|
|
}
|
|
};
|
|
}, [currentElementIndex, drawElements]);
|
|
|
|
useEffect(() => {
|
|
if (currentElementIndex < drawElements.length - 1) return;
|
|
|
|
const timer = setTimeout(() => {
|
|
setTitle("");
|
|
}, drawElementChangeDelay * 2)
|
|
|
|
return () => {
|
|
if (timer) {
|
|
clearTimeout(timer);
|
|
}
|
|
}
|
|
}, [currentElementIndex, drawElements])
|
|
|
|
useEffect(() => {
|
|
setShouldDisplayPalmLines(
|
|
lines.includes(drawElements[currentElementIndex] as IPalmistryLine)
|
|
);
|
|
}, [currentElementIndex, drawElements, lines]);
|
|
|
|
useEffect(() => {
|
|
if (currentElementIndex < drawElements.length - 1) return;
|
|
const timer = setTimeout(() => {
|
|
setSmallPhotoState(true);
|
|
}, drawElementChangeDelay * 2);
|
|
const goNextTimer = setTimeout(
|
|
() => {
|
|
// navigate(routes.client.compatibilityV2Email())
|
|
setIsDecorationShown(false);
|
|
setClassNameScannedPhoto(styles.scannedPhotoSmall);
|
|
},
|
|
drawElementChangeDelay * drawElements.length + 8000
|
|
);
|
|
|
|
return () => {
|
|
if (timer) {
|
|
clearTimeout(timer);
|
|
}
|
|
if (goNextTimer) {
|
|
clearTimeout(goNextTimer);
|
|
}
|
|
};
|
|
}, [currentElementIndex, drawElements.length, navigate]);
|
|
|
|
// useEffect(() => {
|
|
// if (currentElementIndex < drawElements.length) return;
|
|
// const timer = setTimeout(() => {
|
|
// // navigate(routes.client.compatibilityV2Email());
|
|
// }, drawElementChangeDelay + 1000);
|
|
// return () => clearTimeout(timer);
|
|
// }, [currentElementIndex, drawElements.length, navigate]);
|
|
|
|
|
|
const [progress, setProgress] = useState(0);
|
|
const [isPause, setIsPause] = useState(false);
|
|
const interval = useRef<NodeJS.Timeout>();
|
|
|
|
const getProgressValue = useCallback(
|
|
(index: number) => {
|
|
const integerDivision = Math.floor(progress / 100);
|
|
if (integerDivision > index) {
|
|
return 100;
|
|
}
|
|
if (integerDivision === index) {
|
|
return progress % 100;
|
|
}
|
|
return 0;
|
|
},
|
|
[progress]
|
|
);
|
|
|
|
const onEndLoading = useCallback(() => {
|
|
const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
|
|
if (isIOSPath && !!authCode && isIOS) {
|
|
return navigate(routes.client.compatibilityV2TryApp());
|
|
}
|
|
navigate(routes.client.compatibilityV2Email());
|
|
}, [isIOSPath, authCode, navigate]);
|
|
|
|
useEffect(() => {
|
|
if (progress === 75) {
|
|
setIsPause(true);
|
|
}
|
|
if (progress !== 0 && (progress / 50) % 2 === 1 && progress > 100) {
|
|
return setIsPause(true);
|
|
}
|
|
}, [progress]);
|
|
|
|
useEffect(() => {
|
|
if (progress >= loadingProfilePoints.length * 100) {
|
|
return onEndLoading();
|
|
}
|
|
interval.current = setTimeout(() => {
|
|
setProgress((prevProgress) => {
|
|
if (!isPause && !isDecorationShown) return prevProgress + 1;
|
|
return prevProgress;
|
|
});
|
|
}, 100);
|
|
return () => {
|
|
clearTimeout(interval.current);
|
|
};
|
|
}, [progress, onEndLoading, isPause, isDecorationShown]);
|
|
|
|
const getCurrentIndex = () => {
|
|
return Math.floor(progress / 100);
|
|
};
|
|
|
|
return (
|
|
<section className={`${styles.page} palmistry-container_type_scan-photo`}>
|
|
<Title variant="h2" className={styles.title}>
|
|
{title}
|
|
</Title>
|
|
<ScannedPhotoElement
|
|
photo={photo}
|
|
small={smallPhotoState}
|
|
drawElementChangeDelay={drawElementChangeDelay}
|
|
startDelay={startDelay}
|
|
displayLines={shouldDisplayPalmLines}
|
|
lines={lines}
|
|
fingers={fingers}
|
|
drawElements={drawElements}
|
|
className={classNameScannedPhoto}
|
|
isDecorationShown={isDecorationShown}
|
|
/>
|
|
<h2
|
|
className={`palmistry-container__waiting-title ${!isDecorationShown ? styles.hidden : ""}`}
|
|
style={{
|
|
animationDelay: `${drawElementChangeDelay * drawElements.length + 2500
|
|
}ms`,
|
|
}}
|
|
>
|
|
{translate("/scanned-photo.title")}
|
|
</h2>
|
|
|
|
<h3
|
|
className={`palmistry-container__waiting-description ${!isDecorationShown ? styles.hidden : ""}`}
|
|
style={{
|
|
animationDelay: `${drawElementChangeDelay * drawElements.length + 3000
|
|
}ms`,
|
|
}}
|
|
>
|
|
{translate("/scanned-photo.text")}
|
|
</h3>
|
|
|
|
|
|
{isPause && (
|
|
<Modal
|
|
isCloseButtonVisible={false}
|
|
open={!!isPause}
|
|
onClose={() => setIsPause(false)}
|
|
className={styles.modal}
|
|
containerClassName={styles["modal-container"]}
|
|
>
|
|
<Title variant="h4" className={styles["modal-title"]}>
|
|
{translate(loadingProfilePoints[getCurrentIndex()].modal.title)}
|
|
</Title>
|
|
<p className={styles["modal-description"]}>
|
|
{translate(loadingProfilePoints[getCurrentIndex()].modal.description)}
|
|
</p>
|
|
<div className={styles["modal-answers"]}>
|
|
<div className={styles["modal-answer"]} onClick={() => setIsPause(false)}>
|
|
<p className={styles["modal-answer-text"]}>
|
|
{translate(loadingProfilePoints[getCurrentIndex()].modal.answerLeft)}
|
|
</p>
|
|
</div>
|
|
<div className={styles["modal-answer"]} onClick={() => setIsPause(false)}>
|
|
<p className={styles["modal-answer-text"]}>
|
|
{translate(loadingProfilePoints[getCurrentIndex()].modal.answerRight)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</Modal>
|
|
)}
|
|
{!isDecorationShown && <div className={styles["points-container"]}>
|
|
{loadingProfilePoints.map(({ title1, title2 }, index) => (
|
|
<div
|
|
className={`${styles["point"]} ${getCurrentIndex() === index && styles["active"]
|
|
}`}
|
|
// ref={(el) => (pointsRef.current[index] = el as HTMLDivElement)}
|
|
key={`point-${index}`}
|
|
>
|
|
<div className={styles["point__text-container"]}>
|
|
<Title variant="h2" className={styles["point__title"]}>
|
|
{translate(getProgressValue(index) > 50 ? title2 : title1)}
|
|
</Title>
|
|
<ProgressBarLine
|
|
containerClassName={styles["progress-bar__container"]}
|
|
lineClassName={styles["progress-bar__line"]}
|
|
lineColor={"#275DA7"}
|
|
value={getProgressValue(index)}
|
|
delay={50}
|
|
/>
|
|
</div>
|
|
<p
|
|
className={styles["point__percentage"]}
|
|
>
|
|
{getProgressValue(index)}%
|
|
</p>
|
|
</div>
|
|
))}
|
|
</div>}
|
|
</section >
|
|
);
|
|
}
|
|
|
|
export default ScannedPhoto;
|