Compare commits
No commits in common. "8056c38ad51ff6e19b3fdde716dff755b716398e" and "8d5cca6cfa80f4377361dfd7cea6aa220ab1b602" have entirely different histories.
8056c38ad5
...
8d5cca6cfa
5018
webapp/package-lock.json
generated
5018
webapp/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,21 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.App-header {
|
||||||
|
background-color: #282c34;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: calc(10px + 2vmin);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.App-link {
|
||||||
|
color: #61dafb;
|
||||||
|
}
|
||||||
|
|
||||||
.Container {
|
.Container {
|
||||||
margin-top: 25px;
|
margin-top: 25px;
|
||||||
}
|
}
|
@ -9,7 +9,6 @@ import {
|
|||||||
import Header from "./components/Header"
|
import Header from "./components/Header"
|
||||||
import Leaderboard from "./components/Leaderboard"
|
import Leaderboard from "./components/Leaderboard"
|
||||||
import Game from "./components/Game"
|
import Game from "./components/Game"
|
||||||
import GameProposal from './components/Game/Proposal'
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|
||||||
@ -20,7 +19,6 @@ function App() {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/leaderboard" element={<Leaderboard/>} />
|
<Route path="/leaderboard" element={<Leaderboard/>} />
|
||||||
<Route path="/game" element={<Game/>} />
|
<Route path="/game" element={<Game/>} />
|
||||||
<Route path="/game/proposal" element={<GameProposal/>} />
|
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
.tile {
|
|
||||||
border: 1px solid #e4e4e4;
|
|
||||||
float: left;
|
|
||||||
font-size: 200%;
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: 34px;
|
|
||||||
height: 34px;
|
|
||||||
width: 34px;
|
|
||||||
margin-right: -1px;
|
|
||||||
margin-top: -1px;
|
|
||||||
padding: 0;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.black {
|
|
||||||
background: lightgray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.board {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
/* scale: 15%; */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.white:hover {
|
|
||||||
background-color:azure;
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
import './index.css';
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { WhiteStone, BlackStone } from '../Stone'
|
|
||||||
|
|
||||||
export default function Board() {
|
|
||||||
|
|
||||||
return <div className='board'>
|
|
||||||
<div className='row'>
|
|
||||||
<BlackTile/> <WhiteTile id={0} stone={WhiteStone()} />
|
|
||||||
<BlackTile/> <WhiteTile id={1} stone={WhiteStone()} />
|
|
||||||
<BlackTile/> <WhiteTile id={2} stone={WhiteStone()} />
|
|
||||||
<BlackTile/> <WhiteTile id={4} stone={WhiteStone()} />
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<WhiteTile id={5} stone={WhiteStone()} /> <BlackTile/>
|
|
||||||
<WhiteTile id={6} stone={WhiteStone()} /> <BlackTile/>
|
|
||||||
<WhiteTile id={7} stone={WhiteStone()} /> <BlackTile/>
|
|
||||||
<WhiteTile id={8} stone={WhiteStone()} /> <BlackTile/>
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<BlackTile/> <WhiteTile id={ 9} stone={WhiteStone()} />
|
|
||||||
<BlackTile/> <WhiteTile id={10} stone={WhiteStone()} />
|
|
||||||
<BlackTile/> <WhiteTile id={11} stone={WhiteStone()} />
|
|
||||||
<BlackTile/> <WhiteTile id={12} stone={WhiteStone()} />
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<WhiteTile id={13} stone={null} /> <BlackTile/>
|
|
||||||
<WhiteTile id={14} stone={null} /> <BlackTile/>
|
|
||||||
<WhiteTile id={15} stone={null} /> <BlackTile/>
|
|
||||||
<WhiteTile id={16} stone={null} /> <BlackTile/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='row'>
|
|
||||||
<BlackTile/> <WhiteTile id={17} stone={null} />
|
|
||||||
<BlackTile/> <WhiteTile id={18} stone={null} />
|
|
||||||
<BlackTile/> <WhiteTile id={19} stone={null} />
|
|
||||||
<BlackTile/> <WhiteTile id={20} stone={null} />
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<WhiteTile id={21} stone={BlackStone()} /> <BlackTile/>
|
|
||||||
<WhiteTile id={22} stone={BlackStone()} /> <BlackTile/>
|
|
||||||
<WhiteTile id={23} stone={BlackStone()} /> <BlackTile/>
|
|
||||||
<WhiteTile id={24} stone={BlackStone()} /> <BlackTile/>
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<BlackTile/> <WhiteTile id={25} stone={BlackStone()} />
|
|
||||||
<BlackTile/> <WhiteTile id={26} stone={BlackStone()} />
|
|
||||||
<BlackTile/> <WhiteTile id={27} stone={BlackStone()} />
|
|
||||||
<BlackTile/> <WhiteTile id={28} stone={BlackStone()} />
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<WhiteTile id={29} stone={BlackStone()} /> <BlackTile/>
|
|
||||||
<WhiteTile id={30} stone={BlackStone()} /> <BlackTile/>
|
|
||||||
<WhiteTile id={31} stone={BlackStone()} /> <BlackTile/>
|
|
||||||
<WhiteTile id={32} stone={BlackStone()} /> <BlackTile/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
function WhiteTile({ id, stone }) {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className='tile white'
|
|
||||||
onClick={() => handleClick(id)}
|
|
||||||
>
|
|
||||||
{stone}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function BlackTile() {
|
|
||||||
return <div className='tile black'/>
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleClick(i) {
|
|
||||||
console.log("click", i)
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
import './index.css';
|
|
||||||
import React from 'react';
|
|
||||||
// import { NavLink } from "react-router-dom";
|
|
||||||
// import { AppData } from "../../../context/data"
|
|
||||||
import GameHeader from '../../GameHeader'
|
|
||||||
import GameSelector from '../../GameSelector'
|
|
||||||
import Board from '../../Board'
|
|
||||||
|
|
||||||
export default function Proposal() {
|
|
||||||
// const [data] = React.useContext(AppData)
|
|
||||||
|
|
||||||
return <div className="split">
|
|
||||||
<div className='split left'>
|
|
||||||
<GameHeader/>
|
|
||||||
<button>+ Create</button>
|
|
||||||
<GameSelector/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='split right'></div>
|
|
||||||
<Board/>
|
|
||||||
</div>
|
|
||||||
};
|
|
@ -1,21 +1,47 @@
|
|||||||
.split {
|
.GameProposal {
|
||||||
width: 100%;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.split .left {
|
|
||||||
float: left;
|
|
||||||
width: 45%;
|
|
||||||
/* max-width: 400px; */
|
|
||||||
|
|
||||||
/* height: 100px; */
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.split .right {
|
.GameProposal .li {
|
||||||
float: left;
|
width: 50%;
|
||||||
width: 55%;
|
border: 1px solid black;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GameProposal .li p {
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GameProposal .li p q {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GameProposal .li p i {
|
||||||
|
font-size: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GameProposal .li button.action {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GameProposal .li:hover button.action {
|
||||||
|
display: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
width: 20%;
|
||||||
|
/* height: 20px; */
|
||||||
|
border-bottom: 1px dotted black;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 50%;
|
||||||
|
padding-left: 50%;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stone {
|
||||||
|
font-size: 140%;
|
||||||
|
vertical-align: -3px;
|
||||||
}
|
}
|
@ -1,22 +1,83 @@
|
|||||||
import './index.css';
|
import './index.css';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import GameHeader from '../GameHeader'
|
import {Accept} from './GameProposalAction';
|
||||||
import GameSelector from '../GameSelector'
|
import Reject from './Reject'
|
||||||
import Board from '../Board'
|
import Cancel from './GameProposalCancel'
|
||||||
|
|
||||||
// import { AppData } from "../../context/data"
|
import { AppData } from "../../context/data"
|
||||||
|
|
||||||
export default function Game() {
|
export default function Game() {
|
||||||
|
const [data] = React.useContext(AppData)
|
||||||
|
|
||||||
return <div className="split">
|
if (data.games == null)
|
||||||
|
return <div>Loading..</div>
|
||||||
|
|
||||||
<div className='split left'>
|
// for (const [key, value] of Object.entries(data.games))
|
||||||
<GameHeader/>
|
// console.log(key, value);
|
||||||
<GameSelector/>
|
|
||||||
|
const waitForYou = data.games
|
||||||
|
.filter(game => game.status === Status.WaitForYou)
|
||||||
|
.map(game => {
|
||||||
|
return <div className="li" key={game.uuid}>
|
||||||
|
<p>
|
||||||
|
You {Stone(game.myColor)} <i>vs</i> {game.opponentName} {Stone(oppositeColor(game.myColor))}
|
||||||
|
<br/>
|
||||||
|
<q>{game.message}</q>
|
||||||
|
<br/>
|
||||||
|
<Accept uuid={game.uuid}/>
|
||||||
|
<Reject uuid={game.uuid}/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
});
|
||||||
|
|
||||||
|
const WaitForOpponent = data.games
|
||||||
|
.filter(game => game.status === Status.WaitForOpponent)
|
||||||
|
.map(game => {
|
||||||
|
return <div className="li" key={game.uuid}>
|
||||||
|
<p>
|
||||||
|
You {Stone(game.myColor)} <i>vs</i> {game.opponentName} {Stone(oppositeColor(game.myColor))}
|
||||||
|
<br/>
|
||||||
|
<q>{game.message}</q>
|
||||||
|
<br/>
|
||||||
|
<Cancel uuid={game.uuid}/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
});
|
||||||
|
|
||||||
|
return <div className="GameProposal">
|
||||||
|
{waitForYou}
|
||||||
|
{WaitForOpponent.length > 0 &&
|
||||||
|
<div className="separator">
|
||||||
|
waiting for opponent ({WaitForOpponent.length})
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{WaitForOpponent}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='split right'></div>
|
|
||||||
<Board/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const Status = {
|
||||||
|
WaitForOpponent: "GAME_PROPOSAL_WAIT_FOR_OPPONENT",
|
||||||
|
WaitForYou: "GAME_PROPOSAL_WAIT_FOR_YOU",
|
||||||
|
}
|
||||||
|
|
||||||
|
function Stone(color) {
|
||||||
|
if (color === "WHITE")
|
||||||
|
return <span className="stone">⛀</span>
|
||||||
|
|
||||||
|
if (color === "BLACK")
|
||||||
|
return <span className="stone">⛂</span>
|
||||||
|
|
||||||
|
return <span className="stone">{color}</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
function oppositeColor(color) {
|
||||||
|
if (color === "WHITE")
|
||||||
|
return "BLACK"
|
||||||
|
|
||||||
|
if (color === "BLACK")
|
||||||
|
return "WHITE"
|
||||||
|
|
||||||
|
return color
|
||||||
|
}
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
.game-header {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
background-color: lightgrey;
|
|
||||||
width: 100%;
|
|
||||||
padding-top: 8px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-header a {
|
|
||||||
color:darkgrey;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: .25s ease;
|
|
||||||
margin-left: 5px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-header .active {
|
|
||||||
color: white;
|
|
||||||
border-radius: 2px;
|
|
||||||
background-color: cadetblue;
|
|
||||||
opacity: 80%;
|
|
||||||
padding-top: 8px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-header a:hover:not(.active) {
|
|
||||||
color: cadetblue;
|
|
||||||
|
|
||||||
/* box-shadow: 0 1.5px 0 0 currentColor; */
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
import './index.css';
|
|
||||||
import React from 'react';
|
|
||||||
import { NavLink } from "react-router-dom";
|
|
||||||
// import { AppData } from "../../context/data"
|
|
||||||
|
|
||||||
export default function GameHeader() {
|
|
||||||
// const [data] = React.useContext(AppData)
|
|
||||||
|
|
||||||
|
|
||||||
return <nav className="game-header">
|
|
||||||
<NavLink to="/game/proposal">Proposal</NavLink>
|
|
||||||
<NavLink to="/game/active">Active</NavLink>
|
|
||||||
<NavLink to="/game/archive">Archive</NavLink>
|
|
||||||
</nav>
|
|
||||||
};
|
|
@ -1,47 +0,0 @@
|
|||||||
.Games {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.Games .li {
|
|
||||||
border: 1px solid black;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Games .li p {
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Games .li p q {
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Games .li p i {
|
|
||||||
font-size: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Games .li button.action {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Games .li:hover button.action {
|
|
||||||
display: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
.separator {
|
|
||||||
/* width: 20%; */
|
|
||||||
/* height: 20px; */
|
|
||||||
border-bottom: 1px dotted black;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 50%;
|
|
||||||
padding-left: 50%;
|
|
||||||
margin-bottom: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stone {
|
|
||||||
font-size: 140%;
|
|
||||||
vertical-align: -3px;
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
import './index.css';
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { AppData } from "../../context/data"
|
|
||||||
|
|
||||||
export default function Game() {
|
|
||||||
const [data] = React.useContext(AppData)
|
|
||||||
|
|
||||||
if (!data?.games)
|
|
||||||
return <div>Loading..</div>
|
|
||||||
|
|
||||||
// for (const [key, value] of Object.entries(data.games))
|
|
||||||
// console.log(key, value);
|
|
||||||
|
|
||||||
console.log("data.games", data.games)
|
|
||||||
const waitForYou = data.games
|
|
||||||
.filter(game => game.status === Status.WaitForYou)
|
|
||||||
.map(game => {
|
|
||||||
return <div className="li" key={game.uuid}>
|
|
||||||
<p>
|
|
||||||
You {Stone(game.myColor)} <i>vs</i> {game.opponentName} {Stone(oppositeColor(game.myColor))}
|
|
||||||
<br/>
|
|
||||||
<q>{game.message}</q>
|
|
||||||
<br/>
|
|
||||||
{/* <Accept uuid={game.uuid}/>
|
|
||||||
<Reject uuid={game.uuid}/> */}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
});
|
|
||||||
|
|
||||||
const WaitForOpponent = data.games
|
|
||||||
.filter(game => game.status === Status.WaitForOpponent)
|
|
||||||
.map(game => {
|
|
||||||
return <div className="li" key={game.uuid}>
|
|
||||||
<p>
|
|
||||||
You {Stone(game.myColor)} <i>vs</i> {game.opponentName} {Stone(oppositeColor(game.myColor))}
|
|
||||||
<br/>
|
|
||||||
<q>{game.message}</q>
|
|
||||||
<br/>
|
|
||||||
{/* <Cancel uuid={game.uuid}/> */}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
});
|
|
||||||
|
|
||||||
return <div className="Container">
|
|
||||||
<div className="Games">
|
|
||||||
{waitForYou}
|
|
||||||
{WaitForOpponent.length > 0 &&
|
|
||||||
<div className="separator">
|
|
||||||
waiting for opponent ({WaitForOpponent.length})
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{WaitForOpponent}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const Status = {
|
|
||||||
WaitForOpponent: "GAME_PROPOSAL_WAIT_FOR_OPPONENT",
|
|
||||||
WaitForYou: "GAME_PROPOSAL_WAIT_FOR_YOU",
|
|
||||||
}
|
|
||||||
|
|
||||||
function Stone(color) {
|
|
||||||
if (color === "WHITE")
|
|
||||||
return <span className="stone">⛀</span>
|
|
||||||
|
|
||||||
if (color === "BLACK")
|
|
||||||
return <span className="stone">⛂</span>
|
|
||||||
|
|
||||||
return <span className="stone">{color}</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
function oppositeColor(color) {
|
|
||||||
if (color === "WHITE")
|
|
||||||
return "BLACK"
|
|
||||||
|
|
||||||
if (color === "BLACK")
|
|
||||||
return "WHITE"
|
|
||||||
|
|
||||||
return color
|
|
||||||
}
|
|
@ -8,44 +8,46 @@ h1 {
|
|||||||
height: 1px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-header {
|
nav {
|
||||||
padding: auto;
|
padding: auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: lightgray;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: .25s ease;
|
||||||
|
|
||||||
|
margin-left: 30px;
|
||||||
|
margin-right: 30px;
|
||||||
|
padding: 0.25rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
color: white;
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: cadetblue;
|
||||||
|
opacity: 80%;
|
||||||
|
padding: 0.25rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover:not(.active) {
|
||||||
|
color:cadetblue;
|
||||||
|
|
||||||
|
box-shadow: 0 1.5px 0 0 currentcolor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-header a {
|
[data-darkreader-scheme="dark"] nav {
|
||||||
color: lightgray;
|
a {
|
||||||
text-decoration: none;
|
color: darkslategrey;
|
||||||
transition: .25s ease;
|
}
|
||||||
width: fit-content;
|
|
||||||
|
|
||||||
margin-left: 5px;
|
.active {
|
||||||
margin-right: 5px;
|
color: white;
|
||||||
padding: 0.25rem 1rem;
|
box-shadow: 0 1.5px 0 0 currentcolor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-header .active {
|
|
||||||
color: white;
|
|
||||||
border-radius: 2px;
|
|
||||||
background-color: cadetblue;
|
|
||||||
opacity: 80%;
|
|
||||||
padding: 0.25rem 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-header a:hover:not(.active) {
|
|
||||||
color: cadetblue;
|
|
||||||
|
|
||||||
box-shadow: 0 1.5px 0 0 currentcolor;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-darkreader-scheme="dark"] .app-header a {
|
|
||||||
color: darkslategrey;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-darkreader-scheme="dark"] .app-header .active {
|
|
||||||
color: white;
|
|
||||||
box-shadow: 0 1.5px 0 0 currentcolor;
|
|
||||||
}
|
|
@ -2,7 +2,7 @@ import './index.css';
|
|||||||
import './wave.css'
|
import './wave.css'
|
||||||
import React from "react"
|
import React from "react"
|
||||||
import { NavLink } from "react-router-dom";
|
import { NavLink } from "react-router-dom";
|
||||||
import OnlineToggle from '../OnlineTgl';
|
import OfflineToggle from '../OnlineTgl';
|
||||||
import { AppData } from "../../context/data"
|
import { AppData } from "../../context/data"
|
||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
@ -10,9 +10,9 @@ export default function Header() {
|
|||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
<h1>
|
<h1>
|
||||||
CordaCheckers<OnlineToggle />
|
CordaCheckers<OfflineToggle />
|
||||||
</h1>
|
</h1>
|
||||||
<nav className='app-header'>
|
<nav>
|
||||||
<NavLink to="/leaderboard" className={data.leaderboardFetching && "woble"}>
|
<NavLink to="/leaderboard" className={data.leaderboardFetching && "woble"}>
|
||||||
<span>L</span>
|
<span>L</span>
|
||||||
<span>e</span>
|
<span>e</span>
|
||||||
@ -35,7 +35,11 @@ export default function Header() {
|
|||||||
</NavLink>
|
</NavLink>
|
||||||
|
|
||||||
<NavLink to="/about" className={""}>
|
<NavLink to="/about" className={""}>
|
||||||
About
|
<span>A</span>
|
||||||
|
<span>b</span>
|
||||||
|
<span>o</span>
|
||||||
|
<span>u</span>
|
||||||
|
<span>t</span>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
.woble {
|
.woble {
|
||||||
display: flex;
|
display: flex;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
/* text-transform: uppercase; */
|
/* text-transform: uppercase; */
|
||||||
/* font-size: 1.5rem; */
|
/* font-size: 1.5rem; */
|
||||||
/* padding: 1rem 2rem; */
|
/* padding: 1rem 2rem; */
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
.white-stone {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.black-stone {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
import './index.css';
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
export function Stone( color ) {
|
|
||||||
switch (color) {
|
|
||||||
case WHITE():
|
|
||||||
return WhiteStone()
|
|
||||||
|
|
||||||
case BLACK():
|
|
||||||
return BlackStone()
|
|
||||||
|
|
||||||
default:
|
|
||||||
console.warn("Unknown color: ", color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function WhiteStone() {
|
|
||||||
return <span className="white-stone">⛀</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
export function BlackStone() {
|
|
||||||
return <span className="black-stone">⛂</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
export function oppositeColor(color) {
|
|
||||||
if (color === WHITE())
|
|
||||||
return BLACK()
|
|
||||||
|
|
||||||
if (color === BLACK())
|
|
||||||
return WHITE()
|
|
||||||
|
|
||||||
return color
|
|
||||||
}
|
|
||||||
|
|
||||||
export function WHITE() {
|
|
||||||
return "WHITE"
|
|
||||||
}
|
|
||||||
|
|
||||||
export function BLACK() {
|
|
||||||
return "BLACK"
|
|
||||||
}
|
|
@ -12,8 +12,8 @@ export const AppDataProvider = ({ children }) => {
|
|||||||
|
|
||||||
const [data, dispatchData] = React.useReducer(reducer, initialState)
|
const [data, dispatchData] = React.useReducer(reducer, initialState)
|
||||||
|
|
||||||
const [games, gamesFetching ] = Poll('/api/gamestate' , 30, data.offlineMode)
|
const [games, gamesFetching ] = Poll('api/gamestate' , 30, data.offlineMode)
|
||||||
const [leaderboard, leaderboardFetching ] = Poll('/api/leaderboard', 60, data.offlineMode)
|
const [leaderboard, leaderboardFetching ] = Poll('api/leaderboard', 60, data.offlineMode)
|
||||||
|
|
||||||
data.games = games
|
data.games = games
|
||||||
data.gamesFetching = gamesFetching
|
data.gamesFetching = gamesFetching
|
||||||
|
Loading…
Reference in New Issue
Block a user