perf: reactive updates

This commit is contained in:
TrèsAbhi committed 2025-10-14 20:15:00 -05:00
1 parent 222b690fba
commit ff4a87e5b8
3 files changed
+48 -47

No files matched your search

@@ -1,11 +1,9 @@
import { Box, Flex } from "@radix-ui/themes"; import { Box, Flex } from "@radix-ui/themes";
import { useLocale } from "../hooks/useLocale";
import { CurrentlyPlaying } from "./CurrentlyPlaying"; import { CurrentlyPlaying } from "./CurrentlyPlaying";
import { PlaylistActions } from "./PlaylistActions"; import { PlaylistActions } from "./PlaylistActions";
import { PlaylistTable } from "./PlaylistTable"; import { PlaylistTable } from "./PlaylistTable";
export function PlaylistOrder() { export function PlaylistOrder() {
return ( return (
<Flex <Flex
direction="column" direction="column"
@@ -1,5 +1,6 @@
import { MinusCircledIcon } from "@radix-ui/react-icons"; import { MinusCircledIcon } from "@radix-ui/react-icons";
import { Checkbox, IconButton, Table } from "@radix-ui/themes"; import { Checkbox, IconButton, Table } from "@radix-ui/themes";
import { memo } from "react";
import { useLocale } from "../hooks/useLocale"; import { useLocale } from "../hooks/useLocale";
import { Playlist, type PlaylistEntry } from "../stores/playlist"; import { Playlist, type PlaylistEntry } from "../stores/playlist";
import { TankRowHeaderCell } from "./TankRowHeaderCell"; import { TankRowHeaderCell } from "./TankRowHeaderCell";
@@ -8,55 +9,57 @@ interface Props extends PlaylistEntry {
index: number; index: number;
} }
export function PlaylistTankEntry({ export const PlaylistTankEntry = memo<Props>(
tank, ({ tank, checked, last, battles, index }) => {
checked, const { locale, strings } = useLocale();
last, const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
battles, const nowDays = Date.now() / (1000 * 60 * 60 * 24);
index, const lastDays = last ? last / (60 * 60 * 24) : undefined;
}: Props) {
const { locale, strings } = useLocale();
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
const nowDays = Date.now() / (1000 * 60 * 60 * 24);
const lastDays = last ? last / (60 * 60 * 24) : undefined;
return ( return (
<Table.Row> <Table.Row>
<Table.Cell>{index + 1}</Table.Cell> <Table.Cell>{index + 1}</Table.Cell>
<TankRowHeaderCell tank={tank} /> <TankRowHeaderCell tank={tank} />
<Table.Cell> <Table.Cell>
{lastDays {lastDays
? rtf.format(Math.floor(lastDays - nowDays), "day") ? rtf.format(Math.floor(lastDays - nowDays), "day")
: strings.website.tools.playlist.table.never} : strings.website.tools.playlist.table.never}
</Table.Cell> </Table.Cell>
<Table.Cell>{battles}</Table.Cell> <Table.Cell>{battles}</Table.Cell>
<Table.Cell <Table.Cell
onClick={() => {
Playlist.mutate((draft) => {
draft.list![index].checked = !checked;
});
}}
>
<Checkbox variant="classic" checked={checked} />
</Table.Cell>
<Table.Cell>
<IconButton
variant="ghost"
size="1"
onClick={() => { onClick={() => {
Playlist.mutate((draft) => { Playlist.mutate((draft) => {
draft.list!.splice(index, 1); draft.list![index].checked = !checked;
}); });
}} }}
> >
<MinusCircledIcon /> <Checkbox variant="classic" checked={checked} />
</IconButton> </Table.Cell>
</Table.Cell>
</Table.Row> <Table.Cell>
); <IconButton
} variant="ghost"
size="1"
onClick={() => {
Playlist.mutate((draft) => {
draft.list!.splice(index, 1);
});
}}
>
<MinusCircledIcon />
</IconButton>
</Table.Cell>
</Table.Row>
);
},
(a, b) =>
a.checked === b.checked &&
a.battles === b.battles &&
a.last === b.last &&
a.wins === b.wins &&
a.index === b.index
);
@@ -16,7 +16,7 @@ export function Page({
locale, locale,
skeleton, skeleton,
}: Props & MaybeSkeletonComponentProps) { }: Props & MaybeSkeletonComponentProps) {
const list = Playlist.use((state) => state.list); const generated = Playlist.use((state) => state.list !== undefined);
const wargaming = App.use((state) => state.logins.wargaming); const wargaming = App.use((state) => state.logins.wargaming);
useEffect(() => { useEffect(() => {
@@ -30,8 +30,8 @@ export function Page({
return ( return (
<LocaleProvider locale={locale}> <LocaleProvider locale={locale}>
<PageWrapper color="tomato" direction="row" maxWidth="unset" p="0"> <PageWrapper color="tomato" direction="row" maxWidth="unset" p="0">
{!list && <PlaylistGenerator />} {!generated && <PlaylistGenerator />}
{list && <PlaylistOrder />} {generated && <PlaylistOrder />}
</PageWrapper> </PageWrapper>
</LocaleProvider> </LocaleProvider>
); );