| 6 | "": "const { game_id, cancelDate } = props;\\\\n\\\\nconst contractId = \\\\\\\"app.chess-game.near\\\\\\\";\\\\nconst chessBoardWidget = \\\\\\\"chess-game.near/widget/ChessBoard\\\\\\\";\\\\nconst buttonWidget = \\\\\\\"chess-game.near/widget/ChessGameButton\\\\\\\";\\\\nconst loadingWidget = \\\\\\\"chess-game.near/widget/ChessGameLoading\\\\\\\";\\\\n\\\\nif (!game_id) return <div>\\\\\\\"game_id\\\\\\\" prop required</div>;\\\\n\\\\nNear.asyncView(contractId, \\\\\\\"get_board\\\\\\\", {\\\\n game_id,\\\\n})\\\\n .then((board) => {\\\\n State.update({\\\\n board,\\\\n });\\\\n })\\\\n .catch((err) => {\\\\n console.log(err);\\\\n State.update({\\\\n error: err,\\\\n });\\\\n });\\\\nNear.asyncView(contractId, \\\\\\\"game_info\\\\\\\", {\\\\n game_id,\\\\n})\\\\n .then((gameInfo) => {\\\\n State.update({\\\\n gameInfo,\\\\n });\\\\n })\\\\n .catch((err) => {\\\\n console.log(err);\\\\n State.update({\\\\n error: err,\\\\n });\\\\n });\\\\n\\\\nState.init({\\\\n board: state.board,\\\\n gameInfo: state.gameInfo,\\\\n move: \\\\\\\"\\\\\\\",\\\\n assetType: state.assetType ?? \\\\\\\"default\\\\\\\",\\\\n error: state.error,\\\\n});\\\\n\\\\nif (!state.board || !state.gameInfo) {\\\\n return <Widget src={loadingWidget} />;\\\\n}\\\\nif (state.error) {\\\\n return \\\\\\\"The game no longer exists. Please return to lobby\\\\\\\";\\\\n}\\\\n\\\\nconst BoardView = styled.div`\\\\n display: flex;\\\\n flex-direction: column;\\\\n align-items: center;\\\\n justify-content: center;\\\\n`;\\\\nconst GameInfo = styled.div`\\\\n display: flex;\\\\n flex-direction: column;\\\\n justify-content: center;\\\\n font-size: 1.4rem;\\\\n margin: 1rem;\\\\n`;\\\\n\\\\nconst renderPlayer = (color, player) => {\\\\n const usesOldSerialization = gameInfo.black.type == null;\\\\n if (usesOldSerialization && player.Human) {\\\\n return (\\\\n <div>\\\\n Player {color}: {player.Human}\\\\n </div>\\\\n );\\\\n } else if (player.type === \\\\\\\"Human\\\\\\\") {\\\\n return (\\\\n <div>\\\\n Player {color}: {player.value}\\\\n </div>\\\\n );\\\\n } else if (usesOldSerialization && player.Ai) {\\\\n return (\\\\n <div>\\\\n Player {color}: AI ({player.Ai})\\\\n </div>\\\\n );\\\\n } else if (player.type === \\\\\\\"Ai\\\\\\\") {\\\\n return (\\\\n <div>\\\\n Player {color}: AI ({player.value})\\\\n </div>\\\\n );\\\\n } else {\\\\n const err = new Error(`Unable to render player: ${player}`);\\\\n console.error(err);\\\\n return \\\\\\\"\\\\\\\";\\\\n }\\\\n};\\\\n\\\\nconst TurnInput = styled.input`\\\\n border-radius: 4px;\\\\n border: 1px solid black;\\\\n`;\\\\nconst SendButton = styled.button`\\\\n border-radius: 4px;\\\\n`;\\\\n\\\\nconst updateMove = (event) => {\\\\n State.update({\\\\n move: event.target.value,\\\\n });\\\\n};\\\\nconst selectAsset = (event) => {\\\\n State.update({\\\\n assetType: event.target.value,\\\\n });\\\\n};\\\\n\\\\nconst playMove = () => {\\\\n if (!state.move) return;\\\\n Near.call(\\\\n contractId,\\\\n \\\\\\\"play_move\\\\\\\",\\\\n {\\\\n game_id,\\\\n mv: state.move,\\\\n },\\\\n \\\\\\\"300000000000000\\\\\\\"\\\\n );\\\\n};\\\\n\\\\nconst Footer = styled.div`\\\\n display: flex;\\\\n flex-direction: column;\\\\n padding-bottom: 2rem;\\\\n max-width: 400px;\\\\n`;\\\\n\\\\nconst text = `\\\\n _A valid move will be parsed from a string._\\\\n \\\\n _Possible valid formats include:_\\\\n - \\\\\\\\\\\\\\\"e2e4\\\\\\\\\\\\\\\"\\\\n - \\\\\\\\\\\\\\\"e2 e4\\\\\\\\\\\\\\\"\\\\n - \\\\\\\\\\\\\\\"e2 to e4\\\\\\\\\\\\\\\"\\\\n - \\\\\\\\\\\\\\\"castle queenside\\\\\\\\\\\\\\\"\\\\n - \\\\\\\\\\\\\\\"castle kingside\\\\\\\\\\\\\\\"\\\\\\'\\\\n\\\\n _If a game stalls because players stop sending moves, it can be stopped after ~3 days._\\\\n _Cancelling a game won\\\\\\'t affect your ELO rating, but resigning will result in a lost match._\\\\n`;\\\\nconst assetText = `\\\\n _Assets are free to use right now, but will later be unlocked via NFTs._\\\\n`;\\\\n\\\\nreturn (\\\\n <BoardView>\\\\n <GameInfo>\\\\n <div>ID: {game_id[0]}</div>\\\\n {renderPlayer(\\\\\\\"White\\\\\\\", state.gameInfo.white)}\\\\n {renderPlayer(\\\\\\\"Black\\\\\\\", state.gameInfo.black)}\\\\n <div>Turn: {state.gameInfo.turn_color}</div>\\\\n {cancelDate && <div>Cancellable: {cancelDate.toLocaleString()}</div>}\\\\n </GameInfo>\\\\n <Widget\\\\n src={chessBoardWidget}\\\\n props={{ board: state.board, assetType: state.assetType }}\\\\n />\\\\n <Footer>\\\\n <h3>Your Move:</h3>\\\\n <div class=\\\\\\\"text-center\\\\\\\">\\\\n <TurnInput\\\\n type=\\\\\\\"text\\\\\\\"\\\\n required\\\\n autocomplete=\\\\\\\"off\\\\\\\"\\\\n id=\\\\\\\"turn\\\\\\\"\\\\n value={state.move}\\\\n onChange={updateMove}\\\\n />\\\\n <Widget\\\\n src={buttonWidget}\\\\n props={{\\\\n onClick: playMove,\\\\n fontSize: \\\\\\\"1.2rem\\\\\\\",\\\\n content: \\\\\\\"Play\\\\\\\",\\\\n inline: true,\\\\n }}\\\\n />\\\\n </div>\\\\n <Markdown text={text} />\\\\n\\\\n {\\\\n // <h3>Assets:</h3>\\\\n // <select onChange={selectAsset} value={state.assetType}>\\\\n // <option value=\\\\\\\"default\\\\\\\">Regular</option>\\\\n // <option value=\\\\\\\"hk\\\\\\\">Hollow Knight Style</option>\\\\n // </select>\\\\n // <Markdown text={assetText} />\\\\n }\\\\n </Footer>\\\\n </BoardView>\\\\n);\\\\n", |