import * as React from "react"; import {ChangeEvent, JSX} from "react"; import {PlayerAndScore} from "../../pkg/word_grid"; import { CellType, cellTypeToDetails, CoordinateData, GridArrowData, GridArrowDispatch, GridArrowDispatchActionType, HighlightableLetterData, LocationType, PlayableLetterData, TileDispatch, TileDispatchActionType, } from "./utils"; export function TileSlot(props: { tile?: React.JSX.Element | undefined, location: CoordinateData, tileDispatch: TileDispatch, arrowDispatch?: GridArrowDispatch, }): React.JSX.Element { let isDraggable = props.tile !== undefined; function onDragStart(e: React.DragEvent) { e.dataTransfer.effectAllowed = "move"; e.dataTransfer.setData("wordGrid/coords", JSON.stringify(props.location)); } function onDrop(e: React.DragEvent) { const startLocation: CoordinateData = JSON.parse(e.dataTransfer.getData("wordGrid/coords")); const thisLocation = props.location; props.tileDispatch({action: TileDispatchActionType.MOVE, start: startLocation, end: thisLocation}); } let className = "tileSpot"; if (props.location.location === LocationType.GRID) { className += " ephemeral"; } let onClick: () => void; if(props.arrowDispatch != null && props.location.location == LocationType.GRID) { onClick = () => { props.arrowDispatch({action: GridArrowDispatchActionType.CYCLE, position: props.location.index}); } } else if(props.location.location == LocationType.TRAY && props.tile != null && props.tile.props.data.text != ' ' && props.tile.props.data.text != '') { onClick = () => { props.tileDispatch({ action: TileDispatchActionType.MOVE_TO_ARROW, end: undefined, start: props.location, }); } } return
{e.preventDefault()}} > {props.tile}
} export function Letter(props: { data: HighlightableLetterData, letterUpdater?: (value: string) => void }): React.JSX.Element { function modifyThisLetter(value:string){ props.letterUpdater(value); } function onBlankInput(e: ChangeEvent){ let value = e.target.value.toUpperCase(); if(value.length > 1){ value = value[value.length - 1]; } else if(value.length == 0){ modifyThisLetter(value); return; } // Now check that it's a letter let is_letter = value.match("[A-Z]") != null; if(is_letter){ modifyThisLetter(value); } else { // Cancel and do nothing e.preventDefault(); } } if(props.data.is_blank && props.data.ephemeral) { return
{props.data.points}
} else { let className = "text"; if (props.data.is_blank) { // not ephemeral className += " prev-blank"; } let letterClassName = "letter"; if (props.data.highlight) { letterClassName += " highlight"; } return
{props.data.text}
{props.data.points}
} } export function TileTray(props: { letters: Array, trayLength: number, trayDispatch: TileDispatch }): React.JSX.Element { let elements: JSX.Element[] = []; for (let i=0; i ); } props.letters .forEach((letter, i) => { if (letter != null && letter.location === LocationType.TRAY) { elements[letter.index] = { props.trayDispatch({action: TileDispatchActionType.SET_BLANK, blankIndex: i, newBlankValue: value}) }} />} key={"letter_tray" + letter.index} location={{location: LocationType.TRAY, index: letter.index}} tileDispatch={props.trayDispatch} /> } }); return (
{elements}
) } export function Arrow(props: { data: GridArrowData, dispatch: GridArrowDispatch, }) { return
; } export function Grid(props: { cellTypes: CellType[], playerLetters: Array, boardLetters: HighlightableLetterData[], tileDispatch: TileDispatch, arrow: GridArrowData, arrowDispatch: GridArrowDispatch, }) { const elements = props.cellTypes.map((ct, i) => { const {className, text} = cellTypeToDetails(ct); let tileElement: JSX.Element; if (props.boardLetters[i] !== undefined) { tileElement = ; } else { tileElement = <> {text} ; } let arrowElement: JSX.Element; if(props.arrow != null && props.arrow.position == i) { arrowElement = ; } return
{tileElement} {arrowElement}
; }); props.playerLetters .forEach((letter, i) => { if (letter != null && letter.location === LocationType.GRID) { const ct = props.cellTypes[letter.index]; const {className} = cellTypeToDetails(ct); elements[letter.index] =
{ props.tileDispatch({action: TileDispatchActionType.SET_BLANK, blankIndex: i, newBlankValue: value}); }} />} location={{location: LocationType.GRID, index: letter.index}} tileDispatch={props.tileDispatch} />
; } }); return
{elements}
} export function Scores(props: {playerScores: Array}){ let elements = props.playerScores.map((ps) => { return

{ps.name}

{ps.score}
; }); return
{elements}
}