import WebFont from "webfontloader";
import * as Hammer from "hammerjs";
import { render } from "solid-js/web";
import { BoardStyle, PiecesStyle } from "./types";
import Board from "./board/Board";
import Game from "./game/Game";
import Player from "./player/Player";
import App from "./ui/App";
import { state, setState } from "./state";
import createImage from "./encoders/createImage";
import createAnimation from "./encoders/createAnimation";
import readFile from "./utils/readFile";
import download from "./utils/download";
import { compressPGN } from "./game/PGNHelpers";
import extractUrlData from "./persistance/extractUrlData";
import importFromLink from "./imports/importFromLink";
const main = async () => {
const board = new Board(state.boardConfig);
const player = new Player(board, state.gameConfig);
/* Register handlers */
const handlers = {
prev() {
player.pause();
player.prev();
},
next() {
player.pause();
player.next();
},
first() {
player.pause();
player.first();
},
last() {
player.pause();
player.last();
},
toggleBorder() {
board.toggleBorder();
setState("boardConfig", "showBorder", !state.boardConfig.showBorder);
},
showBorder() {
board.showBorder();
setState("boardConfig", "showBorder", true);
},
hideBorder() {
board.hideBorder();
setState("boardConfig", "showBorder", false);
},
toggleExtraInfo() {
board.toggleExtraInfo();
setState(
"boardConfig",
"showExtraInfo",
!state.boardConfig.showExtraInfo
);
},
toggleAnonymous() {
setState("boardConfig", "anonymous", !state.boardConfig.anonymous);
board.updateConfig({ anonymous: state.boardConfig.anonymous });
},
toggleTitleScreen() {
setState("gameConfig", "titleScreen", !state.gameConfig.titleScreen);
},
flip() {
console.log("FLIP");
board.flip();
setState("boardConfig", "flipped", !state.boardConfig.flipped);
},
togglePlay() {
player.playing ? player.pause() : player.play();
},
goto(ply: number) {
player.pause();
player.goto(ply);
},
changeBoardStyle(style: BoardStyle) {
board.setStyle(style);
setState("boardConfig", "boardStyle", style);
},
changePiecesStyle(style: PiecesStyle) {
board.setPiecesStyle(style);
setState("boardConfig", "piecesStyle", style);
},
async loadPGN(pgn: string) {
const game = new Game().loadPGN(pgn);
setState({
pgn: game.pgn,
fen: "",
moves: game.getMoves(),
ply: 0,
game,
});
window.location.hash = `v1/pgn/${compressPGN(game.pgn)}`;
await player.load(game);
setState("activeTab", "game");
},
async loadFEN(fen: string) {
const game = new Game().loadFEN(fen);
setState({ pgn: "", fen, moves: game.getMoves(), ply: 0, game });
await player.load(game);
},
async importPGN(link: string) {
const result = await importFromLink(link);
if (result.error) {
return;
}
await this.loadPGN(result.pgn);
},
async downloadImage() {
const data = await createImage(
state.fen,
state.pgn,
state.ply,
state.boardConfig,
state.gameConfig.picSize
);
download(data, "fen", "png");
},
async downloadAnimation() {
const data = await createAnimation(
state.pgn,
state.boardConfig,
state.gameConfig.format,
state.gameConfig.animationSize
);
download(data, "game", state.gameConfig.format.toLowerCase());
},
};
/* Render the page */
render(
() => ,
document.getElementById("root") as HTMLElement
);
const $board = document.querySelector("#board");
$board?.appendChild(board.canvas);
/* Restore game from the url */
const { pgn, fen } = extractUrlData();
await (pgn
? handlers.loadPGN(pgn)
: fen
? handlers.loadFEN(fen)
: handlers.loadFEN(
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
));
/* Register events */
const keyMapping: { [key: string]: () => void } = {
ArrowLeft: handlers.prev,
ArrowRight: handlers.next,
ArrowUp: handlers.first,
ArrowDown: handlers.last,
" ": handlers.togglePlay,
b: handlers.toggleBorder,
f: handlers.flip,
e: handlers.toggleExtraInfo,
};
document.addEventListener("keydown", (e) => {
const target = e.target as HTMLElement | null;
if (
keyMapping[e.key] &&
target?.nodeName !== "INPUT" &&
target?.nodeName !== "TEXTAREA"
) {
keyMapping[e.key]();
}
});
const preventDefaults = (e: Event) => {
e.preventDefault();
e.stopPropagation();
};
["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => {
document.addEventListener(eventName, preventDefaults, false);
});
document.addEventListener("drop", async (e) => {
if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {
const content = await readFile(e.dataTransfer.files[0]);
handlers.loadPGN(content);
}
});
const hammer = new Hammer.Manager(board.canvas);
hammer.add(new Hammer.Swipe());
hammer.add(new Hammer.Pinch());
hammer.add(new Hammer.Press({ time: 500 }));
hammer.add(new Hammer.Tap({ taps: 1 }));
hammer.on("swiperight", handlers.next);
hammer.on("swipeleft", handlers.prev);
hammer.on("swipeup", handlers.first);
hammer.on("swipedown", handlers.last);
hammer.on("pinchin", handlers.showBorder);
hammer.on("pinchout", handlers.hideBorder);
hammer.on("tap", handlers.next);
hammer.on("press", handlers.flip);
};
/* Boot */
WebFont.load({
google: {
families: ["Ubuntu:500,700", "Fira Mono"],
},
custom: {
families: ["Chess"],
urls: ["/fonts.css"],
},
active: main,
});