diff options
Diffstat (limited to 'diplomacy/web/src/gui/core')
-rw-r--r-- | diplomacy/web/src/gui/core/delete_button.jsx | 43 | ||||
-rw-r--r-- | diplomacy/web/src/gui/core/page.jsx | 79 |
2 files changed, 114 insertions, 8 deletions
diff --git a/diplomacy/web/src/gui/core/delete_button.jsx b/diplomacy/web/src/gui/core/delete_button.jsx new file mode 100644 index 0000000..59141fd --- /dev/null +++ b/diplomacy/web/src/gui/core/delete_button.jsx @@ -0,0 +1,43 @@ +import React from "react"; +import {Button} from "./button"; +import PropTypes from "prop-types"; + +export class DeleteButton extends React.Component { + constructor(props) { + super(props); + this.state = {step: 0}; + this.onClick = this.onClick.bind(this); + } + + onClick() { + this.setState({step: this.state.step + 1}, () => { + if (this.state.step === 2) + this.props.onClick(); + }); + } + + render() { + let title = ''; + let color = ''; + if (this.state.step === 0) { + title = this.props.title; + color = 'secondary'; + } else if (this.state.step === 1) { + title = this.props.confirmTitle; + color = 'danger'; + } else if (this.state.step === 2) { + title = this.props.waitingTitle; + color = 'danger'; + } + return ( + <Button title={title} color={color} onClick={this.onClick} small={true} large={true}/> + ); + } +} + +DeleteButton.propTypes = { + title: PropTypes.string.isRequired, + confirmTitle: PropTypes.string.isRequired, + waitingTitle: PropTypes.string.isRequired, + onClick: PropTypes.func.isRequired +}; diff --git a/diplomacy/web/src/gui/core/page.jsx b/diplomacy/web/src/gui/core/page.jsx index ad830f1..560252c 100644 --- a/diplomacy/web/src/gui/core/page.jsx +++ b/diplomacy/web/src/gui/core/page.jsx @@ -55,6 +55,10 @@ export class Page extends React.Component { this.logout = this.logout.bind(this); this.loadGameFromDisk = this.loadGameFromDisk.bind(this); this.unloadFancyBox = this.unloadFancyBox.bind(this); + this._post_remove = this._post_remove.bind(this); + this._add_to_my_games = this._add_to_my_games.bind(this); + this._remove_from_my_games = this._remove_from_my_games.bind(this); + this._remove_from_games = this._remove_from_games.bind(this); } static wrapMessage(message) { @@ -194,6 +198,12 @@ export class Page extends React.Component { this.setState({myGames: myGames, games: gamesFound}); } + getGame(gameID) { + if (this.state.myGames.hasOwnProperty(gameID)) + return this.state.myGames[gameID]; + return this.state.games[gameID]; + } + getMyGames() { return Page.__sort_games(Object.values(this.state.myGames)); } @@ -230,9 +240,40 @@ export class Page extends React.Component { } } + _post_remove(gameID) { + this.disconnectGame(gameID) + .then(() => { + const myGames = this._remove_from_my_games(gameID); + const games = this._remove_from_games(gameID); + this.setState( + {games, myGames}, + () => this.loadGames({info: `Game ${gameID} deleted.`})); + }); + } + + removeGame(gameID) { + const game = this.getGame(gameID); + if (game) { + if (game.client) { + game.client.remove() + .then(() => this._post_remove(gameID)) + .catch(error => this.error(`Error when deleting game ${gameID}: ${error.toString()}`)); + } else { + this.channel.joinGame({game_id: gameID}) + .then(networkGame => { + networkGame.remove() + .then(() => this._post_remove(gameID)) + .catch(error => this.error(`Error when deleting game ${gameID}: ${error.toString()}`)); + }) + .catch(error => this.error(`Error when connecting to game to delete (${gameID}): ${error.toString()}`)); + } + } + } + + disconnectGame(gameID) { - if (this.state.myGames.hasOwnProperty(gameID)) { - const game = this.state.myGames[gameID]; + const game = this.getGame(gameID); + if (game) { if (game.client) game.client.clearAllCallbacks(); return this.channel.getGamesInfo({games: [gameID]}) @@ -244,26 +285,48 @@ export class Page extends React.Component { return null; } - addToMyGames(game) { - // Update state myGames with given game **and** update local storage. + _add_to_my_games(game) { const myGames = Object.assign({}, this.state.myGames); const gamesFound = this.state.games.hasOwnProperty(game.game_id) ? Object.assign({}, this.state.games) : this.state.games; myGames[game.game_id] = game; if (gamesFound.hasOwnProperty(game.game_id)) gamesFound[game.game_id] = game; - DipStorage.addUserGame(this.channel.username, game.game_id); - this.setState({myGames: myGames, games: gamesFound}, () => this.loadGames()); + return {myGames: myGames, games: gamesFound}; } - removeFromMyGames(gameID) { + _remove_from_my_games(gameID) { if (this.state.myGames.hasOwnProperty(gameID)) { const games = Object.assign({}, this.state.myGames); delete games[gameID]; DipStorage.removeUserGame(this.channel.username, gameID); - this.setState({myGames: games}, () => this.loadGames()); + return games; + } else { + return this.state.myGames; + } + } + + _remove_from_games(gameID) { + if (this.state.games.hasOwnProperty(gameID)) { + const games = Object.assign({}, this.state.games); + delete games[gameID]; + return games; + } else { + return this.state.games; } } + addToMyGames(game) { + // Update state myGames with given game **and** update local storage. + DipStorage.addUserGame(this.channel.username, game.game_id); + this.setState(this._add_to_my_games(game), () => this.loadGames()); + } + + removeFromMyGames(gameID) { + const myGames = this._remove_from_my_games(gameID); + if (myGames !== this.state.myGames) + this.setState({myGames}, () => this.loadGames()); + } + hasMyGame(gameID) { return this.state.myGames.hasOwnProperty(gameID); } |