127 lines
3.9 KiB
TypeScript
127 lines
3.9 KiB
TypeScript
|
import {addNTimes, PlayableLetterData} from "./utils";
|
||
|
import {useEffect, useState} from "react";
|
||
|
import {Modal} from "./Modal";
|
||
|
import {Letter as LetterData} from "word_grid";
|
||
|
import * as React from "react";
|
||
|
|
||
|
export function TileExchangeModal(props: {
|
||
|
playerLetters: PlayableLetterData[],
|
||
|
isOpen: boolean,
|
||
|
setOpen: (isOpen: boolean) => void,
|
||
|
exchangeFunction: (selectedArray: Array<boolean>) => void
|
||
|
}) {
|
||
|
|
||
|
function clearExchangeTiles() {
|
||
|
const array: boolean[] = [];
|
||
|
addNTimes(array, false, props.playerLetters.length);
|
||
|
return array;
|
||
|
}
|
||
|
|
||
|
const [tilesToExchange, setTilesToExchange] = useState<boolean[]>(clearExchangeTiles);
|
||
|
useEffect(() => {
|
||
|
setTilesToExchange(clearExchangeTiles());
|
||
|
}, [props.playerLetters])
|
||
|
|
||
|
let tilesExchangedSelected = 0;
|
||
|
for (let i of tilesToExchange) {
|
||
|
if(i) {
|
||
|
tilesExchangedSelected++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return <Modal isOpen={props.isOpen} setOpen={(isOpen) => {
|
||
|
setTilesToExchange(clearExchangeTiles());
|
||
|
props.setOpen(isOpen);
|
||
|
}}>
|
||
|
<div className="tile-exchange-dialog">
|
||
|
<div className="instructions">
|
||
|
Click on each tile you'd like to exchange. You currently have {tilesExchangedSelected} tiles selected.
|
||
|
</div>
|
||
|
<div className="selection-buttons">
|
||
|
<button onClick={(e) => {
|
||
|
const array: boolean[] = [];
|
||
|
addNTimes(array, true, props.playerLetters.length);
|
||
|
setTilesToExchange(array);
|
||
|
}}>Select All</button>
|
||
|
<button onClick={(e) => {
|
||
|
setTilesToExchange(clearExchangeTiles());
|
||
|
}}>Select None</button>
|
||
|
</div>
|
||
|
|
||
|
<TilesExchangedTray
|
||
|
tray={props.playerLetters}
|
||
|
selectedArray={tilesToExchange}
|
||
|
setSelectedArray={setTilesToExchange}
|
||
|
trayLength={props.playerLetters.length}
|
||
|
/>
|
||
|
<div className="finish-buttons">
|
||
|
<button onClick={() => {
|
||
|
setTilesToExchange(clearExchangeTiles());
|
||
|
props.setOpen(false);
|
||
|
}}>Cancel</button>
|
||
|
<button disabled = {tilesExchangedSelected == 0} onClick={(e) => {
|
||
|
props.exchangeFunction(tilesToExchange);
|
||
|
props.setOpen(false);
|
||
|
}}>Exchange</button>
|
||
|
</div>
|
||
|
</div>
|
||
|
</Modal>;
|
||
|
|
||
|
}
|
||
|
|
||
|
function TilesExchangedTray(props: {
|
||
|
tray: Array<PlayableLetterData>,
|
||
|
trayLength: number,
|
||
|
selectedArray: Array<boolean>,
|
||
|
setSelectedArray: (x: Array<boolean>) => void,
|
||
|
}){
|
||
|
|
||
|
const divContent = [];
|
||
|
for(let i=0; i<props.trayLength; i++) {
|
||
|
divContent.push(<span key={i} />); // empty tile elements
|
||
|
}
|
||
|
|
||
|
for(let i = 0; i<props.trayLength; i++){
|
||
|
const tileData = props.tray[i];
|
||
|
|
||
|
const toggleFunction = () => {
|
||
|
props.selectedArray[i] = !props.selectedArray[i];
|
||
|
props.setSelectedArray(props.selectedArray.slice());
|
||
|
}
|
||
|
|
||
|
if(tileData != null){
|
||
|
divContent[tileData.index] =
|
||
|
<DummyExchangeTile key={tileData.index} letter={tileData} isSelected={props.selectedArray[i]} onClick={toggleFunction}/>;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return <div className="tray">
|
||
|
{divContent}
|
||
|
</div>;
|
||
|
|
||
|
}
|
||
|
|
||
|
function DummyExchangeTile(props: {
|
||
|
letter: LetterData,
|
||
|
isSelected: boolean,
|
||
|
onClick: () => void,
|
||
|
}){
|
||
|
|
||
|
let textClassName = "text";
|
||
|
if(props.letter.is_blank) {
|
||
|
textClassName += " prev-blank";
|
||
|
}
|
||
|
|
||
|
let letterClassName = "letter";
|
||
|
if(props.isSelected){
|
||
|
letterClassName += ' selected-tile';
|
||
|
}
|
||
|
|
||
|
|
||
|
return <div className={letterClassName} onClick={props.onClick}>
|
||
|
<div className={textClassName}>{props.letter.text}</div>
|
||
|
<div className="letter-points">{props.letter.points}</div>
|
||
|
</div>;
|
||
|
}
|