From 864eb9ee4b0d8ed47fe59767639fb5bdba620c78 Mon Sep 17 00:00:00 2001 From: gofnnp Date: Thu, 28 Sep 2023 02:22:13 +0400 Subject: [PATCH] feat: preload apng leo, page moons, logic of transitions between pages breath and compatibility, fix navbar footer, fix energy values --- src/components/App/index.tsx | 46 +++++++++++-- src/components/BreathPage/index.tsx | 43 +++++------- src/components/CompatResultPage/index.tsx | 17 ++++- src/components/EnergyValues/index.tsx | 2 +- src/components/HomePage/index.tsx | 4 +- src/components/HomePage/styles.module.css | 5 ++ src/components/NavbarFooter/index.tsx | 11 ++-- .../StartBreathModalChild/index.tsx | 2 - src/components/UserCallbacksPage/index.tsx | 13 +++- src/components/WallpaperPage/index.tsx | 65 ++++++++++++++----- .../WallpaperPage/styles.module.css | 23 ++++++- src/store/siteConfig.ts | 3 +- 12 files changed, 170 insertions(+), 64 deletions(-) diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 9a542da..2391167 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { Routes, Route, @@ -42,16 +42,42 @@ import HomePage from "../HomePage"; import UserCallbacksPage from "../UserCallbacksPage"; import NavbarFooter, { INavbarHomeItems } from "../NavbarFooter"; import { EPathsFromHome } from "@/store/siteConfig"; +import parseAPNG, { APNG } from "apng-js"; +import { useApi, useApiCall } from "@/api"; +import { Asset } from "@/api/resources/Assets"; function App(): JSX.Element { const [isSpecialOfferOpen, setIsSpecialOfferOpen] = useState(false); + const [leoApng, setLeoApng] = useState(Error); const navigate = useNavigate(); + const api = useApi(); const closeSpecialOfferAttention = () => { setIsSpecialOfferOpen(false); navigate(routes.client.emailEnter()); }; + const assetsData = useCallback(async () => { + const { assets } = await api.getAssets({ + category: String("au"), + }); + return assets; + }, [api]); + + const { data } = useApiCall(assetsData); + + 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(); + setLeoApng(parseAPNG(arrayBuffer)); + } + getApng(); + }, [data]); + return ( }> @@ -84,7 +110,10 @@ function App(): JSX.Element { path={routes.client.compatibilityResult()} element={} /> - } /> + } + /> } /> } /> null, @@ -163,12 +194,17 @@ function Layout({ setIsSpecialOfferOpen }: LayoutProps): JSX.Element { { title: "Compatibility", path: routes.client.compatibility(), + paths: [ + routes.client.compatibility(), + routes.client.compatibilityResult(), + ], image: "Compatibility.svg", onClick: handleCompatibility, }, { title: "My Moon", path: routes.client.wallpaper(), + paths: [routes.client.wallpaper()], image: "moon.svg", onClick: () => null, }, @@ -221,7 +257,7 @@ function MainPage(): JSX.Element { function ProtectWallpaperPage(): JSX.Element { const status = useSelector(selectors.selectStatus); - return (); + return ; return status === "subscribed" ? ( ) : ( diff --git a/src/components/BreathPage/index.tsx b/src/components/BreathPage/index.tsx index 8a4ef60..776d756 100644 --- a/src/components/BreathPage/index.tsx +++ b/src/components/BreathPage/index.tsx @@ -1,7 +1,6 @@ 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"; @@ -10,13 +9,17 @@ import StartBreathModalChild from "../StartBreathModalChild"; import Title from "../Title"; import { useNavigate } from "react-router-dom"; import routes from "@/routes"; -import parseAPNG from "apng-js"; +import { APNG } from "apng-js"; import Player from "apng-js/types/library/player"; import { EPathsFromHome } from "@/store/siteConfig"; let apngPlayer: Player | null = null; -function BreathPage(): JSX.Element { +interface BreathPageProps { + leoApng: Error | APNG; +} + +function BreathPage({ leoApng }: BreathPageProps): JSX.Element { const { t } = useTranslation(); const [isOpenModal, setIsOpenModal] = useState(true); const [isShowPreview, setIsShowPreview] = useState(true); @@ -28,15 +31,6 @@ function BreathPage(): JSX.Element { 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(() => { @@ -55,26 +49,20 @@ function BreathPage(): JSX.Element { }, [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); + async function getApngPlayer() { 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); + 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(); } } } - getApng(); - }, [data]); + getApngPlayer(); + }, [leoApng]); const beginBreath = () => { setIsOpenModal(false); @@ -168,7 +156,10 @@ function BreathPage(): JSX.Element { )} - + {!isOpenModal && !isShowPreview && (
diff --git a/src/components/CompatResultPage/index.tsx b/src/components/CompatResultPage/index.tsx index a3bb37f..1f37812 100644 --- a/src/components/CompatResultPage/index.tsx +++ b/src/components/CompatResultPage/index.tsx @@ -25,6 +25,8 @@ function CompatResultPage(): JSX.Element { const showNavbarFooter = homeConfig.isShowNavbar; const [text, setText] = useState("Loading..."); const [isOpenModal, setIsOpenModal] = useState(true); + const [isVisualLoading, setIsVisualLoading] = useState(true); + const [isDataLoading, setIsDataLoading] = useState(true); const handleNext = () => { if (homeConfig.pathFromHome === EPathsFromHome.breath) { @@ -68,10 +70,14 @@ function CompatResultPage(): JSX.Element { setTimeout(loadAIRequest, 3000); } setText(aIRequest?.ai_request?.response?.body || "Loading..."); + setIsDataLoading(false); + checkLoading(); return aIRequest.ai_request; }; return await loadAIRequest(); } + setIsDataLoading(false); + checkLoading(); setText(aICompat?.compat?.body || "Loading..."); return aICompat.compat; @@ -91,6 +97,14 @@ function CompatResultPage(): JSX.Element { return "108px"; }; + function checkLoading() { + if (isVisualLoading || isDataLoading) { + setIsOpenModal(true); + } else { + setIsOpenModal(false); + } + } + return (
{ - setIsOpenModal(false); + setIsVisualLoading(false); + checkLoading(); }} /> diff --git a/src/components/EnergyValues/index.tsx b/src/components/EnergyValues/index.tsx index b7fb4e2..d073787 100644 --- a/src/components/EnergyValues/index.tsx +++ b/src/components/EnergyValues/index.tsx @@ -14,7 +14,7 @@ const colors: Record = { } const valueFormatter = (value: number) => { - return `${(value).toFixed()}%` + return `${(value * 10).toFixed(1)}%` } function EnergyValues({ className, values }: IEnergyValues): JSX.Element { diff --git a/src/components/HomePage/index.tsx b/src/components/HomePage/index.tsx index 147e21c..7195c02 100644 --- a/src/components/HomePage/index.tsx +++ b/src/components/HomePage/index.tsx @@ -134,7 +134,7 @@ function HomePage(): JSX.Element {
-
+ {
{buttonTextFormatter(t("aura-10_breath-button"))} -
+
}
{dailyForecast && dailyForecast.forecasts.map((forecast, index) => ( diff --git a/src/components/HomePage/styles.module.css b/src/components/HomePage/styles.module.css index 18f457f..7fed6b2 100644 --- a/src/components/HomePage/styles.module.css +++ b/src/components/HomePage/styles.module.css @@ -131,6 +131,11 @@ /* margin-left: 13px; */ } +.content__buttons--hidden { + opacity: 0; + pointer-events: none; +} + @keyframes pulse { 0% { transform: scale(0.9); diff --git a/src/components/NavbarFooter/index.tsx b/src/components/NavbarFooter/index.tsx index 52684de..fba02d8 100644 --- a/src/components/NavbarFooter/index.tsx +++ b/src/components/NavbarFooter/index.tsx @@ -3,8 +3,9 @@ import styles from "./styles.module.css"; export interface INavbarHomeItems { title: string; - path: string; + paths: string[]; image: string; + path: string; active?: boolean; onClick?: () => void; } @@ -32,9 +33,9 @@ function NavbarFooter({ items }: INavbarHomeProps): JSX.Element { className={styles["navbar-item__image-container"]} style={{ backgroundColor: - item.path === location.pathname ? "#ff2c57" : "#fff", - mask: `url('./navbar-icons/${item.image}')`, - WebkitMask: `url('./navbar-icons/${item.image}')`, + item.paths.includes(location.pathname) ? "#ff2c57" : "#fff", + mask: `url('/navbar-icons/${item.image}')`, + WebkitMask: `url('/navbar-icons/${item.image}')`, WebkitMaskSize: "contain", WebkitMaskRepeat: "no-repeat", WebkitMaskPosition: "center", @@ -49,7 +50,7 @@ function NavbarFooter({ items }: INavbarHomeProps): JSX.Element {

{item.title} diff --git a/src/components/StartBreathModalChild/index.tsx b/src/components/StartBreathModalChild/index.tsx index 8e2c8aa..67dbb6e 100644 --- a/src/components/StartBreathModalChild/index.tsx +++ b/src/components/StartBreathModalChild/index.tsx @@ -12,8 +12,6 @@ function StartBreathModalChild({ isShowNavbar=false }: IStartBreathModalChildProps): JSX.Element { const { t } = useTranslation(); - console.log(isShowNavbar); - return (

diff --git a/src/components/UserCallbacksPage/index.tsx b/src/components/UserCallbacksPage/index.tsx index bc89f2f..e0602f8 100644 --- a/src/components/UserCallbacksPage/index.tsx +++ b/src/components/UserCallbacksPage/index.tsx @@ -28,20 +28,27 @@ function UserCallbacksPage(): JSX.Element { if (homeConfig.pathFromHome === EPathsFromHome.breath) { return navigate(routes.client.compatibility()); } + if (homeConfig.pathFromHome === EPathsFromHome.navbar) { + return navigate(routes.client.breath()); + } }; const getPaddingBottomPage = () => { - if (homeConfig.pathFromHome === EPathsFromHome.compatibility && showNavbarFooter) return "246px"; + if ( + homeConfig.pathFromHome === EPathsFromHome.compatibility && + showNavbarFooter + ) + return "246px"; if (showNavbarFooter) return "164px"; return "108px"; - } + }; return (
- {!showNavbarFooter &&
} + {
}
<> diff --git a/src/components/WallpaperPage/index.tsx b/src/components/WallpaperPage/index.tsx index 910b8f1..e917a13 100644 --- a/src/components/WallpaperPage/index.tsx +++ b/src/components/WallpaperPage/index.tsx @@ -11,7 +11,7 @@ import { getCategoryIdByZodiacSign, getZodiacSignByDate, } from "@/services/zodiac-sign"; -import { Zodiac } from "@/api/resources/Zodiacs"; +import { Zodiac, ZodiacParagraph } from "@/api/resources/Zodiacs"; type Forecasts = DailyForecasts.Forecast[]; type PersonalAssets = Assets.Asset[]; @@ -21,9 +21,42 @@ interface WallpaperData { zodiac: Zodiac; } +function getZodiacParagraphs( + paragraphs: ZodiacParagraph[], + depth = 0 +): JSX.Element[] { + depth++; + if (!paragraphs) { + return []; + } + function getTypeOfContent(content: string[] | ZodiacParagraph[]) { + if (Array.isArray(content) && content.length > 0) { + return typeof content[0]; + } + } + + return paragraphs.map((paragraph, index) => { + const Headline = `h${depth}` as keyof JSX.IntrinsicElements; + return ( + <div className={styles["wallpaper-paragraph"]} key={index}> + <Headline + className={`${styles["wallpaper-paragraph__title"]} ${ + depth % 2 === 0 ? styles["wallpaper-paragraph__title--white"] : "" + }`} + > + {paragraph.title} + </Headline> + {getTypeOfContent(paragraph.content) === "string" + ? paragraph.content.map((content, _index) => <p key={_index}>{content as string}</p>) + : getZodiacParagraphs(paragraph.content as ZodiacParagraph[], depth)} + </div> + ); + }); +} + function WallpaperPage(): JSX.Element { const api = useApi(); - const { t, i18n } = useTranslation(); + const { i18n } = useTranslation(); const locale = i18n.language; const token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIzNjEyLCJpYXQiOjE2OTM0MTg5MTAsImV4cCI6MTcwMjA1ODkxMCwianRpIjoiNzg5MjkwYWItODg0YS00MGUyLTkyNjEtOWI2OGEyNjkwNmE0IiwiZW1haWwiOiJvdGhlckBleGFtcGxlLmNvbSIsInN0YXRlIjoicHJvdmVuIiwibG9jIjoiZW4iLCJ0eiI6LTI4ODAwLCJ0eXBlIjoiZW1haWwiLCJpc3MiOiJjb20ubGlmZS5hdXJhIn0.J2ocWIv5jKzuKMcwMgWMiNMyGg5qLlMAeln-bQm_9lw"; @@ -50,7 +83,6 @@ function WallpaperPage(): JSX.Element { })); }, [api, token, locale, zodiacSign]); const { data, isPending } = useApiCall<WallpaperData>(loadData); - const forecasts = data ? data.forecasts : []; const asset = data ? data.assets.at(0) : null; const zodiacInfo = data ? data.zodiac : null; @@ -64,14 +96,6 @@ function WallpaperPage(): JSX.Element { className={styles["wallpaper-image"]} style={{ backgroundImage: `url(${asset?.url})` }} > - <div className={styles["zodiac-metas"]}> - {zodiacInfo?.metas.map((meta, index) => ( - <div key={index} className={styles["zodiac-meta"]}> - <p className={styles["zodiac-meta-label"]}>{meta.label}</p> - <p className={styles["zodiac-meta-value"]}>{meta.value}</p> - </div> - ))} - </div> {asset ? ( <div className={styles["btn-download"]} onClick={handleClick} /> ) : null} @@ -80,10 +104,18 @@ function WallpaperPage(): JSX.Element { <div className={styles["wallpaper-content"]}> {isPending ? null : ( <> - <h1 className={styles["wallpaper-title"]}> + <div className={styles["zodiac-metas"]}> + {zodiacInfo?.metas.map((meta, index) => ( + <div key={index} className={styles["zodiac-meta"]}> + <p className={styles["zodiac-meta-label"]}>{meta.label}</p> + <p className={styles["zodiac-meta-value"]}>{meta.value}</p> + </div> + ))} + </div> + {/* <h1 className={styles["wallpaper-title"]}> {t("analysis_background")} - </h1> - {forecasts.map((forecast) => ( + </h1> */} + {/* {forecasts.map((forecast) => ( <div key={forecast.category_name} className={styles["wallpaper-forecast"]} @@ -93,7 +125,10 @@ function WallpaperPage(): JSX.Element { </h2> <p className={styles["wallpaper-text"]}>{forecast.body}</p> </div> - ))} + ))} */} + <div className={styles["wallpaper-forecast"]}> + {getZodiacParagraphs(zodiacInfo?.paragraphs || [])} + </div> </> )} </div> diff --git a/src/components/WallpaperPage/styles.module.css b/src/components/WallpaperPage/styles.module.css index bd19fcb..c9d6913 100644 --- a/src/components/WallpaperPage/styles.module.css +++ b/src/components/WallpaperPage/styles.module.css @@ -33,7 +33,7 @@ } .wallpaper-content::before { - content: ''; + content: ""; display: block; position: absolute; top: -30px; @@ -72,7 +72,8 @@ } .zodiac-metas { - width: 100%; + width: calc(100% - 64px); + margin: -80px auto 16px; height: fit-content; padding: 16px; background-color: #5d5d5d; @@ -97,4 +98,20 @@ .zodiac-meta-value { font-weight: 700; -} \ No newline at end of file +} + +.wallpaper-paragraph { + margin-bottom: 32px; +} + +.wallpaper-paragraph__title { + color: #ea445a; + margin-bottom: 16px; +} + +.wallpaper-paragraph__title--white { + margin-bottom: 0; + color: #fff; + font-size: 22px; + font-weight: 700; +} diff --git a/src/store/siteConfig.ts b/src/store/siteConfig.ts index e5edeef..902ab51 100644 --- a/src/store/siteConfig.ts +++ b/src/store/siteConfig.ts @@ -3,7 +3,8 @@ import type { PayloadAction } from "@reduxjs/toolkit"; export enum EPathsFromHome { compatibility, - breath + breath, + navbar } interface ISiteConfig {