Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add option to show multiple games from a PGN #31

Closed
wants to merge 12 commits into from
96 changes: 91 additions & 5 deletions demo/demo.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion demo/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
Expand All @@ -21,6 +21,7 @@
<div><div></div></div>
<div><div></div></div>
<div><div></div></div>
<div><div></div></div>
</div>
<script src="lichess-pgn-viewer.js" type="module"></script>
<script src="demo.js" type="module"></script>
Expand Down
157 changes: 89 additions & 68 deletions scss/_layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,109 +13,127 @@ $board-min-width: 200px !default;

--controls-height: #{$controls-height};
&--controls-false {
--controls-height: 0em;
--controls-height: 0;
}

--select-height: 0;
&--select {
--select-height: $player-height;
}

&--moves-false {
grid-template-areas:
'board'
'controls';
grid-template-columns: minmax(200px, calc(100vh - var(--controls-height)));
grid-template-rows: auto var(--controls-height);
grid-template:
'select' var(--select-height)
'board' auto
'controls' var(--controls-height)
/ minmax(200px, calc(100vh - var(--controls-height)));
}

&--moves-right {
grid-template-areas:
'board side'
'controls side';
grid-template-columns: auto $grid-side-column;
grid-template-rows: auto var(--controls-height);
grid-template:
'board select' var(--select-height)
'board side' auto
'controls side' var(--controls-height)
/ auto $grid-side-column;
}

&--moves-bottom {
grid-template-areas:
'board'
'controls'
'side';
grid-template-rows: auto var(--controls-height);
grid-template:
'select' var(--select-height)
'board' auto
'controls' var(--controls-height)
'side' auto
/ auto;
.lpv__controls {
border-bottom: 1px solid $lpv-border;
}
}

