import styles from "./styles.module.css"; import { useCallback, useEffect, useRef, useState } from "react"; import { UserCallbacks, useApi, useApiCall } from "@/api"; import { Asset } from "@/api/resources/Assets"; 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 parseAPNG from "apng-js"; import Player from "apng-js/types/library/player"; let apngPlayer: Player | null = null; function BreathPage(): 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 assetsData = useCallback(async () => { const { assets } = await api.getAssets({ category: String("au"), }); return assets; }, [api]); const { data } = useApiCall(assetsData); useEffect(() => { if (isOpenModal) return; const previewTimeOut = setTimeout(() => { setIsShowPreview(false); apngPlayer?.play(); }, 10_000); const navigateTimeOut = setTimeout(() => { navigate(routes.client.breathResult()); }, 60_000); return () => { clearTimeout(navigateTimeOut); clearTimeout(previewTimeOut); }; }, [navigate, isOpenModal]); useEffect(() => { async function getApng() { if (!data) return; const response = await fetch( data.find((item) => item.key === "au.apng.leo")?.url || "" ); const arrayBuffer = await response.arrayBuffer(); const apng = parseAPNG(arrayBuffer); const context = leoCanvasRef.current?.getContext("2d"); if (context && !(apng instanceof Error)) { context.canvas.height = apng.height; context.canvas.width = apng.width; const _apngPlayer = await apng.getPlayer(context); apngPlayer = _apngPlayer; if (apngPlayer) { apngPlayer.stop(); } } } getApng(); }, [data]); const beginBreath = () => { setIsOpenModal(false); }; const token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIzNjEyLCJpYXQiOjE2OTM0MTg5MTAsImV4cCI6MTcwMjA1ODkxMCwianRpIjoiNzg5MjkwYWItODg0YS00MGUyLTkyNjEtOWI2OGEyNjkwNmE0IiwiZW1haWwiOiJvdGhlckBleGFtcGxlLmNvbSIsInN0YXRlIjoicHJvdmVuIiwibG9jIjoiZW4iLCJ0eiI6LTI4ODAwLCJ0eXBlIjoiZW1haWwiLCJpc3MiOiJjb20ubGlmZS5hdXJhIn0.J2ocWIv5jKzuKMcwMgWMiNMyGg5qLlMAeln-bQm_9lw"; 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) { 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]); useApiCall(createCallback); return ( <>
{!isOpenModal && isShowPreview && (
{t("aura.breath_relax.text")}
)} {!isOpenModal && !isShowPreview && (
{t("breathIn")} {t("breathOut")}
)}
); } export default BreathPage;