From ee9dbdaf74b9cf6168b6ab3af82513dc8d629a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Sun, 1 Sep 2024 17:41:50 -0500 Subject: [PATCH] feat: better loading --- .../MetaSection/components/Votes/index.tsx | 44 ++++++++++----- .../MetaSection/components/VotesSkeleton.tsx | 55 ------------------- .../components/Model/MetaSection/index.tsx | 11 ++-- .../Model/TechTreeSection/index.tsx | 20 +++---- src/hooks/useTankVotes.ts | 45 +++++++-------- 5 files changed, 65 insertions(+), 110 deletions(-) delete mode 100644 src/app/tools/tankopedia/[id]/components/Model/MetaSection/components/VotesSkeleton.tsx diff --git a/src/app/tools/tankopedia/[id]/components/Model/MetaSection/components/Votes/index.tsx b/src/app/tools/tankopedia/[id]/components/Model/MetaSection/components/Votes/index.tsx index f0f25b76b..4f1fc68c4 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/MetaSection/components/Votes/index.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/MetaSection/components/Votes/index.tsx @@ -1,4 +1,4 @@ -import { Flex, Heading, Text } from '@radix-ui/themes'; +import { Flex, Heading, Skeleton, Text } from '@radix-ui/themes'; import { memo } from 'react'; import { WargamingLoginButton } from '../../../../../../../../../components/Navbar/components/WargamingLoginButton'; import { formatCompact } from '../../../../../../../../../core/math/formatCompact'; @@ -19,9 +19,11 @@ export const Votes = memo( return ( - + - {formatCompact(votes.votes)} {votes.votes === 1 ? 'vote' : 'votes'} + {!votes && } + {votes && formatCompact(votes.votes)}{' '} + {votes && (votes.votes > 1 ? 'votes' : 'vote')} {!wargaming && ( @@ -37,8 +39,14 @@ export const Votes = memo( gap={{ initial: '0', sm: '6' }} direction={{ initial: 'column', sm: 'row' }} > - - + + - {wargaming && ( - + + <> - {votes.last_updated - ? `You voted on ${new Date(votes.last_updated).toLocaleDateString()}` - : `You haven't voted yet`} + {votes ? ( + wargaming ? ( + votes.last_updated ? ( + `You voted on ${new Date(votes.last_updated).toLocaleDateString()}` + ) : ( + `You haven't voted yet` + ) + ) : ( + 'Login to vote' + ) + ) : ( + + )} - )} + ); diff --git a/src/app/tools/tankopedia/[id]/components/Model/MetaSection/components/VotesSkeleton.tsx b/src/app/tools/tankopedia/[id]/components/Model/MetaSection/components/VotesSkeleton.tsx deleted file mode 100644 index 3c567f776..000000000 --- a/src/app/tools/tankopedia/[id]/components/Model/MetaSection/components/VotesSkeleton.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { PaperPlaneIcon } from '@radix-ui/react-icons'; -import { Button, Flex, Heading, Skeleton, Text } from '@radix-ui/themes'; -import { WargamingLoginButton } from '../../../../../../../../components/Navbar/components/WargamingLoginButton'; -import * as App from '../../../../../../../../stores/app'; - -export function VotesSkeleton() { - const wargaming = App.useDeferred( - undefined, - (state) => state.logins.wargaming, - ); - - return ( - - - - - - - {!wargaming && ( - - Login to vote - - )} - {wargaming && ( - - )} - - - - - - Easiness - - - - Firepower - - - - - - Maneuverability - - - - Survivability - - - - - - ); -} diff --git a/src/app/tools/tankopedia/[id]/components/Model/MetaSection/index.tsx b/src/app/tools/tankopedia/[id]/components/Model/MetaSection/index.tsx index de21f6ff3..9911023cf 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/MetaSection/index.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/MetaSection/index.tsx @@ -1,6 +1,5 @@ import { ChevronLeftIcon, MixIcon } from '@radix-ui/react-icons'; import { Button, Code, Flex } from '@radix-ui/themes'; -import { Suspense } from 'react'; import { classIcons } from '../../../../../../../components/ClassIcon'; import { Link } from '../../../../../../../components/Link'; import { asset } from '../../../../../../../core/blitzkit/asset'; @@ -9,7 +8,6 @@ import * as App from '../../../../../../../stores/app'; import * as Duel from '../../../../../../../stores/duel'; import { Listing } from './components/Listing'; import { Votes } from './components/Votes'; -import { VotesSkeleton } from './components/VotesSkeleton'; export function MetaSection() { const developerMode = App.useDeferred(false, (state) => state.developerMode); @@ -40,7 +38,10 @@ export function MetaSection() { - + {protagonist.nameFull && ( {protagonist.nameFull} @@ -139,9 +140,7 @@ export function MetaSection() { - }> - - + ); diff --git a/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/index.tsx b/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/index.tsx index 0ac640b39..bb305add6 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/index.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/index.tsx @@ -1,6 +1,6 @@ import { CaretLeftIcon, CaretRightIcon, PlusIcon } from '@radix-ui/react-icons'; import { Flex, Heading, IconButton, ScrollArea, Text } from '@radix-ui/themes'; -import { use, useEffect, useMemo, useRef, useState } from 'react'; +import { Fragment, use, useEffect, useMemo, useRef, useState } from 'react'; import { asset } from '../../../../../../../core/blitzkit/asset'; import { imgur } from '../../../../../../../core/blitzkit/imgur'; import { tankDefinitions } from '../../../../../../../core/blitzkit/tankDefinitions'; @@ -128,6 +128,7 @@ export function TechTreeSection() { return ( - {index > 0 && } + + {index > 0 && } - + ); })} @@ -180,14 +180,14 @@ export function TechTreeSection() { <> {master.successors!.map((id, index) => ( - <> + {index > 0 && ( - + )} - - + + ))} )} diff --git a/src/hooks/useTankVotes.ts b/src/hooks/useTankVotes.ts index b7d004749..dec1694e1 100644 --- a/src/hooks/useTankVotes.ts +++ b/src/hooks/useTankVotes.ts @@ -1,4 +1,4 @@ -import { use, useMemo } from 'react'; +import { useEffect, useState } from 'react'; import { TankVotes } from '../app/api/tank-voting/[id]/average/route'; import { unwrapBlitzkitResponse } from '../core/blitzkit/unwrapBlitzkitResponse'; import * as App from '../stores/app'; @@ -20,32 +20,25 @@ const cache: Record | TankVotes> = {}; export function useTankVotes(id: number) { const wargaming = App.use((state) => state.logins.wargaming); - const promise = useMemo( - () => - new Promise((resolve) => { - if (id in cache) { - resolve(cache[id]); - } else { - const cacheable = fetch( - `http://localhost:3000/api/tank-voting/${id}/average${ - wargaming - ? `?player=${wargaming.id}&token=${wargaming.token}` - : '' - }`, - ) - .then( - (response) => - response.json() as Promise>, - ) - .then(unwrapBlitzkitResponse); - cacheable.then(resolve); + const [votes, setVotes] = useState(null); - cache[id] = cacheable; - } - }), - [id, wargaming], - ); - const votes = use(promise); + useEffect(() => { + if (id in cache) { + Promise.all([cache[id]]).then(([votes]) => setVotes(votes)); + } else { + const cacheable = fetch( + `/api/tank-voting/${id}/average${ + wargaming ? `?player=${wargaming.id}&token=${wargaming.token}` : '' + }`, + ) + .then( + (response) => response.json() as Promise>, + ) + .then(unwrapBlitzkitResponse); + cacheable.then(setVotes); + cache[id] = cacheable; + } + }, [id, wargaming]); return votes; }