From 6d080dceddcdde04d9df0b684394e76399628ab1 Mon Sep 17 00:00:00 2001 From: Halit Aksoy Date: Sat, 4 Jun 2022 19:26:40 +0300 Subject: [PATCH 1/4] add react-menu dependency --- package.json | 2 ++ yarn.lock | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 9201418..0a7d6c9 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "author": "", "license": "ISC", "dependencies": { + "@szhsin/react-menu": "^3.0.2", + "@types/": "szhsin/react-menu", "@types/uuid": "^8.3.4", "mancala.js": "^0.0.2-beta.2", "react": "^17.0.2", diff --git a/yarn.lock b/yarn.lock index f094108..812cc55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1011,6 +1011,21 @@ "@parcel/utils" "^1.11.0" physical-cpu-count "^2.0.0" +"@szhsin/react-menu@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@szhsin/react-menu/-/react-menu-3.0.2.tgz#d22971c53d56e6d404c9d3c98f533907cd8f03dc" + integrity sha512-m9Ly+cT+CxQx3xhq90CVaOLQWU7f7UKeMxfDt1gPYV23tDwEe8Zo6PO547qPlAEGEwwb9MdA38U8OyueXKJc2g== + dependencies: + prop-types "^15.7.2" + react-transition-state "^1.1.4" + +"@types/@szhsin/react-menu": + version "3.0.2" + resolved "https://codeload.github.com/szhsin/react-menu/tar.gz/28284b2183801fb4f6a95e9270ce580441c5da70" + dependencies: + prop-types "^15.7.2" + react-transition-state "^1.1.4" + "@types/prop-types@*": version "15.7.5" resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" @@ -3364,7 +3379,7 @@ log-symbols@^2.2.0: dependencies: chalk "^2.0.1" -loose-envify@^1.1.0: +loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -4333,6 +4348,15 @@ process@^0.11.10: resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +prop-types@^15.7.2: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + psl@^1.1.28: version "1.8.0" resolved "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz" @@ -4433,6 +4457,16 @@ react-dom@^17.0.2: object-assign "^4.1.1" scheduler "^0.20.2" +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-transition-state@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/react-transition-state/-/react-transition-state-1.1.4.tgz#113224eaa27e0ff81661305e44d5e0348cdf61ac" + integrity sha512-6nQLWWx95gYazCm6OdtD1zGbRiirvVXPrDtHAGsYb4xs9spMM7bA8Vx77KCpjL8PJ8qz1lXFGz2PTboCSvt7iw== + react@^17.0.2: version "17.0.2" resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz" From 0e48fe922823590971dde5789ac5ba83cf0a944d Mon Sep 17 00:00:00 2001 From: Halit Aksoy Date: Sat, 4 Jun 2022 19:27:13 +0300 Subject: [PATCH 2/4] add id and name to Theme --- src/theme/DefaultTheme.ts | 2 ++ src/theme/OldTheme.ts | 2 ++ src/theme/Theme.ts | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/theme/DefaultTheme.ts b/src/theme/DefaultTheme.ts index 4560c65..c5ec0d7 100644 --- a/src/theme/DefaultTheme.ts +++ b/src/theme/DefaultTheme.ts @@ -11,6 +11,8 @@ const colors = { const colorSpecial = "#F6A9A9"; const defaultTheme: Theme = { + id: "1", + name: "Default Light Theme", background: "#EEEEEE", appBarBgColor: colors.quaternary, primary: colors.primary, diff --git a/src/theme/OldTheme.ts b/src/theme/OldTheme.ts index a830781..139f824 100644 --- a/src/theme/OldTheme.ts +++ b/src/theme/OldTheme.ts @@ -1,6 +1,8 @@ import { Theme } from "./Theme"; const oldTheme: Theme = { + id: "0", + name: "Old Theme", background: "#EEEEEE", appBarBgColor: "rgb(228, 228, 228)", primary: "#4D606E", diff --git a/src/theme/Theme.ts b/src/theme/Theme.ts index 98038dc..e5a9653 100644 --- a/src/theme/Theme.ts +++ b/src/theme/Theme.ts @@ -1,4 +1,6 @@ export type Theme = { + id: string; + name: string; primary: string; primaryLight: string; background: string; From c5f1741d4b7cbb5def95d17f881c2f23a7b39b48 Mon Sep 17 00:00:00 2001 From: Halit Aksoy Date: Sat, 4 Jun 2022 19:28:57 +0300 Subject: [PATCH 3/4] save current theme to localStorage --- src/context.tsx | 3 +-- src/theme/ThemeManager.ts | 27 ++++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/context.tsx b/src/context.tsx index 140c840..0fd4cc5 100644 --- a/src/context.tsx +++ b/src/context.tsx @@ -2,7 +2,6 @@ import { Texts, TrTr } from "./const/texts"; import { RTMT } from "./rtmt/rtmt"; import { RTMTWS } from "./rtmt/rtmt_websocket"; import { UserKeyStore, UserKeyStoreImpl } from "./store/key_store"; -import defaultTheme from "./theme/DefaultTheme"; import ThemeManager from "./theme/ThemeManager"; export type Context = { @@ -16,7 +15,7 @@ export const initContext = () => { const rtmt = new RTMTWS(); const userKeyStore = new UserKeyStoreImpl(); const texts = TrTr; - const themeManager = new ThemeManager(defaultTheme); + const themeManager = new ThemeManager(); return { rtmt: rtmt, userKeyStore: userKeyStore, diff --git a/src/theme/ThemeManager.ts b/src/theme/ThemeManager.ts index 8d391aa..2b943d0 100644 --- a/src/theme/ThemeManager.ts +++ b/src/theme/ThemeManager.ts @@ -1,18 +1,39 @@ +import defaultTheme from "./DefaultTheme"; +import oldTheme from "./OldTheme"; import { Theme } from "./Theme"; +export const themes = [defaultTheme, oldTheme]; + +const THEME_ID = "theme_id"; + export default class ThemeManager { _theme: Theme; onThemeChange: (theme: Theme) => void; - constructor(theme: Theme) { - this._theme = theme; + constructor() { + this._theme = this.readFromLocalStorage() || defaultTheme; } public get theme() { return this._theme; } - public set theme(value) { + public set theme(value: Theme) { this._theme = value; this.onThemeChange?.(value); + this.writetToLocalStorage(value); + } + + private writetToLocalStorage(value: Theme) { + localStorage.setItem(THEME_ID, value.id); + } + + private readFromLocalStorage(): Theme { + const themeID = localStorage.getItem(THEME_ID); + const theme = themes.find((eachTheme: Theme) => themeID === eachTheme.id); + return theme; + } + + public get themes(): Theme[] { + return themes; } } From 6295d33add287c3c6cd41ab5ade99af641a71ddc Mon Sep 17 00:00:00 2001 From: Halit Aksoy Date: Sat, 4 Jun 2022 20:54:19 +0300 Subject: [PATCH 4/4] add theme chooser --- src/Home.tsx | 65 ++++++++++++++++++++++++++++++++++-- src/animation/PitAnimator.ts | 2 +- src/index.html | 2 ++ src/theme/OldTheme.ts | 2 +- 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/Home.tsx b/src/Home.tsx index c102865..109c9ca 100644 --- a/src/Home.tsx +++ b/src/Home.tsx @@ -18,6 +18,10 @@ import { GameMove } from "./models/GameMove"; import PitAnimator from "./animation/PitAnimator"; import BoardViewModel from "./viewmodel/BoardViewModel"; import { v4 } from "uuid"; +import { Menu, MenuButton, MenuItem } from "@szhsin/react-menu"; +import "@szhsin/react-menu/dist/index.css"; +import "@szhsin/react-menu/dist/transitions/slide.css"; +import { getColorByLuminance } from "./util/ColorUtil"; type ConnectionState = "connecting" | "error" | "connected" | "reconnecting"; @@ -116,6 +120,12 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => { }; }, []); + React.useEffect(() => { + context.themeManager.onThemeChange = () => { + updateBoardViewModel(pitAnimator.getBoardViewModelFromGame(game)); + }; + }, [boardViewModel]); + const resetGameState = () => { setGame(undefined); setCrashMessage(undefined); @@ -185,7 +195,11 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => { } return <>; }; - + const menuTextColor = getColorByLuminance( + context.themeManager.theme.appBarBgColor, + context.themeManager.theme.primary, + context.themeManager.theme.primaryLight + ); return (
= ({ initial = 0 }) => { }} >

{context.texts.Mancala}

-
+
+
+ light_mode + } + transition + align="end" + > + {context.themeManager.themes.map((theme) => { + return ( + (context.themeManager.theme = theme)} + > +
+ {theme.name} +
+ ); + })} +
+
{renderNewGameButton()} {game && !userKeyWhoLeave && diff --git a/src/animation/PitAnimator.ts b/src/animation/PitAnimator.ts index 3e912a7..d9c28fc 100644 --- a/src/animation/PitAnimator.ts +++ b/src/animation/PitAnimator.ts @@ -162,7 +162,7 @@ export default class PitAnimator { } } - private getBoardViewModelFromGame(game: MancalaGame): BoardViewModel { + public getBoardViewModelFromGame(game: MancalaGame): BoardViewModel { const pitViewModels = this.createPitViewModelsFromGame(game); return BoardViewModelFactory.create(v4(), pitViewModels); } diff --git a/src/index.html b/src/index.html index cf30955..e6ca5a9 100644 --- a/src/index.html +++ b/src/index.html @@ -11,6 +11,8 @@ +