feat : add lichess user games import

This commit is contained in:
GuillaumeSD
2024-03-17 18:57:22 +01:00
parent f9cb5acc1f
commit 46198f2a47
7 changed files with 147 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
import { useLocalStorage } from "@/hooks/useLocalStorage";
import { getUserRecentGames } from "@/lib/chessCom";
import { getChessComUserRecentGames } from "@/lib/chessCom";
import { capitalize } from "@/lib/helpers";
import { ChessComGame } from "@/types/chessCom";
import {
@@ -33,7 +33,7 @@ export default function ChessComInput({ pgn, setPgn }: Props) {
const timeout = setTimeout(
async () => {
const games = await getUserRecentGames(chessComUsername);
const games = await getChessComUserRecentGames(chessComUsername);
setGames(games);
},
requestCount === 0 ? 0 : 500

View File

@@ -0,0 +1,101 @@
import { useLocalStorage } from "@/hooks/useLocalStorage";
import { getLichessUserRecentGames } from "@/lib/lichess";
import { capitalize } from "@/lib/helpers";
import { LichessGame } from "@/types/lichess";
import {
CircularProgress,
FormControl,
Grid,
ListItemButton,
ListItemText,
TextField,
} from "@mui/material";
import { useEffect, useState } from "react";
interface Props {
pgn: string;
setPgn: (pgn: string) => void;
}
export default function LichessInput({ pgn, setPgn }: Props) {
const [requestCount, setRequestCount] = useState(0);
const [lichessUsername, setLichessUsername] = useLocalStorage(
"lichess-username",
""
);
const [games, setGames] = useState<LichessGame[]>([]);
useEffect(() => {
if (!lichessUsername) {
setGames([]);
return;
}
const timeout = setTimeout(
async () => {
const games = await getLichessUserRecentGames(lichessUsername);
setGames(games);
},
requestCount === 0 ? 0 : 500
);
setRequestCount((prev) => prev + 1);
return () => {
clearTimeout(timeout);
};
}, [lichessUsername]); // eslint-disable-line react-hooks/exhaustive-deps
return (
<>
<FormControl sx={{ m: 1, width: 300 }}>
<TextField
label="Enter your Lichess username..."
variant="outlined"
value={lichessUsername ?? ""}
onChange={(e) => setLichessUsername(e.target.value)}
/>
</FormControl>
{lichessUsername && (
<Grid
container
item
xs={12}
gap={2}
justifyContent="center"
alignContent="center"
minHeight={100}
>
{games.map((game) => (
<ListItemButton
onClick={() => setPgn(game.pgn)}
selected={pgn === game.pgn}
style={{ width: 350, maxWidth: 350 }}
key={game.id}
>
<ListItemText
primary={`${
capitalize(game.players.white.user?.name || "white") ||
"White"
} (${game.players?.white?.rating || "?"}) vs ${
capitalize(game.players.black.user?.name || "black") ||
"Black"
} (${game.players?.black?.rating || "?"})`}
secondary={`${capitalize(game.speed)} played at ${new Date(
game.lastMoveAt
)
.toLocaleString()
.slice(0, -3)}`}
primaryTypographyProps={{ noWrap: true }}
secondaryTypographyProps={{ noWrap: true }}
/>
</ListItemButton>
))}
{games.length === 0 && <CircularProgress />}
</Grid>
)}
</>
);
}

View File

@@ -20,6 +20,7 @@ import { useState } from "react";
import GamePgnInput from "./gamePgnInput";
import ChessComInput from "./chessComInput";
import { useLocalStorage } from "@/hooks/useLocalStorage";
import LichessInput from "./lichessInput";
interface Props {
open: boolean;
@@ -105,6 +106,10 @@ export default function NewGameDialog({ open, onClose, setGame }: Props) {
<ChessComInput pgn={pgn} setPgn={setPgn} />
)}
{gameOrigin === GameOrigin.Lichess && (
<LichessInput pgn={pgn} setPgn={setPgn} />
)}
{parsingError && (
<FormControl fullWidth>
<Typography color="red" textAlign="center" marginTop={1}>
@@ -133,4 +138,5 @@ export default function NewGameDialog({ open, onClose, setGame }: Props) {
const gameOriginLabel: Record<GameOrigin, string> = {
[GameOrigin.Pgn]: "PGN",
[GameOrigin.ChessCom]: "Chess.com",
[GameOrigin.Lichess]: "Lichess.org",
};