From cce19cf04b6871505f1438ce554e689442a8f734 Mon Sep 17 00:00:00 2001 From: Manu Artero Anguita Date: Wed, 14 Dec 2022 14:01:43 +0100 Subject: [PATCH] feat: save GameContext on localStorage (no UI) --- src/@types/storming.d.ts | 8 +++++++ src/App.tsx | 11 ++++++--- src/components/index.ts | 2 ++ src/components/menu/menu-icon.svg | 17 ++++++++++++++ src/components/menu/menu.scss | 7 ++++++ src/components/menu/menu.tsx | 32 +++++++++++++++++++++++++ src/services/db.ts | 39 +++++++++++++++++++++++++++++++ 7 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 src/components/menu/menu-icon.svg create mode 100644 src/components/menu/menu.scss create mode 100644 src/components/menu/menu.tsx create mode 100644 src/services/db.ts diff --git a/src/@types/storming.d.ts b/src/@types/storming.d.ts index cd15717..8afd78d 100644 --- a/src/@types/storming.d.ts +++ b/src/@types/storming.d.ts @@ -157,3 +157,11 @@ interface GameContext { firstPlayer(player: Player): void; skip(): void; } + +// ---- + +type Savegame = { + date: string; + empireSize: number; + gameContext: GameContext; +} diff --git a/src/App.tsx b/src/App.tsx index d73e163..7656428 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,11 @@ import { - Board, LogPanel, - Marketplace, PlayerHand, RoundSummary, - TimeLine + Board, + LogPanel, + Marketplace, + Menu, + PlayerHand, + RoundSummary, + TimeLine, } from "components"; import { GameContextProvider } from "contexts"; import { StrictMode } from "react"; @@ -14,6 +18,7 @@ function App() {
+ diff --git a/src/components/index.ts b/src/components/index.ts index 6a3a703..dc22920 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -4,3 +4,5 @@ export { default as LogPanel } from "./log-panel/log-panel"; export { default as RoundSummary } from "./round-summary/round-summary"; export { default as TimeLine } from "./timeline/timeline-controller"; export { default as Marketplace } from "./marketplace/marketplace"; + +export { Menu } from "./menu/menu"; diff --git a/src/components/menu/menu-icon.svg b/src/components/menu/menu-icon.svg new file mode 100644 index 0000000..953f1bb --- /dev/null +++ b/src/components/menu/menu-icon.svg @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/src/components/menu/menu.scss b/src/components/menu/menu.scss new file mode 100644 index 0000000..802947e --- /dev/null +++ b/src/components/menu/menu.scss @@ -0,0 +1,7 @@ +.menu { + position: absolute; + top: 0; + right: 0; + width: 32px; + background-color: rgba(0, 0, 0, 0.5); +} diff --git a/src/components/menu/menu.tsx b/src/components/menu/menu.tsx new file mode 100644 index 0000000..53820b2 --- /dev/null +++ b/src/components/menu/menu.tsx @@ -0,0 +1,32 @@ +import { logRender } from "utils/console"; +import { savegame } from "services/db"; +import MenuIcon from "./menu-icon.svg"; +import { useGameContext } from "contexts"; + +import "./menu.scss"; + +export function Menu(): JSX.Element { + logRender("Menu"); + + const gameContext = useGameContext(); + + const saveHandler = () => { + savegame(gameContext); + }; + + const loadHandler = () => { + // TODO + }; + + return ( +
+ Menu Icon { + console.log("clicked"); + }} + /> +
+ ); +} diff --git a/src/services/db.ts b/src/services/db.ts new file mode 100644 index 0000000..b3cb289 --- /dev/null +++ b/src/services/db.ts @@ -0,0 +1,39 @@ +/* + * using local storage for now (up to 5MB) + * check if i need to use Indexed DB instead + */ + +import { empireSize } from "game-logic/empire-size"; +import { warnInconsistentState } from "utils/console"; + +export function savegame(gameContext: GameContext) { + const date = Date.now().toString(); + const playerEmpireSize = empireSize(gameContext.board).player; + const item: Savegame = { + date, + empireSize: playerEmpireSize, + gameContext, + }; + try { + window.localStorage.setItem(date, JSON.stringify(item)); + } catch (e) { + warnInconsistentState(`error while saving game context: ${e}`); + return undefined; + } + return date; +} + +export function listSavegames() { + return Object.keys(window.localStorage); +} + +export function loadSavegame(date: string): Savegame | undefined { + const raw = window.localStorage.getItem(date); + if (!raw) { + warnInconsistentState( + `trying to load game context with key ${key} but no data found` + ); + return undefined; + } + return JSON.parse(raw); +}