import styles from "./styles.module.css"; import { useCallback, useEffect, useRef, useState } from "react"; import { UserCallbacks, useApi, useApiCall } from "@/api"; import { useDispatch, useSelector } from "react-redux"; import { actions, selectors } from "@/store"; import { useTranslation } from "react-i18next"; import FullScreenModal from "../FullScreenModal"; import StartBreathModalChild from "../StartBreathModalChild"; import Title from "../Title"; import { useNavigate } from "react-router-dom"; import routes from "@/routes"; import { APNG } from "apng-js"; import Player from "apng-js/types/library/player"; let apngPlayer: Player | null = null; interface BreathPageProps { leoApng: Error | APNG; } function BreathPage({ leoApng }: BreathPageProps): JSX.Element { const { t } = useTranslation(); const [isOpenModal, setIsOpenModal] = useState(true); const [isShowPreview, setIsShowPreview] = useState(true); const leoCanvasRef = useRef(null); const pageRef = useRef(null); const api = useApi(); const dispatch = useDispatch(); const navigate = useNavigate(); const homeConfig = useSelector(selectors.selectHome); const showNavbarFooter = homeConfig.isShowNavbar; const queryTimeOutRef = useRef(); useEffect(() => { return () => { if (queryTimeOutRef.current) { clearTimeout(queryTimeOutRef.current); } }; }, []); useEffect(() => { if (isOpenModal) return; const previewTimeOut = setTimeout(() => { setIsShowPreview(false); apngPlayer?.play(); }, 10_000); const navigateTimeOut = setTimeout(() => { navigate(routes.client.breathResult()); }, 50_000); return () => { clearTimeout(navigateTimeOut); clearTimeout(previewTimeOut); }; }, [navigate, isOpenModal]); useEffect(() => { async function getApngPlayer() { const context = leoCanvasRef.current?.getContext("2d"); if (context && !(leoApng instanceof Error)) { context.canvas.height = leoApng.height; context.canvas.width = leoApng.width; const _apngPlayer = await leoApng.getPlayer(context); apngPlayer = _apngPlayer; if (apngPlayer) { apngPlayer.stop(); } } } getApngPlayer(); }, [leoApng]); const beginBreath = () => { setIsOpenModal(false); }; const token = useSelector(selectors.selectToken); const createCallback = useCallback(async () => { const data: UserCallbacks.PayloadPost = { data: { user_callback: { kind: "breathing_end", }, }, token, }; const createCallbackRequest = await api.createUserCallbacks(data); dispatch(actions.userCallbacks.update(createCallbackRequest.user_callback)); if (!createCallbackRequest.user_callback.is_complete) { const getUserCallbacksRequest = async () => { const getCallback = await api.getUserCallbacks({ id: createCallbackRequest.user_callback.id, token, }); if (!getCallback.user_callback.is_complete) { queryTimeOutRef.current = setTimeout(getUserCallbacksRequest, 3000); } dispatch( actions.userCallbacks.update({ description: getCallback.user_callback.description || "Loading...", }) ); return getCallback.user_callback; }; return await getUserCallbacksRequest(); } return createCallbackRequest.user_callback; }, [api, dispatch, token]); useApiCall(createCallback); const handleCross = () => { navigate(routes.client.breathResult()); }; return ( <>
{!showNavbarFooter && (
)} {!isOpenModal && isShowPreview && (
{t("aura.breath_relax.text")}
)} {!isOpenModal && !isShowPreview && (
{t("breathIn")} {t("breathOut")}
)}
); } export default BreathPage;