This commit is contained in:
Maciej Caderek
2022-02-07 18:49:17 +01:00
parent 4fa2ba1fb9
commit f2d6c080d4
20 changed files with 1749 additions and 127 deletions

29
src/ui/App.tsx Normal file
View File

@@ -0,0 +1,29 @@
import type { Component } from "solid-js";
import type { DeepReadonly } from "solid-js/store";
import Moves from "./components/Moves";
import Controls from "./components/Controls";
import Load from "./components/Load";
import { Handlers } from "../types";
import { State } from "../state";
import "./app.css";
const App: Component<{ handlers: Handlers; state: DeepReadonly<State> }> = (
props
) => {
return (
<div class="layout">
<div id="setup" class="setup-box"></div>
<div id="board" class="board-box"></div>
<div id="controls" class="controls-box">
<Controls handlers={props.handlers}></Controls>
</div>
<div id="moves" class="moves-box">
{/* <Moves moves={props.state.moves} handlers={props.handlers}></Moves> */}
<Load></Load>
</div>
</div>
);
};
export default App;

View File

@@ -1,38 +0,0 @@
import { Handlers } from "./../types";
import { html } from "common-tags";
class Controls {
constructor(private element: HTMLElement, handlers: Handlers) {
this.element.addEventListener("click", (e) => {
const target = e.target as HTMLElement;
if (target?.dataset?.type === "control") {
const action = target?.dataset?.action;
console.log(action);
if (action && handlers.hasOwnProperty(action)) {
// @ts-ignore
handlers[action]();
}
}
});
}
load() {
const content = html`<div class="controls">
<button data-type="control" data-action="first">FIRST</button>
<button data-type="control" data-action="prev">PREV</button>
<button data-type="control" data-action="togglePlay">PLAY/PAUSE</button>
<button data-type="control" data-action="next">NEXT</button>
<button data-type="control" data-action="last">LAST</button>
<button data-type="control" data-action="flip">FLIP</button>
<button data-type="control" data-action="toggleBorder">TOGGLE BORDER</button>
<button data-type="control" data-action="toggleExtraInfo">TOGGLE EXTRA INFO</button>
</ul> `;
this.element.innerHTML = content;
return this;
}
}
export default Controls;

View File

@@ -1,36 +0,0 @@
import { html } from "common-tags";
import Player from "../player/Player";
import chunk_ from "@arrows/array/chunk_";
class Moves {
constructor(private element: HTMLElement, private player: Player) {
this.element.addEventListener("click", (e) => {
const target = e.target as HTMLElement;
if (target?.dataset?.type === "ply") {
const ply = Number(target?.dataset?.ply);
this.player.goto(ply);
}
});
}
load(moves: string[]) {
const items = chunk_(2, moves).map(
([white, black], i) =>
html`<p>
${i + 1}. <span data-type="ply" data-ply=${i * 2 + 1}>${white}</span>
<span data-type="ply" data-ply=${i * 2 + 2}>${black}</span>
</p>`
);
const content = html`<div class="moves">
${items.join("\n")}
</ul> `;
this.element.innerHTML = content;
return this;
}
}
export default Moves;

118
src/ui/app.css Normal file
View File