&--moves-auto {
grid-template-areas:
'board side'
'controls side';
grid-template-columns: minmax($board-min-width, calc(100vh - var(--controls-height))) $grid-side-column-full-screen;
grid-template-rows: auto var(--controls-height);
grid-template:
'board select' var(--select-height)
'board side' auto
'controls side' var(--controls-height)
/ minmax($board-min-width, calc(100vh - var(--controls-height))) $grid-side-column-full-screen;
@media (max-width: #{$moves-auto-to-right}) {
grid-template-areas:
'board'
'controls'
'side';
grid-template-columns: minmax(
$board-min-width,
calc(100vh - var(--controls-height) - #{$grid-side-row})
);
grid-template-rows: auto var(--controls-height);
grid-template:
'select' var(--select-height)
'board' auto
'controls' var(--controls-height)
'side' auto
/ minmax($board-min-width, calc(100vh - var(--controls-height) - #{$grid-side-row}));
}
}

&--players {
&.lpv--moves-false {
grid-template-areas:
'player-top'
'board'
'player-bot'
'controls';
grid-template-rows: $player-height auto $player-height var(--controls-height);
grid-template:
'select' var(--select-height)
'player-top' $player-height
'board' auto
'player-bot' $player-height
'controls' var(--controls-height)
/ auto;
}

&.lpv--moves-right {
grid-template-areas:
'player-top side'
'board side'
'player-bot side'
'controls side';
grid-template-rows: $player-height auto $player-height var(--controls-height);
grid-template:
'player-top side' $player-height
'board side' auto
'player-bot side' $player-height
'controls side' var(--controls-height)
/ auto auto;

&.lpv--select {
grid-template-areas:
'player-top select'
'board side'
'player-bot side'
'controls side';
}
}

&.lpv--moves-bottom {
grid-template-areas:
'player-top'
'board'
'player-bot'
'controls'
'side';
grid-template-rows: $player-height auto $player-height var(--controls-height);
grid-template:
'select' var(--select-height)
'player-top' $player-height
'board' auto
'player-bot' $player-height
'controls' var(--controls-height)
'side' auto
/ auto;
.lpv__controls {
border-bottom: 1px solid $lpv-border;
}
}

&.lpv--moves-auto {
grid-template-areas:
'player-top side'
'board side'
'player-bot side'
'controls side';
grid-template-columns:
minmax($board-min-width, calc(100vh - 2 * #{$player-height} - var(--controls-height)))
grid-template:
'player-top side' $player-height
'board side' auto
'player-bot side' $player-height
'controls side' var(--controls-height)
/ minmax($board-min-width, calc(100vh - 2 * #{$player-height} - var(--controls-height)))
$grid-side-column-full-screen;
grid-template-rows: $player-height auto $player-height var(--controls-height);
@media (max-width: #{$moves-auto-to-right}) {
&.lpv--select {
grid-template-areas:
'player-top'
'board'
'player-bot'
'controls'
'side';
grid-template-columns: minmax(
$board-min-width,
calc(100vh - 2 * #{$player-height} - var(--controls-height) - #{$grid-side-row})
);
grid-template-rows: $player-height auto $player-height var(--controls-height);
'player-top select'
'board side'
'player-bot side'
'controls side';
}
@media (max-width: #{$moves-auto-to-right}) {
grid-template:
'select' var(--select-height)
'player-top' $player-height
'board' auto
'player-bot' $player-height
'controls' var(--controls-height)
'side' auto
/ minmax(
$board-min-width,
calc(100vh - 2 * #{$player-height} - var(--controls-height) - #{$grid-side-row})
);
}
}
}
Expand All @@ -135,6 +153,9 @@ $board-min-width: 200px !default;
&__controls {
grid-area: controls;
}
&__select {
grid-area: select;
}
&__menu,
&__pgn {
grid-area: 1 / 1 / 2 / 2;
Expand Down
1 change: 1 addition & 0 deletions scss/_lichess-pgn-viewer.lib.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ $lpv-interesting: hsl(307, 80%, 70%) !default;
@import './controls';
@import './scrollbar';
@import './font';
@import './select';

.lpv {
border-radius: 5px;
Expand Down
7 changes: 7 additions & 0 deletions scss/_select.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.lpv__select {
background: inherit;
font: inherit;
color: inherit;
border: none;
cursor: pointer;
}
2 changes: 0 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Opts } from './interfaces';

const defaults: Opts = {
pgn: '*', // the PGN to render
fen: undefined, // initial FEN, will append [FEN "initial FEN"] to the PGN
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gotta keep that somehow

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's just keep the current behavior of adding the fen to the first game.

showPlayers: 'auto', // show the players above and under the board
showClocks: true, // show the clocks alongside the players
showMoves: 'auto', // false | "right" | "bottom" | auto. "auto" uses media queries
Expand All @@ -25,7 +24,6 @@ const defaults: Opts = {
export default function (element: HTMLElement, cfg: Partial<Opts>) {
const opts = { ...defaults };
deepMerge(opts, cfg);
if (opts.fen) opts.pgn = `[FEN "${opts.fen}"]\n${opts.pgn}`;
if (!opts.classes) opts.classes = element.className;
return opts;
}
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export interface Metadata {
increment: number;
};
orientation?: Color;
name: string;
}

export interface Player {
Expand Down Expand Up @@ -78,7 +79,6 @@ export type Lichess = string | false;

export interface Opts {
pgn: string;
fen?: string;
chessground: CgConfig;
orientation?: Color;
showPlayers: ShowPlayers;
Expand Down
7 changes: 5 additions & 2 deletions src/pgn.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { expect, test } from '@jest/globals';
import { isNormal, parseSquare } from 'chessops';
import { makeGame } from './pgn';
import { makeGame as makeGameFromPgnGame } from './pgn';
import { parsePgn } from 'chessops/pgn';

const makeGame = (pgn: string) => makeGameFromPgnGame(parsePgn(pgn)[0] ?? parsePgn('*'));

test('single move pgn', () => {
const lastMove = makeGame('e4')!.moves.children[0].data;
Expand Down Expand Up @@ -35,7 +38,7 @@ test('longer mainline', () => {
expect(lastMove.path.path).toBe('/?UE)8\\M.>E>8>aP$5WG>DVN%ISKD3TD5F`WIPWP-5_b3-PI+;D;,4;4->4,>M,c');
});
test('initial position', () => {
expect(makeGame('').initial.pos.fullmoves).toBe(1);
expect(makeGame('*').initial.pos.fullmoves).toBe(1);
expect(makeGame('1. e4 c5 2. Nf3').initial.pos.fullmoves).toBe(1);
expect(
makeGame('[FEN "rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq - 1 2"]').initial.pos.fullmoves,
Expand Down
17 changes: 14 additions & 3 deletions src/pgn.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Color, makeUci, Position } from 'chessops';
import { scalachessCharPair } from 'chessops/compat';
import { makeFen } from 'chessops/fen';
import { parsePgn, parseComment, PgnNodeData, startingPosition, transform, Node } from 'chessops/pgn';
import { parseComment, PgnNodeData, startingPosition, transform, Node, Game as PgnGame } from 'chessops/pgn';
import { makeSanAndPlay, parseSan } from 'chessops/san';
import { Game } from './game';
import { MoveData, Initial, Players, Player, Comments, Metadata, Clocks, Lichess } from './interfaces';
Expand All @@ -28,8 +28,7 @@ export const parseComments = (strings: string[]): Comments => {
};
};

export const makeGame = (pgn: string, lichess: Lichess = false): Game => {
const game = parsePgn(pgn)[0] || parsePgn('*')[0];
export const makeGame = (game: PgnGame<PgnNodeData>, lichess: Lichess = false): Game => {
const start = startingPosition(game.headers).unwrap();
const fen = makeFen(start.toSetup());
const comments = parseComments(game.comments || []);
Expand Down Expand Up @@ -135,5 +134,17 @@ function makeMetadata(headers: Headers, lichess: Lichess): Metadata {
isLichess: !!(lichess && site?.startsWith(lichess)),
timeControl,
orientation: orientation === 'white' || orientation === 'black' ? orientation : undefined,
name: makeGameName(headers),
};
}

const makeGameName = (h: Headers): string => {
const event = h.get('event');
const players = ['white', 'black']
.map(c => [h.get(c), h.get(c + 'title'), h.get(c + 'elo')])
.map(([name, title, rating]) =>
name ? `${title ? `${title} ` : ''}${name}${rating ? ` (${rating})` : ''}` : undefined,
)
.filter(x => !!x);
return players.length == 2 ? players.join(' vs ') : event ?? '?';
};
Loading
Loading