Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e14ba9c

Browse files
author
Pbatch
authored
Merge pull request Pbatch#32 from Pbatch/pb_start
Support starting from any position
2 parents c5c7ab4 + eee5c23 commit e14ba9c

File tree

11 files changed

+275
-47
lines changed

11 files changed

+275
-47
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { useState } from "react";
2+
import { findFen } from "../../utils/findFen";
3+
import { useDispatch } from 'react-redux';
4+
import { gameResetPgnAndFen, gameResetStart } from "../../slices/gameSlice";
5+
import { Color } from "chess.js";
6+
7+
const FenButton = ({ piecesModelRef, videoRef, canvasRef, setText, cornersRef }:
8+
{piecesModelRef: any, videoRef: any, canvasRef: any, setText: any, cornersRef: any }) => {
9+
const options = ["Normal", "Infer (White to move)", "Infer (Black to move)"];
10+
11+
const dispatch = useDispatch();
12+
const [option, setOption] = useState<string>(options[0]);
13+
14+
const handleClick = (e: any, option: string) => {
15+
e.preventDefault();
16+
if (option === "Normal") {
17+
dispatch(gameResetStart());
18+
dispatch(gameResetPgnAndFen());
19+
} else {
20+
const color: Color = option.includes("White to move") ? "w" : "b";
21+
findFen(piecesModelRef, videoRef, cornersRef, canvasRef, dispatch, setText, color);
22+
}
23+
setOption(option);
24+
}
25+
26+
return (
27+
<div className="dropdown">
28+
<button className="btn btn-dark btn-sm btn-outline-light dropdown-toggle w-100" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
29+
Start: {option}
30+
</button>
31+
<ul className="dropdown-menu" aria-labelledby="dropdownMenuButton1">
32+
{options.map((option) =>
33+
<li key={option}>
34+
<a onClick={(e) => handleClick(e, option)} className="dropdown-item" href="#">{option}</a>
35+
</li>
36+
)}
37+
</ul>
38+
</div>
39+
);
40+
};
41+
42+
export default FenButton;

src/components/common/video.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@ import { CORNER_KEYS, MARKER_DIAMETER, MARKER_RADIUS } from "../../utils/constan
44
import { Corners } from ".";
55
import { useWindowWidth, useWindowHeight } from '@react-hook/window-size';
66
import { useDispatch } from 'react-redux';
7-
import { cornersSelect, cornersSet } from "../../slices/cornersSlice";
7+
import { cornersSet } from "../../slices/cornersSlice";
88
import { getMarkerXY, getXY } from "../../utils/detect";
99
import { Chessboard } from 'kokopu-react';
10-
import { CornersDict, CornersPayload, Game, setBoolean, setStringArray } from "../../types";
10+
import { CornersPayload, Game, setBoolean, setStringArray } from "../../types";
1111
import { gameSelect } from "../../slices/gameSlice";
1212