@@ -0,0 +1,118 @@
@font-face {
font-family: "Chess";
src: url("chess.ttf") format("ttf");
}
* {
border: 0;
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 10px;
}
body {
background-repeat: repeat;
background-position: center;
text-align: center;
}
.dark {
background-color: #191d24;
background-image: url(src/ui/img/pattern.png);
color: #ddd;
}
.light {
background-color: #cfcfcf;
background-image: url(src/ui/img/pattern-light.png);
color: #222;
}
.board {
/* width: 600px;
height: 600px;
width: 800px;
height: 800px; */
/* width: 1024px;
height: 1024px; */
box-shadow: 0 0 30px rgba(0, 0, 0, 0.5);
border-radius: 5px;
max-width: 100%;
max-height: 95vh;
}
.layout {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-template-areas:
"setup board controls"
"setup board moves";
}
.moves-box {
/* background: rgba(255, 192, 203, 0.1); */
height: 85vh;
grid-area: moves;
}
.board-box {
/* background: rgba(255, 166, 0, 0.1); */
height: 100vh;
grid-area: board;
}
.setup-box {
/* background: rgba(135, 207, 235, 0.1); */
height: 100vh;
grid-area: setup;
}
.controls-box {
/* background: rgba(0, 255, 0, 0.1); */
height: 15vh;
grid-area: controls;
}
.controls__button {
margin: 5px;
padding: 5px;
cursor: pointer;
}
.moves {
padding: 20px;
}
.move {
display: inline-block;
width: 50%;
min-width: 150px;
text-align: left;
}
.ply {
padding-left: 10px;
cursor: pointer;
}
@media screen and (max-width: 1024px) {
.layout {
grid-template-columns: 1fr;
}
.moves-box {
height: auto;
}
.board-box {
height: auto;
}
.setup-box {
height: auto;
}
}

View File

@@ -0,0 +1,35 @@
import { Component } from "solid-js";
import { Handlers } from "../../types";
const Controls: Component<{ handlers: Handlers }> = (props) => {
return (
<div class="controls">
<button class="controls__button" onClick={props.handlers.first}>
FIRST
</button>
<button class="controls__button" onClick={props.handlers.prev}>
PREV
</button>
<button class="controls__button" onClick={props.handlers.togglePlay}>
PLAY/PAUSE
</button>
<button class="controls__button" onClick={props.handlers.next}>
NEXT
</button>
<button class="controls__button" onClick={props.handlers.last}>
LAST
</button>
<button class="controls__button" onClick={props.handlers.flip}>
FLIP
</button>
<button class="controls__button" onClick={props.handlers.toggleBorder}>
TOGGLE BORDER
</button>
<button class="controls__button" onClick={props.handlers.toggleExtraInfo}>
TOGGLE EXTRA INFO
</button>
</div>
);
};
export default Controls;

View File

@@ -0,0 +1,26 @@
import { Component, For } from "solid-js";
import chunk_ from "@arrows/array/chunk_";
import { Handlers } from "../../types";
import "./load.css";
const Load: Component<{}> = (props) => {
return (
<div class="load">
<input
class="load__fen-input"
type="text"
name="load-fen"
placeholder="PASTE FEN..."
/>
<button class="load__fen-btn">LOAD FEN</button>
<textarea
class="load__pgn-input"
name="load-pgn"
placeholder="PASTE PGN..."
></textarea>
<button class="load__pgn-btn">LOAD PGN</button>
</div>
);
};
export default Load;

View File

@@ -0,0 +1,37 @@
import { Component, For } from "solid-js";
import chunk_ from "@arrows/array/chunk_";
import { Handlers } from "../../types";
const Moves: Component<{ moves: readonly string[]; handlers: Handlers }> = (
props
) => {
return (
<div class="moves">
<For each={chunk_(2, props.moves as string[])}>
{(move, i) => {
const [white, black] = move as [string, string];
return (
<p class="move">
{i() + 1}.
<span
class="ply"
onClick={() => props.handlers.goto(i() * 2 + 1)}
>
{white}
</span>
<span
class="ply"
onClick={() => props.handlers.goto(i() * 2 + 2)}
>
{black}
</span>
</p>
);
}}
</For>
</div>
);
};
export default Moves;

View File

@@ -0,0 +1,26 @@
.load {
background: black;
padding: 20px;
}
.load__fen-input {
width: 100%;
padding: 10px;
font-family: "Fira Mono";
font-size: 1.4rem;
}
.load__pgn-input {
width: 100%;
padding: 10px;
font-family: "Fira Mono";
font-size: 1.4rem;
}
.load__fen-btn,
.load__pgn-btn {
width: 100%;
padding: 10px;
font-family: "Fira Mono";
font-size: 1.4rem;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
src/ui/img/pattern.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB