Skip to content

Commit

Permalink
feat: reimplement pgn & fen copy fields -> move to sidebar -> fix pgn…
Browse files Browse the repository at this point in the history
… copy when starting fen is provided
  • Loading branch information
kevinjosethomas committed Dec 13, 2024
1 parent 9d388c6 commit 7c5302b
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 27 deletions.
17 changes: 15 additions & 2 deletions src/components/Board/GameplayInterface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,15 @@ export const GameplayInterface: React.FC<Props> = (
>
{Info}
</GameInfo>
<StatsDisplay stats={stats} hideSession={true} />
<div className="flex w-full flex-col gap-2">
<ExportGame
game={game}
whitePlayer={whitePlayer ?? 'Unknown'}
blackPlayer={blackPlayer ?? 'Unknown'}
maiaVersion={maiaTitle}
/>
<StatsDisplay stats={stats} hideSession={true} />
</div>
</div>
<div className="relative flex aspect-square w-full max-w-[75vh]">
<GameBoard
Expand Down Expand Up @@ -224,7 +232,6 @@ export const GameplayInterface: React.FC<Props> = (
) : null}
</div>
</div>
<ExportGame moves={game.moves.slice(0, controller.currentIndex + 1)} />
</div>
</>
)
Expand Down Expand Up @@ -266,6 +273,12 @@ export const GameplayInterface: React.FC<Props> = (
</div>
<div className="w-screen">{props.children}</div>
<StatsDisplay stats={stats} hideSession={true} />
<ExportGame
game={game}
whitePlayer={whitePlayer ?? 'Unknown'}
blackPlayer={blackPlayer ?? 'Unknown'}
maiaVersion={maiaTitle}
/>
</div>
</div>
</div>
Expand Down
111 changes: 88 additions & 23 deletions src/components/Misc/ExportGame.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,117 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
import { Chess } from 'chess.ts'
import { useEffect, useState } from 'react'
import { useContext, useEffect, useState } from 'react'

import { Move } from 'src/types'
import { Move, PlayedGame } from 'src/types'
import { GameControllerContext } from 'src/contexts'

interface Props {
moves: Move[]
game: PlayedGame
whitePlayer: string
blackPlayer: string
maiaVersion: string
}

export const ExportGame: React.FC<Props> = ({ moves }) => {
export const ExportGame: React.FC<Props> = ({
game,
whitePlayer,
blackPlayer,
maiaVersion,
}) => {
const [fen, setFen] = useState('')
const [pgn, setPgn] = useState('')
const { currentIndex } = useContext(GameControllerContext)

useEffect(() => {
const chess = new Chess()
moves.forEach((move) => {
game.moves.forEach((move) => {
if (move.san) {
chess.move(move.san)
}
})
setPgn(chess.pgn())
}, [moves])
}, [game.moves])

useEffect(() => {
const initial = new Chess(game.moves[0].board)
initial.addHeader('ID', game.id)
initial.addHeader('Event', `Play v. ${maiaVersion}`)
initial.addHeader('Site', `https://maiachess.com/`)
initial.addHeader('White', whitePlayer)
initial.addHeader('Black', blackPlayer)
if (game.termination) {
initial.addHeader('Result', game.termination.result)
if (game.termination.condition) {
initial.addHeader('Termination', game.termination.condition)
}
}
game.moves.forEach((move, index) => {
if (!move.san || index > currentIndex) {
return
}

initial.move(move.san)
})
setFen(game.moves[currentIndex].board)
setPgn(initial.pgn())
}, [currentIndex, game.moves])

const copy = (content: string) => {
navigator.clipboard.writeText(content)
}

return (
<div className="flex flex-row items-center justify-center gap-2">
<div className="flex h-10 items-center overflow-hidden rounded border border-primary/10 bg-background-1">
<div className="flex w-[500px] items-center justify-start bg-background-1 px-4">
<p className="whitespace-nowrap text-sm text-secondary">
{moves[moves.length - 1].board}
<div className="flex flex-col gap-1">
<div className="flex flex-col gap-0.5">
<div className="flex items-center justify-between">
<p className="select-none text-sm font-semibold tracking-wider text-secondary">
FEN
</p>
<i
tabIndex={0}
role="button"
onClick={() => copy(fen)}
className="material-symbols-outlined select-none text-base text-secondary hover:text-primary"
>
content_copy
</i>
</div>
<button
onClick={() => copy(moves[moves.length - 1].board)}
className="flex h-10 w-10 min-w-10 items-center justify-center border-l border-primary/10 bg-background-2 transition duration-200 hover:bg-background-3"
<div
role="button"
tabIndex={0}
onClick={() => copy(fen)}
className="border-1 group flex cursor-pointer overflow-x-hidden rounded border border-white/5 bg-background-1/50 px-4 py-2"
>
<span className="material-symbols-outlined text-xl">
<p className="whitespace-nowrap text-xs text-secondary group-hover:text-secondary/80">
{fen}
</p>
</div>
</div>
<div className="flex flex-col gap-0.5">
<div className="flex items-center justify-between">
<p className="select-none text-sm font-semibold tracking-wider text-secondary">
PGN
</p>
<i
tabIndex={0}
role="button"
onClick={() => copy(pgn)}
className="material-symbols-outlined select-none text-base text-secondary hover:text-primary"
>
content_copy
</span>
</button>
</i>
</div>
<div
role="button"
tabIndex={0}
onClick={() => copy(pgn)}
className="border-1 group flex cursor-pointer overflow-x-hidden rounded border border-white/5 bg-background-1/50 px-4 py-2"
>
<p className="whitespace-pre-wrap text-xs text-secondary group-hover:text-secondary/80">
{pgn}
</p>
</div>
</div>
<button
onClick={() => copy(pgn)}
className="flex h-10 items-center justify-center rounded border border-primary/10 bg-background-2 px-4 py-1 transition duration-300 hover:bg-background-3"
>
Copy PGN
</button>
</div>
)
}
2 changes: 0 additions & 2 deletions src/hooks/useStockfishEngine/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ class Engine {
}

if (!isNaN(mate) && isNaN(cp)) {
console.log(msg)
console.log(this.fen)
cp = mate > 0 ? 10000 : -10000
}

Expand Down

0 comments on commit 7c5302b

Please sign in to comment.