This commit is contained in:
Maciej Caderek
2022-02-22 03:26:31 +01:00
parent 34b352c6c4
commit 2baf02dd60
16 changed files with 151 additions and 119 deletions

View File

@@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="favicon.svg" /> <link rel="icon" type="image/svg+xml" href="favicon.svg" />
<meta <meta
name="viewport" name="viewport"
content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/> />
<link <link
rel="stylesheet" rel="stylesheet"

View File

@@ -203,7 +203,7 @@ const main = async () => {
); );
const $board = document.querySelector<HTMLImageElement>("#board"); const $board = document.querySelector<HTMLImageElement>("#board");
$board?.appendChild(board.canvas); $board?.prepend(board.canvas);
/* Restore game from the url */ /* Restore game from the url */
@@ -219,6 +219,9 @@ const main = async () => {
)); ));
/* Register events */ /* Register events */
document.addEventListener("dblclick", function (el) {
el.preventDefault();
});
if (!state.mobile) { if (!state.mobile) {
const keyMapping: { [key: string]: () => void } = { const keyMapping: { [key: string]: () => void } = {

View File

@@ -30,6 +30,8 @@ const initialGameConfig: GameConfig = {
animationSize: "M", animationSize: "M",
}; };
export type TabName = "game" | "load" | "share" | "boards" | "pieces";
export type State = { export type State = {
boardConfig: BoardConfig; boardConfig: BoardConfig;
gameConfig: GameConfig; gameConfig: GameConfig;
@@ -39,7 +41,8 @@ export type State = {
moves: string[]; moves: string[];
ply: number; ply: number;
mobile: boolean; mobile: boolean;
activeTab: "game" | "load"; layout: "single" | "double" | "triple";
activeTab: TabName;
playing: boolean; playing: boolean;
}; };
@@ -56,6 +59,7 @@ const initialState: State = {
moves: [], moves: [],
ply: 0, ply: 0,
mobile, mobile,
layout: mobile ? "single" : "triple",
activeTab: "load", activeTab: "load",
playing: false, playing: false,
}; };

View File

@@ -188,6 +188,12 @@ a:hover {
.board-box { .board-box {
height: auto; height: auto;
padding: var(--header-height) 0 1rem 0;
font-size: 0;
}
.board {
border-radius: 0;
} }
.setup-box { .setup-box {

View File

@@ -1,12 +1,13 @@
import type { Component } from "solid-js"; import { Component, Show } from "solid-js";
import type { DeepReadonly } from "solid-js/store"; import type { DeepReadonly } from "solid-js/store";
import { Handlers } from "../types"; import { Handlers } from "../types";
import { State } from "../state"; import { State, state } from "../state";
import Header from "./components/Header"; import Header from "./components/Header";
import GameTabs from "./components/GameTabs"; import GameTabs from "./components/GameTabs";
import SetupTabs from "./components/SetupTabs"; import SetupTabs from "./components/SetupTabs";
import Controls from "./components/Controls";
import "./App.css"; import "./App.css";
@@ -17,10 +18,16 @@ const App: Component<{ handlers: Handlers; state: DeepReadonly<State> }> = (
<> <>
<Header handlers={props.handlers} /> <Header handlers={props.handlers} />
<div class="layout"> <div class="layout">
<Show when={state.layout === "triple"}>
<div id="setup" class="setup-box"> <div id="setup" class="setup-box">
<SetupTabs handlers={props.handlers}></SetupTabs> <SetupTabs handlers={props.handlers}></SetupTabs>
</div> </div>
<div id="board" class="board-box"></div> </Show>
<div id="board" class="board-box">
<Show when={state.layout === "single"}>
<Controls handlers={props.handlers} />
</Show>
</div>
<div id="moves" class="game-box"> <div id="moves" class="game-box">
<GameTabs <GameTabs
moves={props.state.moves} moves={props.state.moves}

View File

@@ -46,13 +46,13 @@ const prepareBoards = async () => {
return boards; return boards;
}; };
const Boards: Component<{ handlers: Handlers }> = (props) => { const Boards: Component<{ handlers: Handlers; class?: string }> = (props) => {
const [boards, setBoards] = createSignal<BoardPreview[]>([]); const [boards, setBoards] = createSignal<BoardPreview[]>([]);
prepareBoards().then((data) => setBoards(data)); prepareBoards().then((data) => setBoards(data));
return ( return (
<Scrollable class="boards"> <Scrollable class={"boards" + (props.class ? ` ${props.class}` : "")}>
<For each={boards()}> <For each={boards()}>
{(board) => { {(board) => {
return ( return (

View File

@@ -8,39 +8,24 @@
@media screen and (max-width: 1024px) { @media screen and (max-width: 1024px) {
.game-box { .game-box {
height: auto; padding: 0;
height: 800px;
} }
} }
.game-tabs { .game {
height: 100%; height: 100%;
display: grid; display: grid;
grid-template-rows: 38px 195px 1fr 84px; grid-template-rows: 38px 195px 1fr 84px;
} }
.game-tabs__btn { .game-tabs {
width: 48%; display: grid;
border-bottom-left-radius: 0; grid-auto-flow: column;
border-bottom-right-radius: 0; grid-template-columns: 1fr 1fr;
height: 38px; column-gap: 0.5rem;
background: var(--color-tab);
} }
.game-tabs__btn:hover { .span3 {
background: var(--color-tab-light); grid-row-end: span 3;
}
.game-tabs__btn--active {
width: 50%;
background: var(--color-bg-block);
color: var(--color-text);
cursor: default;
}
.game-tabs__btn--active:hover {
background: var(--color-bg-block);
}
.game-tabs__btn:nth-child(1) {
margin-right: 2%;
} }

View File

@@ -1,36 +1,55 @@
import { Component, Switch, Match } from "solid-js"; import { Component, Switch, Match, Show } from "solid-js";
import Moves from "./Moves"; import Moves from "./Moves";
import Controls from "./Controls"; import Controls from "./Controls";
import Info from "./Info"; import Info from "./Info";
import Load from "./Load"; import Load from "./Load";
import Share from "./Share";
import Boards from "./Boards";
import Pieces from "./Pieces";
import Tab from "./reusable/Tab";
import { Handlers } from "../../types"; import { Handlers } from "../../types";
import { setState, state, TabName } from "../../state";
import "./GameTabs.css"; import "./GameTabs.css";
import { setState, state } from "../../state";
const setTab = (tab: TabName) => {
setState("activeTab", tab);
};
const GameTabs: Component<{ moves: readonly string[]; handlers: Handlers }> = ( const GameTabs: Component<{ moves: readonly string[]; handlers: Handlers }> = (
props props
) => { ) => {
return ( return (
<div class="game">
<div class="game-tabs"> <div class="game-tabs">
<div class="tabs"> <Tab name="game" setTab={setTab} isActive={state.activeTab === "game"}>
<button
class={
"game-tabs__btn" +
(state.activeTab === "game" ? " game-tabs__btn--active" : "")
}
onClick={() => setState("activeTab", "game")}
>
GAME GAME
</button> </Tab>
<button <Tab name="load" setTab={setTab} isActive={state.activeTab === "load"}>
class={
"game-tabs__btn" +
(state.activeTab === "load" ? " game-tabs__btn--active" : "")
}
onClick={() => setState("activeTab", "load")}
>
LOAD LOAD
</button> </Tab>
<Show when={state.layout !== "triple"}>
<Tab
name="share"
setTab={setTab}
isActive={state.activeTab === "share"}
>
<i class="las la-share"></i>
</Tab>
<Tab
name="boards"
setTab={setTab}
isActive={state.activeTab === "boards"}
>
<i class="las la-chess-board"></i>
</Tab>
<Tab
name="pieces"
setTab={setTab}
isActive={state.activeTab === "pieces"}
>
<i class="las la-chess"></i>
</Tab>
</Show>
</div> </div>
<Switch> <Switch>
<Match when={state.activeTab === "game"}> <Match when={state.activeTab === "game"}>
@@ -39,8 +58,19 @@ const GameTabs: Component<{ moves: readonly string[]; handlers: Handlers }> = (
<Controls handlers={props.handlers} /> <Controls handlers={props.handlers} />
</Match> </Match>
<Match when={state.activeTab === "load"}> <Match when={state.activeTab === "load"}>
<Load handlers={props.handlers} /> <Load handlers={props.handlers} class="span3" />
</Match> </Match>
<Show when={state.layout !== "triple"}>
<Match when={state.activeTab === "share"}>
<Share handlers={props.handlers} class="span3" />
</Match>
<Match when={state.activeTab === "boards"}>
<Boards handlers={props.handlers} class="span3" />
</Match>
<Match when={state.activeTab === "pieces"}>
<Pieces handlers={props.handlers} class="span3" />
</Match>
</Show>
</Switch> </Switch>
</div> </div>
); );

View File

@@ -3,7 +3,6 @@
padding: 20px; padding: 20px;
border-bottom-left-radius: 5px; border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px; border-bottom-right-radius: 5px;
grid-row-end: span 3;
} }
.load__pgn-input { .load__pgn-input {

View File

@@ -4,7 +4,7 @@ import readFile from "../../utils/readFile";
import { state } from "../../state"; import { state } from "../../state";
import "./Load.css"; import "./Load.css";
const Load: Component<{ handlers: Handlers }> = (props) => { const Load: Component<{ handlers: Handlers; class?: string }> = (props) => {
const [fen, setFEN] = createSignal(""); const [fen, setFEN] = createSignal("");
const [pgn, setPGN] = createSignal(""); const [pgn, setPGN] = createSignal("");
const [link, setLink] = createSignal(""); const [link, setLink] = createSignal("");
@@ -12,7 +12,7 @@ const Load: Component<{ handlers: Handlers }> = (props) => {
let filePicker: HTMLInputElement | undefined = undefined; let filePicker: HTMLInputElement | undefined = undefined;
return ( return (
<div class="load"> <div class={"load" + (props.class ? ` ${props.class}` : "")}>
<input <input
class="load__fen-input" class="load__fen-input"
type="text" type="text"

View File

@@ -10,9 +10,9 @@ const pieces = Object.entries(piecesSets).map(([key, data]) => ({
img: data.nw, img: data.nw,
})) as { key: PiecesStyle; img: string }[]; })) as { key: PiecesStyle; img: string }[];
const Pieces: Component<{ handlers: Handlers }> = (props) => { const Pieces: Component<{ handlers: Handlers; class?: string }> = (props) => {
return ( return (
<Scrollable class="pieces"> <Scrollable class={"pieces" + (props.class ? ` ${props.class}` : "")}>
{ {
<For each={pieces}> <For each={pieces}>
{(item) => ( {(item) => (

View File

@@ -6,12 +6,6 @@
min-width: 375px; min-width: 375px;
} }
@media screen and (max-width: 1024px) {
.setup-box {
height: auto;
}
}
.setup { .setup {
font-size: 1.6rem; font-size: 1.6rem;
height: 100%; height: 100%;
@@ -19,29 +13,9 @@
grid-template-rows: 38px 1fr; grid-template-rows: 38px 1fr;
} }
.setup-tabs__btn { .setup-tabs {
width: 32%; display: grid;
border-bottom-left-radius: 0; grid-auto-flow: column;
border-bottom-right-radius: 0; grid-template-columns: 1fr 1fr 1fr;
height: 38px; column-gap: 0.5rem;
background: var(--color-tab);
}
.setup-tabs__btn:hover {
background: var(--color-tab-light);
}
.setup-tabs__btn--active {
background: var(--color-bg-block);
color: var(--color-text);
cursor: default;
}
.setup-tabs__btn--active:hover {
background: var(--color-bg-block);
}
.setup-tabs__btn:nth-child(1),
.setup-tabs__btn:nth-child(2) {
margin-right: 2%;
} }

View File

@@ -4,6 +4,7 @@ import "./SetupTabs.css";
import Share from "./Share"; import Share from "./Share";
import Boards from "./Boards"; import Boards from "./Boards";
import Pieces from "./Pieces"; import Pieces from "./Pieces";
import Tab from "./reusable/Tab";
const SetupTabs: Component<{ const SetupTabs: Component<{
handlers: Handlers; handlers: Handlers;
@@ -12,34 +13,16 @@ const SetupTabs: Component<{
return ( return (
<div class="setup"> <div class="setup">
<div class="tabs"> <div class="setup-tabs">
<button <Tab name="share" setTab={setTab} isActive={tab() === "share"}>
class={
"setup-tabs__btn" +
(tab() === "share" ? " setup-tabs__btn--active" : "")
}
onClick={() => setTab("share")}
>
<i class="las la-share"></i> SHARE <i class="las la-share"></i> SHARE
</button> </Tab>
<button <Tab name="boards" setTab={setTab} isActive={tab() === "boards"}>
class={
"setup-tabs__btn" +
(tab() === "boards" ? " setup-tabs__btn--active" : "")
}
onClick={() => setTab("boards")}
>
<i class="las la-chess-board"></i> BOARDS <i class="las la-chess-board"></i> BOARDS
</button> </Tab>
<button <Tab name="pieces" setTab={setTab} isActive={tab() === "pieces"}>
class={
"setup-tabs__btn" +
(tab() === "pieces" ? " setup-tabs__btn--active" : "")
}
onClick={() => setTab("pieces")}
>
<i class="las la-chess"></i> PIECES <i class="las la-chess"></i> PIECES
</button> </Tab>
</div> </div>
<Switch> <Switch>
<Match when={tab() === "share"}> <Match when={tab() === "share"}>

View File

@@ -5,7 +5,7 @@ import { state, setState } from "../../state";
import "./Share.css"; import "./Share.css";
import download from "../../utils/download"; import download from "../../utils/download";
const Share: Component<{ handlers: Handlers }> = (props) => { const Share: Component<{ handlers: Handlers; class?: string }> = (props) => {
const [copyId, setCopyId] = createSignal(""); const [copyId, setCopyId] = createSignal("");
const [imageRendering, setImageRendering] = createSignal(false); const [imageRendering, setImageRendering] = createSignal(false);
const [animationRendering, setAnimationRendering] = createSignal(false); const [animationRendering, setAnimationRendering] = createSignal(false);
@@ -16,7 +16,7 @@ const Share: Component<{ handlers: Handlers }> = (props) => {
}; };
return ( return (
<Scrollable class="share"> <Scrollable class={"share" + (props.class ? ` ${props.class}` : "")}>
<div className="share__view"> <div className="share__view">
<h2 class="header--first">Board options</h2> <h2 class="header--first">Board options</h2>
<button <button

View File

@@ -0,0 +1,21 @@
.tab {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
height: 38px;
background: var(--color-tab);
min-width: 4rem;
}
.tab:hover {
background: var(--color-tab-light);
}
.tab--active {
background: var(--color-bg-block);
color: var(--color-text);
cursor: default;
}
.tab--active:hover {
background: var(--color-bg-block);
}

View File

@@ -0,0 +1,20 @@
import { Component } from "solid-js";
import "./Tab.css";
import { TabName } from "../../../state";
const Tab: Component<{
name: TabName;
setTab: (name: TabName) => void;
isActive: boolean;
}> = (props) => {
return (
<button
class={"tab" + (props.isActive ? " tab--active" : "")}
onClick={() => props.setTab(props.name)}
>
{props.children}
</button>
);
};
export default Tab;