refactor BoardView
This commit is contained in:
parent
0d2b16c1fe
commit
f53617185c
@ -1,6 +1,6 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { FunctionComponent, useEffect, useState } from "react";
|
import { FunctionComponent, useEffect, useState } from "react";
|
||||||
import BoardView from "./components/BoardView";
|
import BoardView from "./components/board/BoardView";
|
||||||
import { context } from "./context";
|
import { context } from "./context";
|
||||||
import { RTMTWS } from "./rtmt/rtmt_websocket";
|
import { RTMTWS } from "./rtmt/rtmt_websocket";
|
||||||
import {
|
import {
|
||||||
|
|||||||
@ -1,110 +1,11 @@
|
|||||||
import { Bank, MancalaGame, Pit } from "mancala.js";
|
import { Bank, MancalaGame, Pit } from "mancala.js";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { FunctionComponent, useState } from "react";
|
import { FunctionComponent, useState } from "react";
|
||||||
import { Context } from "../context";
|
import { Context } from "../../context";
|
||||||
import { getColorByBrightness } from "../util/ColorUtil";
|
import BoardViewModel from "../../viewmodel/BoardViewModel";
|
||||||
import BoardViewModel from "../viewmodel/BoardViewModel";
|
import PitViewModel from "../../viewmodel/PitViewModel";
|
||||||
import PitViewModel from "../viewmodel/PitViewModel";
|
import PitView from "./PitView";
|
||||||
|
import StoreView from "./StoreView";
|
||||||
const StoneView: FunctionComponent<{ color: string }> = ({ color }) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
background: color,
|
|
||||||
margin: "1px",
|
|
||||||
width: "1vw",
|
|
||||||
height: "1vw",
|
|
||||||
borderRadius: "10vw",
|
|
||||||
transition: "background-color 0.5s",
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
function range(size: number) {
|
|
||||||
var ans = [];
|
|
||||||
for (let i = 0; i < size; i++) {
|
|
||||||
ans.push(i);
|
|
||||||
}
|
|
||||||
return ans;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PitView: FunctionComponent<{
|
|
||||||
pitViewModel: PitViewModel;
|
|
||||||
onClick: () => void;
|
|
||||||
}> = ({ pitViewModel, onClick }) => {
|
|
||||||
const stones = [...range(pitViewModel.stoneCount)].map((i, index) => (
|
|
||||||
<StoneView key={index} color={pitViewModel.stoneColor} />
|
|
||||||
));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
onClick={onClick}
|
|
||||||
style={{
|
|
||||||
background: pitViewModel.pitColor,
|
|
||||||
margin: "5px",
|
|
||||||
padding: "5px",
|
|
||||||
borderRadius: "10vw",
|
|
||||||
transition: "background-color 0.5s",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
alignContent: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
justifyItems: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{stones}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const StoreView: FunctionComponent<{
|
|
||||||
context: Context;
|
|
||||||
pitViewModel: PitViewModel;
|
|
||||||
gridColumn: string;
|
|
||||||
gridRow: string;
|
|
||||||
}> = ({ context, pitViewModel, gridColumn, gridRow }) => {
|
|
||||||
const stones = [...range(pitViewModel.stoneCount)].map((i, index) => (
|
|
||||||
<StoneView key={index} color={pitViewModel.stoneColor} />
|
|
||||||
));
|
|
||||||
const textColor = getColorByBrightness(
|
|
||||||
pitViewModel.pitColor,
|
|
||||||
context.themeManager.theme.textColor,
|
|
||||||
context.themeManager.theme.textLightColor
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
gridColumn: gridColumn,
|
|
||||||
gridRow: gridRow,
|
|
||||||
background: pitViewModel.pitColor,
|
|
||||||
margin: "5px",
|
|
||||||
borderRadius: "10vw",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignContent: "center",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
position: "relative",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{stones}
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
bottom: "2vw",
|
|
||||||
fontFamily: "monospace",
|
|
||||||
fontWeight: "bold",
|
|
||||||
fontSize: "2vw",
|
|
||||||
color: textColor,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{stones.length}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const BoardView: FunctionComponent<{
|
const BoardView: FunctionComponent<{
|
||||||
game?: MancalaGame;
|
game?: MancalaGame;
|
||||||
@ -165,7 +66,7 @@ const BoardView: FunctionComponent<{
|
|||||||
background: theme.boardColor,
|
background: theme.boardColor,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{userKey === game.player2Id ? (
|
{userKey === game?.player2Id ? (
|
||||||
<>
|
<>
|
||||||
<StoreView
|
<StoreView
|
||||||
context={context}
|
context={context}
|
||||||
@ -179,7 +80,7 @@ const BoardView: FunctionComponent<{
|
|||||||
gridColumn="8 / 9"
|
gridColumn="8 / 9"
|
||||||
gridRow="1 / 3"
|
gridRow="1 / 3"
|
||||||
/>
|
/>
|
||||||
{player1Pits.reverse()}
|
{player1Pits?.reverse()}
|
||||||
{player2Pits}
|
{player2Pits}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
@ -196,7 +97,7 @@ const BoardView: FunctionComponent<{
|
|||||||
gridColumn="1 / 2"
|
gridColumn="1 / 2"
|
||||||
gridRow="1 / 3"
|
gridRow="1 / 3"
|
||||||
/>
|
/>
|
||||||
{player2Pits.reverse()}
|
{player2Pits?.reverse()}
|
||||||
{player1Pits}
|
{player1Pits}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
38
src/components/board/PitView.tsx
Normal file
38
src/components/board/PitView.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { FunctionComponent } from "react";
|
||||||
|
import Util from "../../util/Util";
|
||||||
|
import PitViewModel from "../../viewmodel/PitViewModel";
|
||||||
|
import StoneView from "./StoneView";
|
||||||
|
|
||||||
|
|
||||||
|
const PitView: FunctionComponent<{
|
||||||
|
pitViewModel: PitViewModel;
|
||||||
|
onClick: () => void;
|
||||||
|
}> = ({ pitViewModel, onClick }) => {
|
||||||
|
const stones = [...Util.range(pitViewModel.stoneCount)].map((i, index) => (
|
||||||
|
<StoneView key={index} color={pitViewModel.stoneColor} />
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={onClick}
|
||||||
|
style={{
|
||||||
|
background: pitViewModel.pitColor,
|
||||||
|
margin: "5px",
|
||||||
|
padding: "5px",
|
||||||
|
borderRadius: "10vw",
|
||||||
|
transition: "background-color 0.5s",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
justifyItems: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{stones}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PitView;
|
||||||
19
src/components/board/StoneView.tsx
Normal file
19
src/components/board/StoneView.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { FunctionComponent } from "react";
|
||||||
|
|
||||||
|
const StoneView: FunctionComponent<{ color: string }> = ({ color }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
background: color,
|
||||||
|
margin: "1px",
|
||||||
|
width: "1vw",
|
||||||
|
height: "1vw",
|
||||||
|
borderRadius: "10vw",
|
||||||
|
transition: "background-color 0.5s",
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default StoneView;
|
||||||
56
src/components/board/StoreView.tsx
Normal file
56
src/components/board/StoreView.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { FunctionComponent } from "react";
|
||||||
|
import { Context } from "../../context";
|
||||||
|
import { getColorByBrightness } from "../../util/ColorUtil";
|
||||||
|
import Util from "../../util/Util";
|
||||||
|
import PitViewModel from "../../viewmodel/PitViewModel";
|
||||||
|
import StoneView from "./StoneView";
|
||||||
|
|
||||||
|
const StoreView: FunctionComponent<{
|
||||||
|
context: Context;
|
||||||
|
pitViewModel: PitViewModel;
|
||||||
|
gridColumn: string;
|
||||||
|
gridRow: string;
|
||||||
|
}> = ({ context, pitViewModel, gridColumn, gridRow }) => {
|
||||||
|
const stones = [...Util.range(pitViewModel.stoneCount)].map((i, index) => (
|
||||||
|
<StoneView key={index} color={pitViewModel.stoneColor} />
|
||||||
|
));
|
||||||
|
const textColor = getColorByBrightness(
|
||||||
|
pitViewModel.pitColor,
|
||||||
|
context.themeManager.theme.textColor,
|
||||||
|
context.themeManager.theme.textLightColor
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
gridColumn: gridColumn,
|
||||||
|
gridRow: gridRow,
|
||||||
|
background: pitViewModel.pitColor,
|
||||||
|
margin: "5px",
|
||||||
|
borderRadius: "10vw",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignContent: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{stones}
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
bottom: "2vw",
|
||||||
|
fontFamily: "monospace",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: "2vw",
|
||||||
|
color: textColor,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{stones.length}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default StoreView;
|
||||||
10
src/util/Util.ts
Normal file
10
src/util/Util.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
export default class Util {
|
||||||
|
public static range(size: number) {
|
||||||
|
var ans = [];
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
ans.push(i);
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user