diff --git a/src/App.js b/src/App.js
index 68d046d..7dc58ae 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,7 +1,7 @@
import { useState, useEffect, useContext } from 'react';
import { Helmet, HelmetProvider } from 'react-helmet-async';
-import { Button, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions } from '@mui/material';
-import { Theme, getImage } from './Theme';
+import { Button, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Box } from '@mui/material';
+import { Theme, getImage, checkThemeAvailability } from './Theme';
import * as gameLogic from './gameLogic.js';
import styles from './App.module.css';
import { DebugRunContext, getLg } from './DebugRunContext';
@@ -9,6 +9,7 @@ import clone from 'just-clone';
import Columns from 'react-columns';
import NavBar from './NavBar';
import { useNavigate, useSearchParams } from 'react-router-dom';
+import themes from './themes.json';
function Square({ currentMove, value, onSquareClick, selectedPiece, index, theme, squares, testid }) {
const isDark = ((Math.floor(index / 8) % 2) !== (index % 2));
@@ -145,7 +146,7 @@ function Board({ theme, data, onPlay, onRevert }) {
window.chess.advanced = data;
return (
-
+
@@ -154,7 +155,7 @@ function Board({ theme, data, onPlay, onRevert }) {
-
+
);
}
@@ -372,7 +373,16 @@ class setupData {
function ThemedApp() {
const [params] = useSearchParams();
- return ;
+ const theme = params.get('theme') ?? 'dark';
+ const navigate = useNavigate();
+ if (checkThemeAvailability(themes.themes[theme]) === false)
+ return (
+ <>
+
+ Sorry, this theme is not available
+ >
+ );
+ return ;
}
function createHistoryObject(squares) {
diff --git a/src/Home.js b/src/Home.js
index be0b610..925fe02 100644
--- a/src/Home.js
+++ b/src/Home.js
@@ -1,7 +1,8 @@
-import { useNavigate, NavLink, Outlet } from 'react-router-dom';
+import { useNavigate, Link, Outlet } from 'react-router-dom';
import styles from './Home.module.css';
import NavBar from './NavBar';
import themes from './themes.json';
+import { checkThemeAvailability } from './Theme';
function Home() {
const navigate = useNavigate();
@@ -21,7 +22,7 @@ function HomePage() {
return (
<>
Chess No. 25 is a simple and open source chess game for two players.
- Chess No. 25 has multiple themes available. Try them now!
+ Chess No. 25 has multiple themes available. Try them now!
If you found a bug or have an idea, please report it on GitHub.
>
);
@@ -29,8 +30,17 @@ function HomePage() {
function ThemesPage() {
let themelist = [];
- for (const theme in themes.themes)
- themelist.push({themes.themes[theme].fullName || theme});
+ for (const theme in themes.themes) {
+ const available = checkThemeAvailability(themes.themes[theme]);
+ if (available === false) {
+ themelist.push({themes.themes[theme].fullName ?? theme} (not available));
+ continue;
+ }
+ let style = {};
+ if (available) // empty string '' if falsy
+ style.color = 'green';
+ themelist.push({themes.themes[theme].fullName ?? theme}{available});
+ }
return (
<>
Please choose a theme:
diff --git a/src/Home.module.css b/src/Home.module.css
index c48bece..d968751 100644
--- a/src/Home.module.css
+++ b/src/Home.module.css
@@ -1,2 +1,11 @@
.home {
}
+
+.themeLink a {
+ text-decoration: none;
+ color: blue;
+}
+
+.themeLink:hover a {
+ text-decoration: underline;
+}
diff --git a/src/NavBar.js b/src/NavBar.js
index c1eec43..45e2d6c 100644
--- a/src/NavBar.js
+++ b/src/NavBar.js
@@ -15,7 +15,7 @@ function NavButton({ to, href, children }) {
function NavBar({ onNavigate, children }) {
return (
-
+
diff --git a/src/Theme.js b/src/Theme.js
index b308597..166cb5e 100644
--- a/src/Theme.js
+++ b/src/Theme.js
@@ -69,5 +69,30 @@ function Theme(themeId, logrun) {
return result;
}
-export { Theme, getImage, pieceIs };
+function checkThemeAvailability(theme) {
+ if (!theme)
+ return false;
+ const av = theme.availability ?? { always: true };
+ const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
+ const now = new Date();
+ if (av.monthSeason)
+ for (const month of av.monthSeason)
+ if (months.includes(month) && new Date(`0 ${month}`).getMonth() === now.getMonth()) {
+ const joinWithCommas = av.monthSeason.slice();
+ const last = joinWithCommas.pop();
+ return ` - Special theme: available only in ${joinWithCommas.join(', ')}${joinWithCommas.length ? ' and ' : ''}${last}`;
+ }
+ if (av.daySeason)
+ for (const dateString of av.dateSeason) {
+ const dateStringParts = dateString.split(' ');
+ if (dateStringParts.length !== 2 || isNaN(Number(dateStringParts[0])) || !months.includes(dateStringParts[1]))
+ continue;
+ const date = new Date(dateString);
+ if (date.getDay() === now.getDay() && date.getMonth === now.getMonth())
+ return ` - Special theme: available only on ${dateString}`;
+ }
+ return av.always ? '' : false;
+}
+
+export { Theme, getImage, pieceIs, checkThemeAvailability };
export default ThemeData;
diff --git a/src/themes.json b/src/themes.json
index 8151aab..6926441 100644
--- a/src/themes.json
+++ b/src/themes.json
@@ -121,9 +121,9 @@
},
"christmas": {
"fullName": "Christmas",
- "avalability": {
+ "availability": {
"monthSeason": [
- 12
+ "December"
]
},
"bodyStyle": {