From 238b56558c3636f9859fb87c2265b016029da8ea Mon Sep 17 00:00:00 2001 From: Teddy Ni Date: Tue, 4 Oct 2022 10:25:08 -0700 Subject: [PATCH] Wrapped Cleanup (#431) * Cleaning up font sizes * More clean up * Add error handling --- .../Wrapped/Sections/DayInParticular.tsx | 2 +- .../Wrapped/Sections/EveryoneScrolling.tsx | 17 +- .../Dashboard/Wrapped/Sections/FriendList.tsx | 11 +- .../Wrapped/Sections/MostMessages.tsx | 2 +- .../Dashboard/Wrapped/Sections/Overview.tsx | 4 +- .../Wrapped/Sections/SentEmojiList.tsx | 5 +- .../Wrapped/Sections/SentWordList.tsx | 11 +- .../Dashboard/Wrapped/Sections/TopFriend.tsx | 14 +- .../Wrapped/Sections/TopGroupChat.tsx | 12 +- .../Wrapped/Sections/WrappedError.tsx | 82 ++++++ .../Wrapped/Sections/WrappedIntro.tsx | 74 +++-- .../Wrapped/Sections/WrappedLoading.tsx | 80 ++++++ .../Dashboard/Wrapped/WrappedGradient.tsx | 152 +++++++++++ .../Dashboard/Wrapped/WrappedPage.tsx | 252 ++++++------------ .../Dashboard/Wrapped/WrappedShareModal.tsx | 3 +- 15 files changed, 488 insertions(+), 233 deletions(-) create mode 100644 app/src/components/Dashboard/Wrapped/Sections/WrappedError.tsx create mode 100644 app/src/components/Dashboard/Wrapped/Sections/WrappedLoading.tsx create mode 100644 app/src/components/Dashboard/Wrapped/WrappedGradient.tsx diff --git a/app/src/components/Dashboard/Wrapped/Sections/DayInParticular.tsx b/app/src/components/Dashboard/Wrapped/Sections/DayInParticular.tsx index f6ac987..f2926cf 100644 --- a/app/src/components/Dashboard/Wrapped/Sections/DayInParticular.tsx +++ b/app/src/components/Dashboard/Wrapped/Sections/DayInParticular.tsx @@ -100,7 +100,7 @@ export function DayInParticular({ }} > - - + + {' '} While everyone else was scrolling TikTok, you were busy{' '} @@ -126,7 +127,7 @@ export function EveryoneScrolling({ ]} wrapper="div" cursor - style={{ fontSize: '3.5vw', color: 'black', fontWeight: '600' }} + style={{ fontSize: '3.3vh', color: 'black', fontWeight: '600' }} /> diff --git a/app/src/components/Dashboard/Wrapped/Sections/FriendList.tsx b/app/src/components/Dashboard/Wrapped/Sections/FriendList.tsx index e0d5142..00ed50d 100644 --- a/app/src/components/Dashboard/Wrapped/Sections/FriendList.tsx +++ b/app/src/components/Dashboard/Wrapped/Sections/FriendList.tsx @@ -114,7 +114,7 @@ export function FriendList({ animate={controls} style={{ lineHeight: 1.2, marginTop: '8vh' }} > - + Your Top Friends @@ -129,7 +129,12 @@ export function FriendList({ delay: 0.2 + 0.1 * index, }} > - + #{index + 1} @@ -142,7 +147,7 @@ export function FriendList({ delay: 0.8 + 0.2 * index, }} > - + {friend} diff --git a/app/src/components/Dashboard/Wrapped/Sections/MostMessages.tsx b/app/src/components/Dashboard/Wrapped/Sections/MostMessages.tsx index 80ed0d6..5357843 100644 --- a/app/src/components/Dashboard/Wrapped/Sections/MostMessages.tsx +++ b/app/src/components/Dashboard/Wrapped/Sections/MostMessages.tsx @@ -93,7 +93,7 @@ export function MostMessages({ animate={controls} style={{ lineHeight: 1.2, display: 'flex', justifyContent: 'center' }} > - + These messages seem to be going to a select few friends... diff --git a/app/src/components/Dashboard/Wrapped/Sections/Overview.tsx b/app/src/components/Dashboard/Wrapped/Sections/Overview.tsx index ca8552d..552507e 100644 --- a/app/src/components/Dashboard/Wrapped/Sections/Overview.tsx +++ b/app/src/components/Dashboard/Wrapped/Sections/Overview.tsx @@ -294,8 +294,8 @@ export function Overview() { style={{ display: 'flex', justifyContent: 'center', margin: '24px 0' }} > - + Your Top Sent Emojis @@ -133,6 +133,7 @@ export function SentEmojiList({ fontSize="4xl" fontWeight="bold" style={{ width: '12vh' }} + color="blue.600" > #{index + 1} @@ -146,7 +147,7 @@ export function SentEmojiList({ delay: 0.8 + 0.2 * index, }} > - + {emoji.word} diff --git a/app/src/components/Dashboard/Wrapped/Sections/SentWordList.tsx b/app/src/components/Dashboard/Wrapped/Sections/SentWordList.tsx index 90264c6..195efa8 100644 --- a/app/src/components/Dashboard/Wrapped/Sections/SentWordList.tsx +++ b/app/src/components/Dashboard/Wrapped/Sections/SentWordList.tsx @@ -112,7 +112,7 @@ export function SentWordList({ animate={controls} style={{ lineHeight: 1.2, marginTop: '8vh' }} > - + Your Top Sent Words @@ -130,7 +130,12 @@ export function SentWordList({ delay: 0.2 + 0.1 * index, }} > - + #{index + 1} @@ -143,7 +148,7 @@ export function SentWordList({ delay: 0.8 + 0.2 * index, }} > - + {word.word} diff --git a/app/src/components/Dashboard/Wrapped/Sections/TopFriend.tsx b/app/src/components/Dashboard/Wrapped/Sections/TopFriend.tsx index 8135f84..fdd97ff 100644 --- a/app/src/components/Dashboard/Wrapped/Sections/TopFriend.tsx +++ b/app/src/components/Dashboard/Wrapped/Sections/TopFriend.tsx @@ -149,11 +149,11 @@ export function TopFriend({ delay: 4.4, }} > - + 🎉 @@ -178,7 +178,7 @@ export function TopFriend({ }} > - + Total Messages: {' '} @@ -219,7 +219,7 @@ export function TopFriend({ delay: 1.3, }} > - + Sent:{' '} {sentTotal.toLocaleString()} @@ -235,7 +235,7 @@ export function TopFriend({ delay: 2.3, }} > - + Received: {' '} @@ -253,7 +253,7 @@ export function TopFriend({ delay: 3.3, }} > - + Top Word: {' '} diff --git a/app/src/components/Dashboard/Wrapped/Sections/TopGroupChat.tsx b/app/src/components/Dashboard/Wrapped/Sections/TopGroupChat.tsx index a6d379d..541daef 100644 --- a/app/src/components/Dashboard/Wrapped/Sections/TopGroupChat.tsx +++ b/app/src/components/Dashboard/Wrapped/Sections/TopGroupChat.tsx @@ -130,7 +130,7 @@ export function TopGroupChat({ tweenDuration={1000} recycle={false} /> -
+
- + 🙌 @@ -179,7 +179,7 @@ export function TopGroupChat({ }} > - + Most Active: {' '} @@ -238,7 +238,7 @@ export function TopGroupChat({ delay: 1.3, }} > - + {mostActive.toLowerCase().trim() === 'you' ? 'You' : 'They'}{' '} Sent: diff --git a/app/src/components/Dashboard/Wrapped/Sections/WrappedError.tsx b/app/src/components/Dashboard/Wrapped/Sections/WrappedError.tsx new file mode 100644 index 0000000..082d1ce --- /dev/null +++ b/app/src/components/Dashboard/Wrapped/Sections/WrappedError.tsx @@ -0,0 +1,82 @@ +import { Box, Button, Spinner, Text } from '@chakra-ui/react'; +import { AnimatePresence, motion, useAnimationControls } from 'framer-motion'; +import { FiRefreshCcw } from 'react-icons/fi'; + +import LogoWithText from '../../../../../assets/LogoWithText.svg'; + +export function WrappedError({ + error, + onRetry, +}: { + error: string; + onRetry: () => void; +}) { + const controls = useAnimationControls(); + + return ( + + + + +
+ Left on Read +
+
+ + + Oops! Something went wrong... + + +
+ If this issue persists, please contact support. +
+ + Error Code: {error} + + + + +
+
+
+ ); +} diff --git a/app/src/components/Dashboard/Wrapped/Sections/WrappedIntro.tsx b/app/src/components/Dashboard/Wrapped/Sections/WrappedIntro.tsx index 1474507..d37228c 100644 --- a/app/src/components/Dashboard/Wrapped/Sections/WrappedIntro.tsx +++ b/app/src/components/Dashboard/Wrapped/Sections/WrappedIntro.tsx @@ -35,40 +35,60 @@ export function WrappedIntro({ height="100%" width="100%" style={{ - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', padding: '36px', borderRadius: 16, + position: 'relative', }} shadow="dark-lg" bgColor="purple.50" > - -
- Left on Read -
-
- - + +
+ Left on Read +
+
+ + + Wrapped + + + + + {startDate.toLocaleDateString()} -{' '} + {globalData.dateRange.latestDate.toLocaleDateString()} + + + - Wrapped -
-
- - - {startDate.toLocaleDateString()} -{' '} - {globalData.dateRange.latestDate.toLocaleDateString()} - + + #LeftOnReadWrapped + +
); diff --git a/app/src/components/Dashboard/Wrapped/Sections/WrappedLoading.tsx b/app/src/components/Dashboard/Wrapped/Sections/WrappedLoading.tsx new file mode 100644 index 0000000..7f0a5c2 --- /dev/null +++ b/app/src/components/Dashboard/Wrapped/Sections/WrappedLoading.tsx @@ -0,0 +1,80 @@ +import { Box, Spinner, Text } from '@chakra-ui/react'; +import { AnimatePresence, motion, useAnimationControls } from 'framer-motion'; + +import LogoWithText from '../../../../../assets/LogoWithText.svg'; + +export function WrappedLoading() { + const controls = useAnimationControls(); + + return ( + + + + +
+ Left on Read +
+
+ + + Wrapping your year... + + + + + + + + #LeftOnReadWrapped + + +
+
+
+ ); +} diff --git a/app/src/components/Dashboard/Wrapped/WrappedGradient.tsx b/app/src/components/Dashboard/Wrapped/WrappedGradient.tsx new file mode 100644 index 0000000..04bce88 --- /dev/null +++ b/app/src/components/Dashboard/Wrapped/WrappedGradient.tsx @@ -0,0 +1,152 @@ +import { Box, IconButton, theme as defaultTheme } from '@chakra-ui/react'; +import { ipcRenderer } from 'electron'; +import { motion, useAnimationControls } from 'framer-motion'; +import React, { useEffect, useMemo, useState } from 'react'; +import { FiChevronLeft, FiChevronRight } from 'react-icons/fi'; + +import { Gradient } from '../../Gradient'; + +export function WrappedGradient({ + theme, + children, +}: { + theme: 'blue' | 'purple' | 'green'; + children: React.ReactNode; +}) { + const blueControls = useAnimationControls(); + const purpleControls = useAnimationControls(); + const greenControls = useAnimationControls(); + + useEffect(() => { + const gradientPurple = new Gradient(); + const gradientBlue = new Gradient(); + const gradientGreen = new Gradient(); + // @ts-ignore + gradientPurple.initGradient('#gradient-canvas-purple'); + + // @ts-ignore + gradientBlue.initGradient('#gradient-canvas-blue'); + + // @ts-ignore + gradientGreen.initGradient('#gradient-canvas-green'); + }, []); + + useEffect(() => { + if (theme === 'blue') { + blueControls.start({ + opacity: 1, + }); + purpleControls.start({ + opacity: 0, + }); + greenControls.start({ + opacity: 0, + }); + } + + if (theme === 'purple') { + blueControls.start({ + opacity: 0, + }); + greenControls.start({ + opacity: 0, + }); + purpleControls.start({ + opacity: 1, + }); + } + + if (theme === 'green') { + blueControls.start({ + opacity: 0, + }); + purpleControls.start({ + opacity: 0, + }); + greenControls.start({ + opacity: 1, + }); + } + }, [theme, blueControls, purpleControls, greenControls]); + + return ( + + + + + + + + + + + {children} + + ); +} diff --git a/app/src/components/Dashboard/Wrapped/WrappedPage.tsx b/app/src/components/Dashboard/Wrapped/WrappedPage.tsx index 46bc26a..e49e57d 100644 --- a/app/src/components/Dashboard/Wrapped/WrappedPage.tsx +++ b/app/src/components/Dashboard/Wrapped/WrappedPage.tsx @@ -1,7 +1,7 @@ import { Box, IconButton, theme as defaultTheme } from '@chakra-ui/react'; import { ipcRenderer } from 'electron'; -import { motion, useAnimationControls } from 'framer-motion'; -import React, { useEffect, useMemo, useState } from 'react'; +import log from 'electron-log'; +import React, { useEffect, useState } from 'react'; import { FiChevronLeft, FiChevronRight } from 'react-icons/fi'; import { EngagementResult } from '../../../analysis/queries/EngagementQueries'; @@ -15,7 +15,7 @@ import { TopFriendsSimpleResult, } from '../../../analysis/queries/WrappedQueries/TopFriendsSimpleQuery'; import { GroupChatFilters } from '../../../constants/filters'; -import { Gradient } from '../../Gradient'; +import { logEvent } from '../../../utils/analytics'; import { useGlobalContext } from '../GlobalContext'; import { BusiestDay } from './Sections/BusiestDay'; import { DayInParticular } from './Sections/DayInParticular'; @@ -33,161 +33,22 @@ import { ThereWereFunnyMoments } from './Sections/ThereWereFunnyMoments'; import { TopFriend } from './Sections/TopFriend'; import { TopGroupChat } from './Sections/TopGroupChat'; import { TotalCount } from './Sections/TotalCount'; +import { WrappedError } from './Sections/WrappedError'; import { WrappedIntro } from './Sections/WrappedIntro'; import { WrappedIntroTexts } from './Sections/WrappedIntroTexts'; +import { WrappedLoading } from './Sections/WrappedLoading'; import { YouTexting } from './Sections/YouTexting'; +import { WrappedGradient } from './WrappedGradient'; export const DURATION_OF_SLIDE_IN_SECS = 10; -function WrappedGradient({ - theme, - children, -}: { - theme: 'blue' | 'purple' | 'green'; - children: React.ReactNode; -}) { - const blueControls = useAnimationControls(); - const purpleControls = useAnimationControls(); - const greenControls = useAnimationControls(); - - useEffect(() => { - const gradientPurple = new Gradient(); - const gradientBlue = new Gradient(); - const gradientGreen = new Gradient(); - // @ts-ignore - gradientPurple.initGradient('#gradient-canvas-purple'); - - // @ts-ignore - gradientBlue.initGradient('#gradient-canvas-blue'); - - // @ts-ignore - gradientGreen.initGradient('#gradient-canvas-green'); - }, []); - - useEffect(() => { - if (theme === 'blue') { - blueControls.start({ - opacity: 1, - }); - purpleControls.start({ - opacity: 0, - }); - greenControls.start({ - opacity: 0, - }); - } - - if (theme === 'purple') { - blueControls.start({ - opacity: 0, - }); - greenControls.start({ - opacity: 0, - }); - purpleControls.start({ - opacity: 1, - }); - } - - if (theme === 'green') { - blueControls.start({ - opacity: 0, - }); - purpleControls.start({ - opacity: 0, - }); - greenControls.start({ - opacity: 1, - }); - } - }, [theme, blueControls, purpleControls, greenControls]); - - return ( - - - - - - - - - - - {children} - - ); -} - export function WrappedPage() { const { dateRange } = useGlobalContext(); - const [activeIndex, setActiveIndex] = useState(18); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + + const [activeIndex, setActiveIndex] = useState(0); const [activeTheme, setActiveTheme] = useState<'blue' | 'purple' | 'green'>( 'purple' ); @@ -231,8 +92,12 @@ export function WrappedPage() { : oneYearAgoDate; // TODO(Danilowicz): set up loading? - useEffect(() => { - async function fetchData() { + + async function fetchData() { + setIsLoading(true); + setError(null); + + try { const sentVsReceivedDataPromise: Promise = ipcRenderer.invoke('query-total-sent-vs-received', { startDate, @@ -356,23 +221,23 @@ export function WrappedPage() { ?.total ?? 0, }); setTopFriendWordAndCount(topFriendWordAndCountResult); + } catch (err: unknown) { + log.error(err); + if (err instanceof Error) { + setError(err.message); + } else { + setError('Internal Error'); + } + } finally { + setIsLoading(false); } + } + + useEffect(() => { fetchData(); // eslint-disable-next-line }, []); - useEffect(() => { - if (activeIndex === 7) { - setActiveTheme('purple'); - } else if (activeIndex === 8) { - setActiveTheme('blue'); - } else if (activeIndex === 17) { - setActiveTheme('blue'); - } else if (activeIndex === 18) { - setActiveTheme('green'); - } - }, [activeIndex]); - // TODO: Refactor this - this is getting pretty expensive bc of re-renders. const components = [ , ]; - const selectedComponent = components[activeIndex]; - - const iconSize = 50; - useEffect(() => { const handleKeyPress = (event: any) => { + if (isLoading) { + return; + } + switch (event.keyCode) { case 37: if (activeIndex > 0) { @@ -545,6 +410,53 @@ export function WrappedPage() { // eslint-disable-next-line }, [activeIndex]); + useEffect(() => { + logEvent({ + eventName: 'WRAPPED_SECTION', + properties: { + page: activeIndex, + }, + }); + + if (activeIndex === 7) { + setActiveTheme('purple'); + } else if (activeIndex === 8) { + setActiveTheme('blue'); + } else if (activeIndex === 17) { + setActiveTheme('blue'); + } else if (activeIndex === 18) { + setActiveTheme('green'); + } + }, [activeIndex]); + + let selectedComponent = components[activeIndex]; + if (error) { + selectedComponent = ( + { + fetchData(); + }} + /> + ); + } else if (isLoading) { + selectedComponent = ; + } + + const iconSize = 50; + + let showLeftIcon: 'hidden' | undefined = + activeIndex === 0 ? 'hidden' : undefined; + if (isLoading || error) { + showLeftIcon = 'hidden'; + } + + let showRightIcon: 'hidden' | undefined = + activeIndex === components.length - 1 ? 'hidden' : undefined; + if (isLoading || error) { + showRightIcon = 'hidden'; + } + return ( } fontSize={iconSize} - visibility={activeIndex === 0 ? 'hidden' : undefined} + visibility={showLeftIcon} /> } fontSize={iconSize} - visibility={ - activeIndex === components.length - 1 ? 'hidden' : undefined - } + visibility={showRightIcon} /> diff --git a/app/src/components/Dashboard/Wrapped/WrappedShareModal.tsx b/app/src/components/Dashboard/Wrapped/WrappedShareModal.tsx index ddc69fb..2a9f7e9 100644 --- a/app/src/components/Dashboard/Wrapped/WrappedShareModal.tsx +++ b/app/src/components/Dashboard/Wrapped/WrappedShareModal.tsx @@ -12,11 +12,10 @@ import { Stack, Text, theme as defaultTheme, - useDisclosure, } from '@chakra-ui/react'; import download from 'downloadjs'; import electron from 'electron'; -import { toBlob, toJpeg, toPixelData, toPng, toSvg } from 'html-to-image'; +import { toPng } from 'html-to-image'; import { useEffect, useState } from 'react'; import { FiDownload,