WIP
This commit is contained in:
29
src/ui/App.tsx
Normal file
29
src/ui/App.tsx
Normal 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;
|
||||
@@ -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;
|
||||
@@ -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
118
src/ui/app.css
Normal 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;
|
||||
}
|
||||
}
|
||||
35
src/ui/components/Controls.tsx
Normal file
35
src/ui/components/Controls.tsx
Normal 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;
|
||||
26
src/ui/components/Load.tsx
Normal file
26
src/ui/components/Load.tsx
Normal 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;
|
||||
37
src/ui/components/Moves.tsx
Normal file
37
src/ui/components/Moves.tsx
Normal 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;
|
||||
26
src/ui/components/load.css
Normal file
26
src/ui/components/load.css
Normal 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;
|
||||
}
|
||||
BIN
src/ui/img/pattern-light.png
Normal file
BIN
src/ui/img/pattern-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
BIN
src/ui/img/pattern.png
Normal file
BIN
src/ui/img/pattern.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Reference in New Issue
Block a user