mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
perf: reactive updates
This commit is contained in:
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>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in new issue
Block a user