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": {