events.onerror = function(event) {
if (event.target.readyState === EventSource.CLOSED) {
+ setTimeout(() => {
add_message("danger", "Connection to server lost.");
+ }, 1000);
}
};
* Game and supporting classes *
*********************************************************/
+function copy_to_clipboard(id)
+{
+ const tmp = document.createElement("input");
+ tmp.setAttribute("value", document.getElementById(id).innerHTML);
+ document.body.appendChild(tmp);
+ tmp.select();
+ document.execCommand("copy");
+ document.body.removeChild(tmp);
+}
+
function GameInfo(props) {
if (! props.id)
return null;
return (
<div className="game-info">
- <h2>{props.id}</h2>
- Invite a friend to play by sending this URL: {props.url}
+ <span className="game-id">{props.id}</span>
+ {" "}
+ Share this link to invite a friend:{" "}
+ <span id="game-share-url">{props.url}</span>
+ {" "}
+ <button
+ className="inline"
+ onClick={() => copy_to_clipboard('game-share-url')}
+ >Copy Link</button>
</div>
);
}
return (
<div className="player-info">
- <h2>Players</h2>
+ <span className="players-header">Players: </span>
{props.player.name}
{props.player.team ? ` (${props.player.team})` : ""}
{props.first_move ? "" : " "}
);
}
+function Glyph(props) {
+
+ const glyph_dots = [];
+
+ let last_square = 0;
+ for (let i = 0; i < 9; i++) {
+ if (props.squares[i])
+ last_square = i;
+ }
+
+ const height = Math.floor(20 * (Math.floor(last_square / 3) + 1));
+
+ const viewbox=`0 0 60 ${height}`;
+
+ for (let row = 0; row < 3; row++) {
+ for (let col = 0; col < 3; col++) {
+ if (props.squares[3 * row + col]) {
+ let cy = 10 + 20 * row;
+ let cx = 10 + 20 * col;
+ glyph_dots.push(
+ <circle
+ key={3 * row + col}
+ cx={cx}
+ cy={cy}
+ r="8"
+ />
+ );
+ }
+ }
+ }
+
+ return (<div className="glyph-and-name">
+ {props.name}
+ <div className="glyph">
+ <svg viewBox={viewbox}>
+ <g fill="#287789">
+ {glyph_dots}
+ </g>
+ </svg>
+ </div>
+ </div>
+ );
+}
+
function Square(props) {
let className = "square";
game_info: {},
player_info: {},
other_players: [],
- squares: Array(9).fill(null).map(() => Array(9).fill(null)),
+ squares: [...Array(9)].map(() => Array(9).fill(null)),
moves: 0,
next_to_play: "+"
};
onClick={(i,j) => this.handle_click(i, j, first_move)}
/>
</div>
+ </div>,
+ <div key="glyphs" className="glyphs">
+ <Glyph
+ name="Single"
+ squares={[1,0,0,
+ 0,0,0,
+ 0,0,0]}
+ />
+ <Glyph
+ name="Double"
+ squares={[1,1,0,
+ 0,0,0,
+ 0,0,0]}
+ />
+ <Glyph
+ name="Line"
+ squares={[1,1,1,
+ 0,0,0,
+ 0,0,0]}
+ />
+ <Glyph
+ name="Pipe"
+ squares={[0,0,1,
+ 1,1,1,
+ 0,0,0]}
+ />
+ <Glyph
+ name="Squat-T"
+ squares={[1,1,1,
+ 0,1,0,
+ 0,0,0]}
+ />
+ <Glyph
+ name="4-block"
+ squares={[1,1,0,
+ 1,1,0,
+ 0,0,0]}
+ />
+ <Glyph
+ name="T"
+ squares={[1,1,1,
+ 0,1,0,
+ 0,1,0]}
+ />
+ <Glyph
+ name="Cross"
+ squares={[0,1,0,
+ 1,1,1,
+ 0,1,0]}
+ />
+ <Glyph
+ name="6-block"
+ squares={[1,1,1,
+ 1,1,1,
+ 0,0,0]}
+ />
+ <Glyph
+ name="Bomber"
+ squares={[1,1,1,
+ 0,1,1,
+ 0,0,1]}
+ />
+ <Glyph
+ name="Chair"
+ squares={[0,0,1,
+ 1,1,1,
+ 1,0,1]}
+ />
+ <Glyph
+ name="J"
+ squares={[0,0,1,
+ 1,0,1,
+ 1,1,1]}
+ />
+ <Glyph
+ name="Earring"
+ squares={[0,1,1,
+ 1,0,1,
+ 1,1,1]}
+ />
+ <Glyph
+ name="House"
+ squares={[0,1,0,
+ 1,1,1,
+ 1,1,1]}
+ />
+ <Glyph
+ name="H"
+ squares={[1,0,1,
+ 1,1,1,
+ 1,0,1]}
+ />
+ <Glyph
+ name="U"
+ squares={[1,0,1,
+ 1,0,1,
+ 1,1,1]}
+ />
+ <Glyph
+ name="Ottoman"
+ squares={[1,1,1,
+ 1,1,1,
+ 1,0,1]}
+ />
+ <Glyph
+ name="O"
+ squares={[1,1,1,
+ 1,0,1,
+ 1,1,1]}
+ />
+ <Glyph
+ name="9-block"
+ squares={[1,1,1,
+ 1,1,1,
+ 1,1,1]}
+ />
</div>
];
}