From 2701df1e3b03c7c605ccf212a02987d53fbd0609 Mon Sep 17 00:00:00 2001
From: notoraptor <notoraptor@users.noreply.github.com>
Date: Wed, 17 Jul 2019 15:16:43 -0400
Subject: [web] Make button "Delete all" remove only orders from current se…
 (#49)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Make button "Delete all" remove only orders from current selected power.
- Reorganize code
- [web] Remove bugged and useless function gameReloaded() from game page.
- This function caused error `engine.getPhaseType is not a function` for
  games with deadlines.
- Move function saveGameToDisk into its own file.
- [web] Add documentation to methods involved in orders management to help understand what happens.
- Move methods getServerOrders() from game GUI component to game engine object.
- Rename method onSetNoOrders to onSetEmptyOrdersSet.
- Rename property in PowerActionsForm: onNoOrders => onPass.
- [web] Update sending orders to send request clearOrders when local orders list is null.

- Renamed local file:
  - components/power_order => power_orders
  - forms/power_actions_form => power_order_creation_form

- Move power orders buttons bar to a separate file:
  - components/power_orders_actions_bar

- [web] Improve messages about local/server defined orders.
---
 diplomacy/web/src/gui/core/page.jsx | 375 ------------------------------------
 1 file changed, 375 deletions(-)
 delete mode 100644 diplomacy/web/src/gui/core/page.jsx

(limited to 'diplomacy/web/src/gui/core/page.jsx')

diff --git a/diplomacy/web/src/gui/core/page.jsx b/diplomacy/web/src/gui/core/page.jsx
deleted file mode 100644
index 5e7aee2..0000000
--- a/diplomacy/web/src/gui/core/page.jsx
+++ /dev/null
@@ -1,375 +0,0 @@
-// ==============================================================================
-// Copyright (C) 2019 - Philip Paquette, Steven Bocco
-//
-//  This program is free software: you can redistribute it and/or modify it under
-//  the terms of the GNU Affero General Public License as published by the Free
-//  Software Foundation, either version 3 of the License, or (at your option) any
-//  later version.
-//
-//  This program is distributed in the hope that it will be useful, but WITHOUT
-//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-//  FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
-//  details.
-//
-//  You should have received a copy of the GNU Affero General Public License along
-//  with this program.  If not, see <https://www.gnu.org/licenses/>.
-// ==============================================================================
-/** Main class to use to create app GUI. **/
-
-import React from "react";
-import {ContentConnection} from "../diplomacy/contents/content_connection";
-import {UTILS} from "../../diplomacy/utils/utils";
-import {Diplog} from "../../diplomacy/utils/diplog";
-import {FancyBox} from "./fancybox";
-import {DipStorage} from "../diplomacy/utils/dipStorage";
-import {PageContext} from "../diplomacy/widgets/page_context";
-import {ContentGames} from "../diplomacy/contents/content_games";
-import {loadGameFromDisk} from "../diplomacy/utils/load_game_from_disk";
-import {ContentGame} from "../diplomacy/contents/content_game";
-
-export class Page extends React.Component {
-
-    constructor(props) {
-        super(props);
-        this.connection = null;
-        this.channel = null;
-        this.availableMaps = null;
-        this.state = {
-            // fancybox,
-            fancyTitle: null,
-            onFancyBox: null,
-            // Page messages
-            error: null,
-            info: null,
-            success: null,
-            // Page content parameters
-            name: null,
-            body: null,
-            // Games.
-            games: {}, // Games found.
-            myGames: {}  // Games locally stored.
-        };
-        this.error = this.error.bind(this);
-        this.info = this.info.bind(this);
-        this.success = this.success.bind(this);
-        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);
-        this.onReconnectionError = this.onReconnectionError.bind(this);
-    }
-
-    static wrapMessage(message) {
-        return message ? `(${UTILS.date()}) ${message}` : '';
-    }
-
-    static __sort_games(games) {
-        // Sort games with not-joined games first, else compare game ID.
-        games.sort((a, b) => (((a.role ? 1 : 0) - (b.role ? 1 : 0)) || a.game_id.localeCompare(b.game_id)));
-        return games;
-    }
-
-    static defaultPage() {
-        return <ContentConnection/>;
-    }
-
-    onReconnectionError(error) {
-        this.__disconnect(error);
-    }
-
-    //// Methods to load a global fancybox.
-
-    loadFancyBox(title, callback) {
-        this.setState({fancyTitle: title, onFancyBox: callback});
-    }
-
-    unloadFancyBox() {
-        this.setState({fancyTitle: null, onFancyBox: null});
-    }
-
-    //// Methods to load a page.
-
-    load(name, body, messages) {
-        const newState = {};
-        if (messages) {
-            for (let key of ['error', 'info', 'success'])
-                newState[key] = Page.wrapMessage(messages[key]);
-        }
-        Diplog.printMessages(newState);
-        newState.name = name;
-        newState.body = body;
-        this.setState(newState);
-    }
-
-    loadGames(messages) {
-        this.load(
-            'games',
-            <ContentGames myGames={this.getMyGames()} gamesFound={this.getGamesFound()}/>,
-            messages
-        );
-    }
-
-    loadGameFromDisk() {
-        loadGameFromDisk(
-            (game) => this.load(
-                `game: ${game.game_id}`,
-                <ContentGame data={game}/>,
-                {success: `Game loaded from disk: ${game.game_id}`}
-            ),
-            this.error
-        );
-    }
-
-    getName() {
-        return this.state.name;
-    }
-
-    //// Methods to sign out channel and go back to connection page.
-
-    __disconnect(error) {
-        // Clear local data and go back to connection page.
-        this.connection.close();
-        this.connection = null;
-        this.channel = null;
-        this.availableMaps = null;
-        const message = Page.wrapMessage(error ? `${error.toString()}` : `Disconnected from channel and server.`);
-        Diplog.success(message);
-        this.setState({
-            error: error ? message : null,
-            info: null,
-            success: error ? null : message,
-            name: null,
-            body: null,
-            // When disconnected, remove all games previously loaded.
-            games: {},
-            myGames: {}
-        });
-    }
-
-    logout() {
-        // Disconnect channel and go back to connection page.
-        if (this.channel) {
-            this.channel.logout()
-                .then(() => this.__disconnect())
-                .catch(error => this.error(`Error while disconnecting: ${error.toString()}.`));
-        } else {
-            this.__disconnect();
-        }
-    }
-
-    //// Methods to be used to set page title and messages.
-
-    error(message) {
-        message = Page.wrapMessage(message);
-        Diplog.error(message);
-        this.setState({error: message});
-    }
-
-    info(message) {
-        message = Page.wrapMessage(message);
-        Diplog.info(message);
-        this.setState({info: message});
-    }
-
-    success(message) {
-        message = Page.wrapMessage(message);
-        Diplog.success(message);
-        this.setState({success: message});
-    }
-
-    warn(message) {
-        this.info(message);
-    }
-
-    //// Methods to manage games.
-
-    updateMyGames(gamesToAdd) {
-        // Update state myGames with given games. This method does not update local storage.
-        const myGames = Object.assign({}, this.state.myGames);
-        let gamesFound = null;
-        for (let gameToAdd of gamesToAdd) {
-            myGames[gameToAdd.game_id] = gameToAdd;
-            if (this.state.games.hasOwnProperty(gameToAdd.game_id)) {
-                if (!gamesFound)
-                    gamesFound = Object.assign({}, this.state.games);
-                gamesFound[gameToAdd.game_id] = gameToAdd;
-            }
-        }
-        if (!gamesFound)
-            gamesFound = this.state.games;
-        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));
-    }
-
-    getGamesFound() {
-        return Page.__sort_games(Object.values(this.state.games));
-    }
-
-    addGamesFound(gamesToAdd) {
-        const gamesFound = {};
-        for (let game of gamesToAdd) {
-            gamesFound[game.game_id] = (
-                this.state.myGames.hasOwnProperty(game.game_id) ?
-                    this.state.myGames[game.game_id] : game
-            );
-        }
-        this.setState({games: gamesFound});
-    }
-
-    leaveGame(gameID) {
-        if (this.state.myGames.hasOwnProperty(gameID)) {
-            const game = this.state.myGames[gameID];
-            if (game.client) {
-                game.client.leave()
-                    .then(() => {
-                        this.disconnectGame(gameID).then(() => {
-                            this.loadGames({info: `Game ${gameID} left.`});
-                        });
-                    })
-                    .catch(error => this.error(`Error when leaving game ${gameID}: ${error.toString()}`));
-            }
-        } else {
-            this.loadGames({info: `No game to left.`});
-        }
-    }
-
-    _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) {
-        const game = this.getGame(gameID);
-        if (game) {
-            if (game.client)
-                game.client.clearAllCallbacks();
-            return this.channel.getGamesInfo({games: [gameID]})
-                .then(gamesInfo => {
-                    this.updateMyGames(gamesInfo);
-                })
-                .catch(error => this.error(`Error while leaving game ${gameID}: ${error.toString()}`));
-        }
-        return null;
-    }
-
-    _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;
-        return {myGames: myGames, games: gamesFound};
-    }
-
-    _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);
-            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);
-    }
-
-    //// Render method.
-
-    render() {
-        const successMessage = this.state.success || '-';
-        const infoMessage = this.state.info || '-';
-        const errorMessage = this.state.error || '-';
-        return (
-            <PageContext.Provider value={this}>
-                <div className="page container-fluid" id={this.state.contentName}>
-                    <div className={'top-msg row'}>
-                        <div title={successMessage !== '-' ? successMessage : ''}
-                             className={'col-sm-4 msg success ' + (this.state.success ? 'with-msg' : 'no-msg')}
-                             onClick={() => this.success()}>
-                            {successMessage}
-                        </div>
-                        <div title={infoMessage !== '-' ? infoMessage : ''}
-                             className={'col-sm-4 msg info ' + (this.state.info ? 'with-msg' : 'no-msg')}
-                             onClick={() => this.info()}>
-                            {infoMessage}
-                        </div>
-                        <div title={errorMessage !== '-' ? errorMessage : ''}
-                             className={'col-sm-4 msg error ' + (this.state.error ? 'with-msg' : 'no-msg')}
-                             onClick={() => this.error()}>
-                            {errorMessage}
-                        </div>
-                    </div>
-                    {this.state.body || Page.defaultPage()}
-                    {this.state.onFancyBox && (
-                        <FancyBox title={this.state.fancyTitle} onClose={this.unloadFancyBox}>
-                            {this.state.onFancyBox()}
-                        </FancyBox>
-                    )}
-                </div>
-            </PageContext.Provider>
-        );
-    }
-}
-- 
cgit v1.2.3