13-
const Video = ({ modelRef, canvasRef, videoRef, sidebarRef, playing, setPlaying, playingRef, setText, digital, webcam }: {
13+
const Video = ({ modelRef, canvasRef, videoRef, sidebarRef, playing,
14+
setPlaying, playingRef, setText, digital, webcam, cornersRef }: {
1415
modelRef: any, canvasRef: any, videoRef: any, sidebarRef: any,
1516
playing: boolean, setPlaying: setBoolean, playingRef: any,
16-
setText: setStringArray, digital: boolean, webcam: boolean
17+
setText: setStringArray, digital: boolean, webcam: boolean,
18+
cornersRef: any
1719
}) => {
18-
const corners: CornersDict = cornersSelect();
1920
const game: Game = gameSelect();
2021

2122
const displayRef: any = useRef(null);
22-
const cornersRef: any = useRef(null);
2323
const gameRef = useRef<Game>(game);
2424

2525
const aspectRatio = 16 / 9;
@@ -78,7 +78,7 @@ const Video = ({ modelRef, canvasRef, videoRef, sidebarRef, playing, setPlaying,
7878
canvasRef.current.height = videoRef.current.offsetHeight;
7979

8080
CORNER_KEYS.forEach((key) => {
81-
const xy = getXY(corners[key], oldHeight, oldWidth);
81+
const xy = getXY(cornersRef.current[key], oldHeight, oldWidth);
8282
const payload: CornersPayload = {
8383
"xy": getMarkerXY(xy, canvasRef.current.height, canvasRef.current.width),
8484
"key": key
@@ -113,10 +113,6 @@ const Video = ({ modelRef, canvasRef, videoRef, sidebarRef, playing, setPlaying,
113113
updateWidthHeight();
114114
}, [windowWidth, windowHeight]);
115115

116-
useEffect(() => {
117-
cornersRef.current = corners
118-
}, [corners])
119-
120116
useEffect(() => {
121117
if ((webcam) || (videoRef.current.src === "")) {
122118
return;

src/components/common/videoAndSidebar.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ import { useRef, useState, useEffect } from "react";
22
import Video from "../common/video";
33
import { useOutletContext } from "react-router-dom";
44
import { useDispatch } from 'react-redux';
5-
import { cornersReset } from '../../slices/cornersSlice';
5+
import { cornersReset, cornersSelect } from '../../slices/cornersSlice';
66
import { Container } from "../common";
77
import LoadModels from "../../utils/loadModels";
8-
import { Context } from "../../types";
8+
import { Context, CornersDict } from "../../types";
99
import RecordSidebar from "../record/recordSidebar";
1010
import UploadSidebar from "../upload/uploadSidebar";
1111
import { gameResetPgnAndFen } from "../../slices/gameSlice";
1212

1313
const VideoAndSidebar = ({ webcam }: {webcam: boolean}) => {
1414
const context = useOutletContext<Context>();
1515
const dispatch = useDispatch();
16+
const corners: CornersDict = cornersSelect();
1617

1718
const [text, setText] = useState<string[]>([]);
1819
const [playing, setPlaying] = useState<boolean>(false);
@@ -22,11 +23,16 @@ const VideoAndSidebar = ({ webcam }: {webcam: boolean}) => {
2223
const playingRef = useRef<boolean>(playing);
2324
const canvasRef = useRef<any>(null);
2425
const sidebarRef = useRef<any>(null);
26+
const cornersRef = useRef<CornersDict>(corners);
2527

2628
useEffect(() => {
2729
playingRef.current = playing;
2830
}, [playing]);
2931

32+
useEffect(() => {
33+
cornersRef.current = corners
34+
}, [corners])
35+
3036
useEffect(() => {
3137
LoadModels(context.piecesModelRef, context.xcornersModelRef);
3238
dispatch(cornersReset())
@@ -45,6 +51,7 @@ const VideoAndSidebar = ({ webcam }: {webcam: boolean}) => {
4551
"playing": playing,
4652
"text": text,
4753
"digital": digital,
54+
"cornersRef": cornersRef
4855
}
4956
const sidebar = () => {
5057
if (webcam) {
@@ -56,8 +63,9 @@ const VideoAndSidebar = ({ webcam }: {webcam: boolean}) => {
5663
return (
5764
<Container>
5865
{sidebar()}
59-
<Video modelRef={context.piecesModelRef} videoRef={videoRef} canvasRef={canvasRef} sidebarRef={sidebarRef}
60-
playing={playing} setPlaying={setPlaying} playingRef={playingRef} setText={setText} digital={digital} webcam={webcam} />
66+
<Video modelRef={context.piecesModelRef} videoRef={videoRef} canvasRef={canvasRef}
67+
sidebarRef={sidebarRef} playing={playing} setPlaying={setPlaying} playingRef={playingRef}
68+
setText={setText} digital={digital} webcam={webcam} cornersRef={cornersRef} />
6169
</Container>
6270
);
6371
};

src/components/record/recordSidebar.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,40 @@
11
import { RecordButton, StopButton } from "./buttons";
22
import { Display, CornersButton, HomeButton, PgnButton, Sidebar, DigitalButton } from "../common";
33
import { setBoolean, setStringArray } from "../../types";
4+
import FenButton from "../common/fenButton";
45

5-
const RecordSidebar = ({ piecesModelRef, xcornersModelRef, videoRef, canvasRef, sidebarRef, playing, setPlaying, text, setText,
6-
digital, setDigital }: {
6+
const RecordSidebar = ({ piecesModelRef, xcornersModelRef, videoRef, canvasRef, sidebarRef,
7+
playing, setPlaying, text, setText, digital, setDigital, cornersRef }: {
78
piecesModelRef: any, xcornersModelRef: any, videoRef: any, canvasRef: any, sidebarRef: any,
89
playing: boolean, setPlaying: setBoolean,
910
text: string[], setText: setStringArray,
10-
digital: boolean, setDigital: setBoolean
11+
digital: boolean, setDigital: setBoolean,
12+
cornersRef: any
1113
}) => {
1214
return (
1315
<Sidebar sidebarRef={sidebarRef} >
1416
<li className="my-1">
1517
<CornersButton piecesModelRef={piecesModelRef} xcornersModelRef={xcornersModelRef} videoRef={videoRef} canvasRef={canvasRef}
1618
setText={setText} />
1719
</li>
20+
<li className="my-1">
21+
<FenButton piecesModelRef={piecesModelRef} videoRef={videoRef}
22+
canvasRef={canvasRef} setText={setText} cornersRef={cornersRef} />
23+
</li>
1824
<li className="my-1">
1925
<div className="btn-group w-100" role="group">
2026
<RecordButton playing={playing} setPlaying={setPlaying} />
2127
<StopButton setPlaying={setPlaying} setText={setText} />
2228
</div>
2329
</li>
24-
<li className="my-1">
25-
<DigitalButton digital={digital} setDigital={setDigital} />
26-
</li>
2730
<li className="border-top"></li>
2831
<li className="my-1">
2932
<Display text={text} />
3033
</li>
3134
<li className="border-top"></li>
3235
<li className="my-1">
3336
<div className="btn-group w-100" role="group">
37+
<DigitalButton digital={digital} setDigital={setDigital} />
3438
<PgnButton setText={setText} playing={playing} />
3539
<HomeButton />
3640
</div>

src/components/upload/uploadSidebar.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { VideoButton, PlayButton, RestartButton, PlaybackButtons, StopButton } from "./buttons";
22
import { CornersButton, HomeButton, Display, PgnButton, Sidebar, DigitalButton } from "../common";
33
import { setBoolean, setStringArray } from "../../types";
4+
import FenButton from "../common/fenButton";
45

5-
const UploadSidebar = ({ videoRef, xcornersModelRef, piecesModelRef, canvasRef, sidebarRef, text, setText,
6-
playing, setPlaying, digital, setDigital }: {
6+
const UploadSidebar = ({ videoRef, xcornersModelRef, piecesModelRef, canvasRef,
7+
sidebarRef, text, setText, playing, setPlaying, digital, setDigital, cornersRef }: {
78
videoRef: any, xcornersModelRef: any, piecesModelRef: any, canvasRef: any, sidebarRef: any,
89
text: string[], setText: setStringArray,
910
playing: boolean, setPlaying: setBoolean,
10-
digital: boolean, setDigital: setBoolean
11+
digital: boolean, setDigital: setBoolean,
12+
cornersRef: any
1113
}) => {
1214
return (
1315
<Sidebar sidebarRef={sidebarRef}>
@@ -18,6 +20,10 @@ playing, setPlaying, digital, setDigital }: {
1820
<CornersButton piecesModelRef={piecesModelRef} xcornersModelRef={xcornersModelRef}
1921
videoRef={videoRef} canvasRef={canvasRef} setText={setText} />
2022
</li>
23+
<li className="my-1">
24+
<FenButton piecesModelRef={piecesModelRef} videoRef={videoRef}
25+
canvasRef={canvasRef} setText={setText} cornersRef={cornersRef} />
26+
</li>
2127
<li className="my-1">
2228
<div className="btn-group w-100" role="group">
2329
<PlayButton videoRef={videoRef} playing={playing} setPlaying={setPlaying} />
@@ -28,16 +34,14 @@ playing, setPlaying, digital, setDigital }: {
2834
<li className="my-1">
2935
<PlaybackButtons videoRef={videoRef} />
3036
</li>
31-
<li className="my-1">
32-
<DigitalButton digital={digital} setDigital={setDigital} />
33-
</li>
3437
<li className="border-top"></li>
3538
<li className="my-1">
3639
<Display text={text} />
3740
</li>
3841
<li className="border-top"></li>
3942
<li className="my-1">
4043
<div className="btn-group w-100" role="group">
44+
<DigitalButton digital={digital} setDigital={setDigital} />
4145
<PgnButton setText={setText} playing={playing} />
4246
<HomeButton />
4347
</div>

src/slices/gameSlice.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ const gameSlice = createSlice({
2323
gameResetPgnAndFen(state) {
2424
state.pgn = `[FEN "${state.start}"]`;
2525
state.fen = state.start;
26+
},
27+
gameResetStart(state) {
28+
state.start = startingPosition;
2629
}
2730
}
2831
})
@@ -32,5 +35,5 @@ export const gameSelect = () => {
3235
}
3336

3437

35-
export const { gameSetPgnAndFen, gameSetStart, gameResetPgnAndFen } = gameSlice.actions
38+
export const { gameSetPgnAndFen, gameSetStart, gameResetPgnAndFen, gameResetStart } = gameSlice.actions
3639
export default gameSlice.reducer

src/utils/constants.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
import { PieceSymbol, Square } from "chess.js";
12
import { CornersKey } from "../types";
23

34
export const MODEL_WIDTH: number = 480;
45
export const MODEL_HEIGHT: number = 288;
56
export const MARKER_RADIUS: number = 25;
67
export const MARKER_DIAMETER: number = 2 * MARKER_RADIUS;
78
export const LABELS: string[] = ["b", "k", "n", "p", "q", "r", "B", "K", "N", "P", "Q", "R"];
8-
export const SQUARE_NAMES: string[] = ['a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1',
9+
export const PIECE_SYMBOLS: PieceSymbol[] = ["b", "k", "n", "p", "q", "r"];
10+
export const SQUARE_NAMES: Square[] = ['a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1',
911
'a2', 'b2', 'c2', 'd2', 'e2', 'f2', 'g2', 'h2',
1012
'a3', 'b3', 'c3', 'd3', 'e3', 'f3', 'g3', 'h3',
1113
'a4', 'b4', 'c4', 'd4', 'e4', 'f4', 'g4', 'h4',

src/utils/detect.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,21 @@ export const invalidVideo = (videoRef: any) => {
66
return true;
77
}
88

9-
// If it's uploaded video, the src must start with "blob"
10-
if (videoRef.current.autoplay === false && !(videoRef.current.src.startsWith("blob"))) {
11-
return true
12-
}
9+
if (videoRef.current.autoplay) {
10+
// Record check
11+
if (videoRef.current?.srcObject === null) {
12+
return true;
13+
}
14+
} else {
15+
// Upload check
16+
const src = videoRef.current?.src;
17+
if (src === null) {
18+
return true;
19+
}
1320

14-
// srcObject is used for recording, src is used for uploading
15-
if (videoRef.current?.srcObject === null && videoRef.current?.src === null) {
16-
return true;
21+
if (!(src.startsWith("blob"))) {
22+
return true;
23+
}
1724
}
1825

1926
return false;

0 commit comments

Comments
 (0)