summaryrefslogtreecommitdiff
path: root/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src')
-rw-r--r--frontend/src/@types/reflexbox.d.ts37
-rw-r--r--frontend/src/api/model.ts187
-rw-r--r--frontend/src/api/sevenWondersApi.ts104
-rw-r--r--frontend/src/api/websocket.ts60
-rw-r--r--frontend/src/components/Application.tsx16
-rw-r--r--frontend/src/components/game-browser/GameBrowser.tsx56
-rw-r--r--frontend/src/components/game-browser/GameList.css3
-rw-r--r--frontend/src/components/game-browser/GameList.tsx85
-rw-r--r--frontend/src/components/game-browser/GameStatus.tsx17
-rw-r--r--frontend/src/components/game-browser/PlayerCount.css3
-rw-r--r--frontend/src/components/game-browser/PlayerCount.tsx12
-rw-r--r--frontend/src/components/game-browser/PlayerInfo.tsx27
-rw-r--r--frontend/src/components/game/Board.css38
-rw-r--r--frontend/src/components/game/Board.tsx67
-rw-r--r--frontend/src/components/game/CardImage.css4
-rw-r--r--frontend/src/components/game/CardImage.tsx26
-rw-r--r--frontend/src/components/game/GameScene.css13
-rw-r--r--frontend/src/components/game/GameScene.tsx77
-rw-r--r--frontend/src/components/game/Hand.css50
-rw-r--r--frontend/src/components/game/Hand.tsx44
-rw-r--r--frontend/src/components/game/ProductionBar.css50
-rw-r--r--frontend/src/components/game/ProductionBar.tsx87
-rw-r--r--frontend/src/components/game/background-papyrus.jpgbin100272 -> 0 bytes
-rw-r--r--frontend/src/components/home/ChooseNameForm.tsx42
-rw-r--r--frontend/src/components/home/Home.css13
-rw-r--r--frontend/src/components/home/Home.tsx12
-rw-r--r--frontend/src/components/home/background-zeus-temple.jpgbin571089 -> 0 bytes
-rw-r--r--frontend/src/components/home/logo-7-wonders.pngbin301442 -> 0 bytes
-rw-r--r--frontend/src/components/lobby/Lobby.tsx56
-rw-r--r--frontend/src/components/lobby/PlayerList.tsx41
-rw-r--r--frontend/src/components/lobby/RadialPlayerList.tsx69
-rw-r--r--frontend/src/components/lobby/radial-list/RadialList.css23
-rw-r--r--frontend/src/components/lobby/radial-list/RadialList.tsx64
-rw-r--r--frontend/src/components/lobby/radial-list/RadialListItem.css11
-rw-r--r--frontend/src/components/lobby/radial-list/RadialListItem.tsx18
-rw-r--r--frontend/src/components/lobby/radial-list/radial-math.ts48
-rw-r--r--frontend/src/components/lobby/round-table.pngbin18527 -> 0 bytes
-rw-r--r--frontend/src/global-styles.css0
-rw-r--r--frontend/src/index.tsx21
-rw-r--r--frontend/src/react-app-env.d.ts1
-rw-r--r--frontend/src/reducers.ts31
-rw-r--r--frontend/src/redux/actions/all.ts5
-rw-r--r--frontend/src/redux/actions/game.ts32
-rw-r--r--frontend/src/redux/actions/lobby.ts32
-rw-r--r--frontend/src/redux/actions/user.ts17
-rw-r--r--frontend/src/redux/currentGame.ts46
-rw-r--r--frontend/src/redux/games.ts56
-rw-r--r--frontend/src/redux/user.ts43
-rw-r--r--frontend/src/sagas.ts23
-rw-r--r--frontend/src/sagas/errors.ts36
-rw-r--r--frontend/src/sagas/game.ts81
-rw-r--r--frontend/src/sagas/gameBrowser.ts55
-rw-r--r--frontend/src/sagas/home.ts28
-rw-r--r--frontend/src/sagas/lobby.ts44
-rw-r--r--frontend/src/setupProxy.js8
-rw-r--r--frontend/src/store.ts27
56 files changed, 0 insertions, 2046 deletions
diff --git a/frontend/src/@types/reflexbox.d.ts b/frontend/src/@types/reflexbox.d.ts
deleted file mode 100644
index 802bc5f3..00000000
--- a/frontend/src/@types/reflexbox.d.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-declare module 'reflexbox' {
-
- import { HTMLAttributes } from 'react';
- import * as React from 'react'
-
- export interface BoxProps {
- w?: number | string,
- h?: number | string,
-
- flex?: boolean,
- wrap?: boolean,
- column?: boolean,
- auto?: boolean,
- order?: number,
- align?: "flex-start" | "flex-end" | "center" | "stretch" | "baseline",
- justify?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly",
-
- m?: number | string,
- mx?: number | string,
- my?: number | string,
- mt?: number | string,
- mb?: number | string,
- ml?: number | string,
- mr?: number | string,
-
- p?: number | string,
- px?: number | string,
- py?: number | string,
- pt?: number | string,
- pb?: number | string,
- pl?: number | string,
- pr?: number | string,
- }
-
- export class Flex extends React.Component<HTMLAttributes & BoxProps> { }
- export class Box extends React.Component<HTMLAttributes & BoxProps> { }
-}
diff --git a/frontend/src/api/model.ts b/frontend/src/api/model.ts
deleted file mode 100644
index 2796a6d3..00000000
--- a/frontend/src/api/model.ts
+++ /dev/null
@@ -1,187 +0,0 @@
-export type ApiErrorDetail = {
- message: string
-};
-
-export type ApiError = {
- message: string,
- details: ApiErrorDetail[]
-};
-
-export type ApiPlayer = {
- username: string,
- displayName: string,
- index: number,
- gameOwner: boolean,
- user: boolean,
-};
-
-export type ApiWonderSidePickMethod = "EACH_RANDOM" | "ALL_A" | "ALL_B" | "SAME_RANDOM_FOR_ALL";
-
-export type ApiSettings = {
- randomSeedForTests: number,
- timeLimitInSeconds: number,
- wonderSidePickMethod: ApiWonderSidePickMethod,
- initialGold: number,
- discardedCardGold: number,
- defaultTradingCost: number,
- pointsPer3Gold: number,
- lostPointsPerDefeat: number,
- wonPointsPerVictoryPerAge: Map<number, number>
-};
-
-export type ApiGameState = "LOBBY" | "PLAYING";
-
-export type ApiLobby = {
- id: number,
- name: string,
- owner: string,
- players: ApiPlayer[],
- settings: ApiSettings,
- state: ApiGameState
-};
-
-export type ApiScience = {
- jokers: number,
- nbWheels: number,
- nbCompasses: number,
- nbTablets: number,
-}
-
-export type ApiMilitary = {
- nbShields: number,
- totalPoints: number,
- nbDefeatTokens: number,
-}
-
-export type ApiResourceType = "WOOD" | "STONE" | "ORE" | "CLAY" | "GLASS" | "PAPYRUS" | "LOOM";
-
-export type ApiResources = {
- quantities: Map<ApiResourceType, number>,
-};
-
-export type ApiRequirements = {
- gold: number,
- resources: ApiResources
-}
-
-export type ApiCardBack = {
- image: string,
-};
-
-export type ApiWonderStage = {
- cardBack: ApiCardBack | null,
- isBuilt: boolean,
- requirements: ApiRequirements,
- builtDuringLastMove: boolean,
-}
-
-export type ApiWonderBuildability = {
- buildable: boolean
-}
-
-export type ApiWonder = {
- name: string,
- initialResource: ApiResourceType,
- stages: ApiWonderStage[],
- image: string,
- nbBuiltStages: number,
- buildability: ApiWonderBuildability,
-}
-
-export type Color = 'BLUE' | 'GREEN' | 'RED' | 'BROWN' | 'GREY' | 'PURPLE' | 'YELLOW';
-
-export type ApiProvider = "LEFT_NEIGHBOUR" | "RIGHT_NEIGHBOUR";
-
-export type ApiCountedResource = {
- type: ApiResourceType,
- count: number,
-}
-
-export type ApiProduction = {
- fixedResources: ApiCountedResource[],
- alternativeResources: ApiResourceType[][],
-}
-
-export type ApiBoughtResources = {
- provider: ApiProvider,
- resources: ApiResources,
-};
-
-export type ApiCard = {
- name: string,
- color: Color,
- requirements: ApiRequirements,
- chainParent: String | null,
- chainChildren: String[],
- image: string,
- back: ApiCardBack
-};
-
-export type ApiTableCard = ApiCard & {
- playedDuringLastMove: boolean,
-};
-
-export type ApiBoard = {
- playerIndex: number,
- wonder: ApiWonder,
- production: ApiProduction,
- publicProduction: ApiProduction,
- science: ApiScience,
- military: ApiMilitary,
- playedCards: ApiTableCard[][],
- gold: number,
-};
-
-export type HandRotationDirection = 'LEFT' | 'RIGHT';
-
-export type ApiMoveType = "PLAY" | "PLAY_FREE" | "UPGRADE_WONDER" | "DISCARD" | "COPY_GUILD";
-
-export type ApiPlayedMove = {
- playerIndex: number,
- type: ApiMoveType,
- card: ApiTableCard,
- boughtResources: ApiBoughtResources[],
-};
-
-export type ApiTable = {
- boards: ApiBoard[],
- currentAge: number,
- handRotationDirection: HandRotationDirection,
- lastPlayedMoves: ApiPlayedMove[],
- nbPlayers: number,
-};
-
-export type ApiAction = 'PLAY' | 'PLAY_2' | 'PLAY_LAST' | 'PICK_NEIGHBOR_GUILD' | 'WAIT';
-
-export type ApiPlayability = {
- playable: boolean,
- chainable: boolean,
- minPrice: number,
-};
-
-export type ApiHandCard = ApiCard & {
- playability: ApiPlayability,
-};
-
-export type ApiPreparedCard = {
- player: ApiPlayer,
- cardBack: ApiCardBack,
-};
-
-export type ApiPlayerTurnInfo = {
- playerIndex: number,
- table: ApiTable,
- currentAge: number,
- action: ApiAction,
- hand: ApiHandCard[],
- playedMove: ApiPlayedMove | null,
- neighbourGuildCards: ApiTableCard[],
- message: string,
- wonderBuildability: ApiWonderBuildability,
-};
-
-export type ApiPlayerMove = {
- type: ApiMoveType,
- cardName: string,
- boughtResources: ApiBoughtResources[],
-};
diff --git a/frontend/src/api/sevenWondersApi.ts b/frontend/src/api/sevenWondersApi.ts
deleted file mode 100644
index 4f76a677..00000000
--- a/frontend/src/api/sevenWondersApi.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import {
- ApiError,
- ApiLobby,
- ApiPlayer,
- ApiPlayerMove,
- ApiPlayerTurnInfo,
- ApiPreparedCard,
- ApiSettings,
- ApiTable,
-} from './model';
-import { JsonStompClient, SubscribeFn } from './websocket';
-import { createJsonStompClient } from './websocket';
-
-const WS_URL = '/seven-wonders-websocket';
-
-export class SevenWondersSession {
- client: JsonStompClient;
-
- constructor(client: JsonStompClient) {
- this.client = client;
- }
-
- watchErrors(): SubscribeFn<ApiError> {
- return this.client.subscriber('/user/queue/errors');
- }
-
- watchNameChoice(): SubscribeFn<ApiPlayer> {
- return this.client.subscriber('/user/queue/nameChoice');
- }
-
- chooseName(displayName: string): void {
- this.client.send('/app/chooseName', { playerName: displayName });
- }
-
- watchGames(): SubscribeFn<ApiLobby[]> {
- return this.client.subscriber('/topic/games');
- }
-
- watchLobbyJoined(): SubscribeFn<Object> {
- return this.client.subscriber('/user/queue/lobby/joined');
- }
-
- createGame(gameName: string): void {
- this.client.send('/app/lobby/create', { gameName });
- }
-
- joinGame(gameId: number): void {
- this.client.send('/app/lobby/join', { gameId });
- }
-
- watchLobbyUpdated(currentGameId: number): SubscribeFn<Object> {
- return this.client.subscriber(`/topic/lobby/${currentGameId}/updated`);
- }
-
- watchGameStarted(currentGameId: number): SubscribeFn<Object> {
- return this.client.subscriber(`/topic/lobby/${currentGameId}/started`);
- }
-
- leave(): void {
- this.client.send('/app/lobby/leave');
- }
-
- reorderPlayers(orderedPlayers: Array<string>): void {
- this.client.send('/app/lobby/reorderPlayers', { orderedPlayers });
- }
-
- updateSettings(settings: ApiSettings): void {
- this.client.send('/app/lobby/updateSettings', { settings });
- }
-
- startGame(): void {
- this.client.send('/app/lobby/startGame');
- }
-
- watchPlayerReady(currentGameId: number): SubscribeFn<string> {
- return this.client.subscriber(`/topic/game/${currentGameId}/playerReady`);
- }
-
- watchTableUpdates(currentGameId: number): SubscribeFn<ApiTable> {
- return this.client.subscriber(`/topic/game/${currentGameId}/tableUpdates`);
- }
-
- watchPreparedCards(currentGameId: number): SubscribeFn<ApiPreparedCard> {
- return this.client.subscriber(`/topic/game/${currentGameId}/prepared`);
- }
-
- watchTurnInfo(): SubscribeFn<ApiPlayerTurnInfo> {
- return this.client.subscriber('/user/queue/game/turn');
- }
-
- sayReady(): void {
- this.client.send('/app/game/sayReady');
- }
-
- prepareMove(move: ApiPlayerMove): void {
- this.client.send('/app/game/prepareMove', { move });
- }
-}
-
-export async function connectToGame(): Promise<SevenWondersSession> {
- const jsonStompClient: JsonStompClient = createJsonStompClient(WS_URL);
- await jsonStompClient.connect();
- return new SevenWondersSession(jsonStompClient);
-}
diff --git a/frontend/src/api/websocket.ts b/frontend/src/api/websocket.ts
deleted file mode 100644
index e9393836..00000000
--- a/frontend/src/api/websocket.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import SockJS from 'sockjs-client';
-import { Client, Frame, Message, Options, Subscription } from 'webstomp-client';
-import * as Stomp from 'webstomp-client';
-
-const DEFAULT_DEBUG_OPTIONS = {
- debug: process.env.NODE_ENV !== 'production',
-};
-
-export type Callback<T> = (value: T) => void;
-export type UnsubscribeFn = () => void;
-export type SubscribeFn<T> = (callback: Callback<T>) => UnsubscribeFn;
-
-export class JsonStompClient {
- client: Client;
-
- constructor(client: Client) {
- this.client = client;
- }
-
- connect(headers: Stomp.ConnectionHeaders = {}): Promise<Frame | void> {
- return new Promise((resolve, reject) => {
- this.client.connect(headers, resolve, reject);
- });
- }
-
- subscribe<T>(path: string, callback: Callback<T>): UnsubscribeFn {
- const socketSubscription: Subscription = this.client.subscribe(path, (message: Message) => {
- // not all frames have a JSON body
- const value: T | void = message && JsonStompClient.parseBody(message);
- callback(value || {} as T);
- });
- return () => socketSubscription.unsubscribe();
- }
-
- static parseBody<T>(message: Message): T | void {
- try {
- return message.body ? JSON.parse(message.body) : undefined;
- } catch (jsonParseError) {
- throw new Error('Cannot parse websocket message as JSON: ' + jsonParseError.message);
- }
- }
-
- subscriber<T>(path: string): SubscribeFn<T> {
- return (callback: Callback<T>) => this.subscribe(path, callback);
- }
-
- send(url: string, body?: Object) {
- const strBody = body ? JSON.stringify(body) : '';
- this.client.send(url, strBody);
- }
-}
-
-function createStompClient(url: string, options: Options = {}): Client {
- const optionsWithDebug = Object.assign({}, DEFAULT_DEBUG_OPTIONS, options);
- return Stomp.over(new SockJS(url), optionsWithDebug);
-}
-
-export function createJsonStompClient(url: string, options: Options = {}): JsonStompClient {
- return new JsonStompClient(createStompClient(url, options));
-}
diff --git a/frontend/src/components/Application.tsx b/frontend/src/components/Application.tsx
deleted file mode 100644
index e0ec604d..00000000
--- a/frontend/src/components/Application.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import React from 'react';
-import { Redirect, Route, Switch } from 'react-router-dom';
-import { GameBrowser } from './game-browser/GameBrowser';
-import { GameScene } from './game/GameScene';
-import { Lobby } from './lobby/Lobby';
-import { Home } from './home/Home';
-
-export const Application = () => (
- <Switch>
- <Route path="/game" component={GameScene} />
- <Route path="/games" component={GameBrowser} />
- <Route path="/lobby" component={Lobby} />
- <Route path="/" component={Home} />
- <Redirect to="/" />
- </Switch>
-);
diff --git a/frontend/src/components/game-browser/GameBrowser.tsx b/frontend/src/components/game-browser/GameBrowser.tsx
deleted file mode 100644
index a6367d5e..00000000
--- a/frontend/src/components/game-browser/GameBrowser.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Button, Classes, InputGroup, Intent } from '@blueprintjs/core';
-import React, { ChangeEvent, Component, SyntheticEvent } from 'react';
-import { connect } from 'react-redux';
-import { Flex } from 'reflexbox';
-import { actions } from '../../redux/actions/lobby';
-import { GameList } from './GameList';
-import { PlayerInfo } from './PlayerInfo';
-
-type GameBrowserProps = {
- createGame: (gameName: string) => void,
-}
-
-class GameBrowserPresenter extends Component<GameBrowserProps> {
-
- _gameName: string | void = undefined;
-
- createGame = (e: SyntheticEvent<any>): void => {
- e.preventDefault();
- if (this._gameName !== undefined) {
- this.props.createGame(this._gameName);
- }
- };
-
- render() {
- return (
- <div>
- <Flex align="center" justify='space-between' p={1}>
- <form onSubmit={this.createGame}>
- <InputGroup
- placeholder="Game name"
- name="game_name"
- onChange={(e: ChangeEvent<HTMLInputElement>) => (this._gameName = e.target.value)}
- rightElement={<CreateGameButton createGame={this.createGame}/>}
- />
- </form>
- <PlayerInfo />
- </Flex>
- <GameList />
- </div>
- );
- }
-}
-
-type CreateGameButtonProps = {
- createGame: (e: SyntheticEvent<any>) => void
-}
-
-const CreateGameButton = ({createGame}: CreateGameButtonProps) => (
- <Button className={Classes.MINIMAL} intent={Intent.PRIMARY} icon='add' onClick={createGame} />
-);
-
-const mapDispatchToProps = {
- createGame: actions.requestCreateGame,
-};
-
-export const GameBrowser = connect(null, mapDispatchToProps)(GameBrowserPresenter);
diff --git a/frontend/src/components/game-browser/GameList.css b/frontend/src/components/game-browser/GameList.css
deleted file mode 100644
index a04e126c..00000000
--- a/frontend/src/components/game-browser/GameList.css
+++ /dev/null
@@ -1,3 +0,0 @@
-tr.gameListRow td {
- vertical-align: middle;
-}
diff --git a/frontend/src/components/game-browser/GameList.tsx b/frontend/src/components/game-browser/GameList.tsx
deleted file mode 100644
index 1b136940..00000000
--- a/frontend/src/components/game-browser/GameList.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-import { Button, Classes } from '@blueprintjs/core'
-import { List } from 'immutable';
-import React from 'react';
-import { connect } from 'react-redux';
-import { ApiLobby } from '../../api/model';
-import { GlobalState } from '../../reducers';
-import { actions } from '../../redux/actions/lobby';
-import { getAllGames } from '../../redux/games';
-import './GameList.css';
-import { GameStatus } from './GameStatus';
-import { PlayerCount } from './PlayerCount';
-
-type GameListStateProps = {
- games: List<ApiLobby>,
-};
-
-type GameListDispatchProps = {
- joinGame: (gameId: number) => void,
-};
-
-type GameListProps = GameListStateProps & GameListDispatchProps
-
-const GameListPresenter = ({ games, joinGame }: GameListProps) => (
- <table className={Classes.HTML_TABLE}>
- <thead>
- <GameListHeaderRow />
- </thead>
- <tbody>
- {games.map((game: ApiLobby) => <GameListItemRow key={game.id} game={game} joinGame={joinGame}/>)}
- </tbody>
- </table>
-);
-
-const GameListHeaderRow = () => (
- <tr>
- <th>Name</th>
- <th>Status</th>
- <th>Nb Players</th>
- <th>Join</th>
- </tr>
-);
-
-type GameListItemRowProps = {
- game: ApiLobby,
- joinGame: (gameId: number) => void,
-};
-
-const GameListItemRow = ({game, joinGame}: GameListItemRowProps) => (
- <tr className="gameListRow">
- <td>{game.name}</td>
- <td>
- <GameStatus state={game.state} />
- </td>
- <td>
- <PlayerCount nbPlayers={game.players.length} />
- </td>
- <td>
- <JoinButton game={game} joinGame={joinGame}/>
- </td>
- </tr>
-);
-
-type JoinButtonProps = {
- game: ApiLobby,
- joinGame: (gameId: number) => void,
-};
-
-const JoinButton = ({game, joinGame}: JoinButtonProps) => {
- const disabled = game.state !== 'LOBBY';
- const onClick = () => joinGame(game.id);
- return <Button minimal disabled={disabled} icon='arrow-right' title='Join Game' onClick={onClick}/>;
-};
-
-function mapStateToProps(state: GlobalState): GameListStateProps {
- return {
- games: getAllGames(state),
- };
-}
-
-const mapDispatchToProps: GameListDispatchProps = {
- joinGame: actions.requestJoinGame,
-};
-
-export const GameList = connect(mapStateToProps, mapDispatchToProps)(GameListPresenter);
-
diff --git a/frontend/src/components/game-browser/GameStatus.tsx b/frontend/src/components/game-browser/GameStatus.tsx
deleted file mode 100644
index 5f237258..00000000
--- a/frontend/src/components/game-browser/GameStatus.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Tag } from '@blueprintjs/core';
-import { Intent } from '@blueprintjs/core';
-import * as React from 'react';
-import { ApiGameState } from '../../api/model';
-
-type GameStatusProps = {
- state: ApiGameState,
-}
-
-export const GameStatus = ({state}: GameStatusProps) => (
- <Tag minimal intent={statusIntents[state]}>{state}</Tag>
-);
-
-const statusIntents = {
- 'LOBBY': Intent.SUCCESS,
- 'PLAYING': Intent.WARNING,
-};
diff --git a/frontend/src/components/game-browser/PlayerCount.css b/frontend/src/components/game-browser/PlayerCount.css
deleted file mode 100644
index d2f18e50..00000000
--- a/frontend/src/components/game-browser/PlayerCount.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.playerCountIcon, .playerCount {
- vertical-align: middle;
-}
diff --git a/frontend/src/components/game-browser/PlayerCount.tsx b/frontend/src/components/game-browser/PlayerCount.tsx
deleted file mode 100644
index 64028f68..00000000
--- a/frontend/src/components/game-browser/PlayerCount.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Icon } from '@blueprintjs/core';
-import * as React from 'react';
-import './PlayerCount.css';
-
-type PlayerCountProps = {
- nbPlayers: number,
-}
-
-export const PlayerCount = ({nbPlayers}: PlayerCountProps) => <div title='Number of players'>
- <Icon className="playerCountIcon" icon="people" title={false} />
- <span className="playerCount"> {nbPlayers}</span>
-</div>;
diff --git a/frontend/src/components/game-browser/PlayerInfo.tsx b/frontend/src/components/game-browser/PlayerInfo.tsx
deleted file mode 100644
index 4afed671..00000000
--- a/frontend/src/components/game-browser/PlayerInfo.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Text } from '@blueprintjs/core';
-import React from 'react';
-import { connect } from 'react-redux';
-import { GlobalState } from '../../reducers';
-import { User } from '../../redux/user';
-import { getCurrentUser } from '../../redux/user';
-
-type PlayerInfoProps = {
- user: User | null,
-}
-
-const PlayerInfoPresenter = ({user}: PlayerInfoProps) => (
- <Text>
- <b>Username:</b>
- {' '}
- {user && user.displayName}
- </Text>
-);
-
-const mapStateToProps = (state: GlobalState): PlayerInfoProps => ({
- user: getCurrentUser(state),
-});
-
-const mapDispatchToProps = {
-};
-
-export const PlayerInfo = connect(mapStateToProps, mapDispatchToProps)(PlayerInfoPresenter);
diff --git a/frontend/src/components/game/Board.css b/frontend/src/components/game/Board.css
deleted file mode 100644
index 0600bd14..00000000
--- a/frontend/src/components/game/Board.css
+++ /dev/null
@@ -1,38 +0,0 @@
-.board {
- width: 100vw
-}
-
-.cards {
- display: flex;
- height: 40vh;
- width: 100vw;
-}
-
-.card-column {
- height: 40vh;
- margin: auto;
- position: relative;
- width: 15vw;
-}
-
-.card {
- position: absolute;
- /* dynamic positioning in JS */
-}
-
-.table-card-img {
- max-width: 10vw;
- max-height: 25vh;
-}
-
-.wonder {
- width: 100vw;
- text-align: center;
-}
-
-.wonder-img {
- border-radius: 0.5%/1.5%;
- box-shadow: 0.2rem 0.2rem 0.5rem black;
- max-height: 30vh;
- max-width: 95vw;
-}
diff --git a/frontend/src/components/game/Board.tsx b/frontend/src/components/game/Board.tsx
deleted file mode 100644
index 98298a1f..00000000
--- a/frontend/src/components/game/Board.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import React from 'react';
-import { ApiBoard, ApiTableCard, ApiWonder } from '../../api/model';
-import './Board.css'
-import { CardImage } from './CardImage';
-
-// card offsets in % of their size when displayed in columns
-const xOffset = 20;
-const yOffset = 21;
-
-type BoardProps = {
- board: ApiBoard,
-}
-
-export const Board = ({board}: BoardProps) => {
- return <div className='board'>
- <TableCards cardColumns={board.playedCards}/>
- <Wonder wonder={board.wonder}/>
- </div>;
-};
-
-type TableCardsProps = {
- cardColumns: ApiTableCard[][],
-}
-
-const TableCards = ({cardColumns}: TableCardsProps) => {
- return <div className="cards">
- {cardColumns.map(column => <TableCardColumn key={column[0].color} cards={column}/>)}
- </div>
-};
-
-type TableCardColumnProps = {
- cards: ApiTableCard[]
-}
-
-const TableCardColumn = ({cards}: TableCardColumnProps) => {
- return <div className="card-column">
- {cards.map((c, i) => <TableCard key={c.name} card={c} indexInColumn={i}/>)}
- </div>
-};
-
-type TableCardProps = {
- card: ApiTableCard,
- indexInColumn: number,
-}
-
-const TableCard = ({card, indexInColumn}: TableCardProps) => {
- let style = {
- transform: `translate(${indexInColumn * xOffset}%, ${indexInColumn * yOffset}%)`,
- zIndex: indexInColumn,
- };
- return <div className="card" style={style}>
- <CardImage card={card} otherClasses="table-card-img"/>
- </div>
-};
-
-type WonderProps = {
- wonder: ApiWonder,
-}
-
-const Wonder = ({wonder}: WonderProps) => {
- return <div className="wonder">
- <img src={`/images/wonders/${wonder.image}`}
- title={wonder.name}
- alt={`Wonder ${wonder.name}`}
- className="wonder-img"/>
- </div>
-};
diff --git a/frontend/src/components/game/CardImage.css b/frontend/src/components/game/CardImage.css
deleted file mode 100644
index 795c1503..00000000
--- a/frontend/src/components/game/CardImage.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.card-img {
- border-radius: 5%;
- box-shadow: 2px 2px 5px black;
-}
diff --git a/frontend/src/components/game/CardImage.tsx b/frontend/src/components/game/CardImage.tsx
deleted file mode 100644
index a37595ad..00000000
--- a/frontend/src/components/game/CardImage.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import React from 'react';
-import { ApiCard } from '../../api/model';
-import './CardImage.css'
-
-type CardImageProps = {
- card: ApiCard,
- otherClasses: string,
- highlightColor?: string
-}
-
-export const CardImage = ({card, otherClasses, highlightColor}: CardImageProps) => {
- const style = highlightStyle(highlightColor);
- return <img src={`/images/cards/${card.image}`}
- title={card.name}
- alt={'Card ' + card.name}
- className={`card-img ${otherClasses}`}
- style={style}/>
-};
-
-function highlightStyle(highlightColor?: string) {
- if (highlightColor) {
- return { boxShadow: `0 0 1rem 0.1rem ${highlightColor}` };
- } else {
- return {};
- }
-}
diff --git a/frontend/src/components/game/GameScene.css b/frontend/src/components/game/GameScene.css
deleted file mode 100644
index 3417459b..00000000
--- a/frontend/src/components/game/GameScene.css
+++ /dev/null
@@ -1,13 +0,0 @@
-.gameSceneRoot {
- background: url('background-papyrus.jpg') center no-repeat;
- background-size: cover;
-}
-
-.fullscreen {
- position: fixed;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- overflow: hidden;
-}
diff --git a/frontend/src/components/game/GameScene.tsx b/frontend/src/components/game/GameScene.tsx
deleted file mode 100644
index 465d0840..00000000
--- a/frontend/src/components/game/GameScene.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import { Button, Classes, Intent, NonIdealState } from '@blueprintjs/core';
-import { List } from 'immutable';
-import React, { Component } from 'react';
-import { connect } from 'react-redux';
-import { ApiPlayer, ApiPlayerMove, ApiPlayerTurnInfo } from '../../api/model';
-import { GlobalState } from '../../reducers';
-import { actions } from '../../redux/actions/game';
-import { getCurrentTurnInfo } from '../../redux/currentGame';
-import { getCurrentGame } from '../../redux/games';
-import { Board } from './Board';
-import './GameScene.css'
-import { Hand } from './Hand';
-import { ProductionBar } from './ProductionBar';
-
-type GameSceneStateProps = {
- players: List<ApiPlayer>,
- turnInfo: ApiPlayerTurnInfo | null,
-}
-
-type GameSceneDispatchProps = {
- sayReady: () => void,
- prepareMove: (move: ApiPlayerMove) => void,
-}
-
-type GameSceneProps = GameSceneStateProps & GameSceneDispatchProps
-
-class GameScenePresenter extends Component<GameSceneProps> {
-
- render() {
- return (
- <div className='gameSceneRoot fullscreen'>
- {!this.props.turnInfo && <GamePreStart onReadyClicked={this.props.sayReady}/>}
- {this.props.turnInfo && this.turnInfoScene(this.props.turnInfo)}
- </div>
- );
- }
-
- turnInfoScene(turnInfo: ApiPlayerTurnInfo) {
- let board = turnInfo.table.boards[turnInfo.playerIndex];
- return <div>
- <p>{turnInfo.message}</p>
- <Board board={board}/>
- <Hand cards={turnInfo.hand}
- wonderUpgradable={turnInfo.wonderBuildability.buildable}
- prepareMove={this.props.prepareMove}/>
- <ProductionBar gold={board.gold} production={board.production}/>
- </div>
- }
-}
-
-type GamePreStartProps = {
- onReadyClicked: () => void
-}
-const GamePreStart = ({onReadyClicked}: GamePreStartProps) => <NonIdealState
- description={<p>Click "ready" when you are</p>}
- action={<Button text="READY" className={Classes.LARGE} intent={Intent.PRIMARY} icon='play'
- onClick={() => onReadyClicked()}/>}
-/>;
-
-function mapStateToProps(state: GlobalState): GameSceneStateProps {
- const game = getCurrentGame(state);
- console.info(game);
-
- return {
- players: game ? List(game.players) : List(),
- turnInfo: getCurrentTurnInfo(state),
- };
-}
-
-function mapDispatchToProps(): GameSceneDispatchProps {
- return {
- sayReady: actions.sayReady,
- prepareMove: actions.prepareMove,
- }
-}
-
-export const GameScene = connect(mapStateToProps, mapDispatchToProps)(GameScenePresenter);
diff --git a/frontend/src/components/game/Hand.css b/frontend/src/components/game/Hand.css
deleted file mode 100644
index 8e7d93c5..00000000
--- a/frontend/src/components/game/Hand.css
+++ /dev/null
@@ -1,50 +0,0 @@
-.hand {
- align-items: center;
- bottom: 0;
- display: flex;
- height: 345px; /* can hold enhanced cards */
- left: 50%;
- max-height: 25vw;
- position: absolute;
- transform: translate(-50%, 55%);
- transition: 0.5s;
- z-index: 30;
-}
-.hand:hover {
- bottom: 4rem;
- transform: translate(-50%, 0%);
-}
-
-.hand-card {
- align-items: flex-end;
- display: grid;
- margin: 0.2rem;
-}
-
-.hand-card .hand-card-img {
- grid-row: 1;
- grid-column: 1;
- max-width: 13vw;
- max-height: 60vh;
- transition: 0.1s;
- width: 11rem;
-}
-.hand-card.unplayable .hand-card-img {
- filter: grayscale(50%) contrast(50%);
-}
-.hand-card:hover .hand-card-img {
- box-shadow: 0 10px 40px black;
- width: 14rem;
- max-width: 15vw;
- max-height: 90vh;
-}
-
-.hand-card .action-buttons {
- align-items: flex-end;
- display: none;
- grid-row: 1;
- grid-column: 1;
-}
-.hand-card:hover .action-buttons {
- display: flex;
-}
diff --git a/frontend/src/components/game/Hand.tsx b/frontend/src/components/game/Hand.tsx
deleted file mode 100644
index 744c45cc..00000000
--- a/frontend/src/components/game/Hand.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import { Button, ButtonGroup, Classes, Intent } from '@blueprintjs/core';
-import React from 'react';
-import { ApiHandCard, ApiPlayerMove } from '../../api/model';
-import './Hand.css'
-import { CardImage } from './CardImage';
-
-type HandProps = {
- cards: ApiHandCard[],
- wonderUpgradable: boolean,
- prepareMove: (move: ApiPlayerMove) => void
-}
-
-export const Hand = ({cards, wonderUpgradable, prepareMove}: HandProps) => {
- return <div className='hand'>{cards.map((c, i) => <HandCard key={i} card={c}
- wonderUpgradable={wonderUpgradable}
- prepareMove={prepareMove}/>)}</div>;
-};
-
-type HandCardProps = {
- card: ApiHandCard,
- wonderUpgradable: boolean,
- prepareMove: (move: ApiPlayerMove) => void
-}
-
-const HandCard = ({card, wonderUpgradable, prepareMove}: HandCardProps) => {
- let playableClass = card.playability.playable ? '' : 'unplayable';
- return <div className={`hand-card ${playableClass}`}>
- <CardImage card={card} otherClasses="hand-card-img"/>
- <ActionButtons card={card} wonderUpgradable={wonderUpgradable} prepareMove={prepareMove} />
- </div>
-};
-
-type ActionButtonsProps = HandCardProps
-
-const ActionButtons = ({card, wonderUpgradable, prepareMove}: ActionButtonsProps) => <ButtonGroup className="action-buttons">
- <Button title="PLAY" className={Classes.LARGE} intent={Intent.SUCCESS} icon='play'
- disabled={!card.playability.playable}
- onClick={() => prepareMove({type: 'PLAY', cardName: card.name, boughtResources: []})}/>
- <Button title="BUILD WONDER" className={Classes.LARGE} intent={Intent.PRIMARY} icon='key-shift'
- disabled={!wonderUpgradable}
- onClick={() => prepareMove({type: 'UPGRADE_WONDER', cardName: card.name, boughtResources: []})}/>
- <Button title="DISCARD" className={Classes.LARGE} intent={Intent.DANGER} icon='cross'
- onClick={() => prepareMove({type: 'DISCARD', cardName: card.name, boughtResources: []})}/>
-</ButtonGroup>;
diff --git a/frontend/src/components/game/ProductionBar.css b/frontend/src/components/game/ProductionBar.css
deleted file mode 100644
index 77a3b8fc..00000000
--- a/frontend/src/components/game/ProductionBar.css
+++ /dev/null
@@ -1,50 +0,0 @@
-.production-bar {
- align-items: center;
- background: lightgray;
- bottom: 0;
- border-top: 1px #8b8b8b solid;
- background: linear-gradient(#eaeaea, #888 7%);
- box-shadow: 0 0 15px 0 #747474;
- display: flex;
- height: 3.5rem;
- position: fixed;
- width: 100vw;
- z-index: 99;
-}
-
-.fixed-resources {
- margin: auto;
- display: flex;
-}
-.alternative-resources {
- margin: auto;
- display: flex;
-}
-
-.resource-with-count {
- margin-left: 1rem
-}
-.resource-choice {
- margin-left: 1.5rem;
-}
-
-.choice-separator {
- font-size: 2rem;
- vertical-align: middle;
- margin: 5px;
- color: #c29929;
- text-shadow: 0 0 1px black;
-}
-
-.token-img {
- height: 3rem;
- vertical-align: middle;
- width: 3rem;
-}
-
-.token-count {
- font-family: fantasy;
- font-size: 1.5rem;
- margin-left: 0.2rem;
- vertical-align: middle;
-}
diff --git a/frontend/src/components/game/ProductionBar.tsx b/frontend/src/components/game/ProductionBar.tsx
deleted file mode 100644
index 3e5c6d34..00000000
--- a/frontend/src/components/game/ProductionBar.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import React from 'react';
-import { ApiCountedResource, ApiProduction, ApiResourceType } from '../../api/model';
-import './ProductionBar.css'
-
-type ProductionBarProps = {
- gold: number,
- production: ApiProduction,
-}
-
-export const ProductionBar = ({gold, production}: ProductionBarProps) => {
- return <div className='production-bar'>
- <GoldIndicator amount={gold}/>
- <FixedResources resources={production.fixedResources}/>
- <AlternativeResources resources={production.alternativeResources}/>
- </div>;
-};
-
-type GoldIndicatorProps = {
- amount: number,
-}
-const GoldIndicator = ({amount}: GoldIndicatorProps) => {
- return <TokenWithCount tokenName="coin" count={amount} otherClasses="gold-indicator"/>
-};
-
-type FixedResourcesProps = {
- resources: ApiCountedResource[],
-}
-const FixedResources = ({resources}: FixedResourcesProps) => {
- return <div className="fixed-resources">
- {resources.map(r => <TokenWithCount key={r.type}
- tokenName={getTokenName(r.type)}
- count={r.count}
- otherClasses="resource-with-count"/>)}
- </div>
-};
-
-type AlternativeResourcesProps = {
- resources: ApiResourceType[][],
-}
-const AlternativeResources = ({resources}: AlternativeResourcesProps) => {
- return <div className="alternative-resources">
- {resources.map((types, i) => <ResourceChoice key={i} types={types}/>)}
- </div>
-};
-
-type ResourceChoiceProps = {
- types: ApiResourceType[],
-}
-const ResourceChoice = ({types}: ResourceChoiceProps) => {
- let typeImages = types.map(type => <TokenImage key={type} tokenName={getTokenName(type)}/>);
- let separator = <span className="choice-separator">∕</span>;
- return <div className="resource-choice">
- {intersperce(typeImages, separator)}
- </div>
-};
-
-function intersperce<T>(array: T[], separator: T): T[] {
- let result = array.reduce((acc: T[], elt: T) => acc.concat(elt, separator), []);
- return result.slice(0, -1); // remove extra separator at the end
-}
-
-type TokenWithCountProps = {
- tokenName: string,
- count: number,
- otherClasses?: string,
-}
-const TokenWithCount = ({tokenName, count, otherClasses = ""}: TokenWithCountProps) => {
- return <div className={`token-with-count ${otherClasses}`}>
- <TokenImage tokenName={tokenName}/>
- <span className="token-count">× {count}</span>
- </div>
-};
-
-type TokenImageProps = {
- tokenName: string,
-}
-const TokenImage = ({tokenName}: TokenImageProps) => {
- return <img src={getTokenImagePath(tokenName)} title={tokenName} alt={tokenName} className="token-img"/>
-};
-
-function getTokenImagePath(tokenName: string): string {
- return `/images/tokens/${tokenName}.png`;
-}
-
-function getTokenName(resourceType: ApiResourceType): string {
- return `resources/${resourceType.toLowerCase()}`;
-}
diff --git a/frontend/src/components/game/background-papyrus.jpg b/frontend/src/components/game/background-papyrus.jpg
deleted file mode 100644
index 57bdffcf..00000000
--- a/frontend/src/components/game/background-papyrus.jpg
+++ /dev/null
Binary files differ
diff --git a/frontend/src/components/home/ChooseNameForm.tsx b/frontend/src/components/home/ChooseNameForm.tsx
deleted file mode 100644
index 8292150b..00000000
--- a/frontend/src/components/home/ChooseNameForm.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { Button, Classes, InputGroup, Intent } from '@blueprintjs/core';
-import React, { ChangeEvent, Component, SyntheticEvent } from 'react';
-import { connect } from 'react-redux';
-import { actions } from '../../redux/actions/user';
-
-type ChooseNameFormPresenterProps = {
- chooseUsername: (username: string) => void,
-}
-
-class ChooseNameFormPresenter extends Component<ChooseNameFormPresenterProps> {
- _username = '';
-
- play = (e: SyntheticEvent<any>) => {
- e.preventDefault();
- if (this._username !== undefined) {
- this.props.chooseUsername(this._username);
- }
- };
-
- render() {
- return (
- <form onSubmit={this.play}>
- <InputGroup
- className={Classes.LARGE}
- placeholder="Username"
- onChange={(e: ChangeEvent<HTMLInputElement>) => (this._username = e.target.value)}
- rightElement={this.renderSubmit()}
- />
- </form>
- );
- }
-
- renderSubmit = () => (
- <Button className={Classes.MINIMAL} onClick={this.play} intent={Intent.PRIMARY} icon="arrow-right" />
- );
-}
-
-const mapDispatchToProps = {
- chooseUsername: actions.chooseUsername,
-};
-
-export const ChooseNameForm = connect(null, mapDispatchToProps)(ChooseNameFormPresenter);
diff --git a/frontend/src/components/home/Home.css b/frontend/src/components/home/Home.css
deleted file mode 100644
index 7d9a96de..00000000
--- a/frontend/src/components/home/Home.css
+++ /dev/null
@@ -1,13 +0,0 @@
-.homeRoot {
- background: url('background-zeus-temple.jpg') center no-repeat;
- background-size: cover;
-}
-
-.fullscreen {
- position: fixed;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- overflow: hidden;
-}
diff --git a/frontend/src/components/home/Home.tsx b/frontend/src/components/home/Home.tsx
deleted file mode 100644
index 094db658..00000000
--- a/frontend/src/components/home/Home.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import * as React from 'react';
-import { Flex } from 'reflexbox';
-import { ChooseNameForm } from './ChooseNameForm';
-import './Home.css'
-import logo from './logo-7-wonders.png';
-
-export const Home = () => (
- <Flex className='homeRoot fullscreen' column align='center' justify='center'>
- <img src={logo} alt="Seven Wonders"/>
- <ChooseNameForm/>
- </Flex>
-);
diff --git a/frontend/src/components/home/background-zeus-temple.jpg b/frontend/src/components/home/background-zeus-temple.jpg
deleted file mode 100644
index 5a28e933..00000000
--- a/frontend/src/components/home/background-zeus-temple.jpg
+++ /dev/null
Binary files differ
diff --git a/frontend/src/components/home/logo-7-wonders.png b/frontend/src/components/home/logo-7-wonders.png
deleted file mode 100644
index 96974d3e..00000000
--- a/frontend/src/components/home/logo-7-wonders.png
+++ /dev/null
Binary files differ
diff --git a/frontend/src/components/lobby/Lobby.tsx b/frontend/src/components/lobby/Lobby.tsx
deleted file mode 100644
index 3594af65..00000000
--- a/frontend/src/components/lobby/Lobby.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Button, Classes, Intent } from '@blueprintjs/core';
-import { List } from 'immutable';
-import React, { Component } from 'react';
-import { connect } from 'react-redux';
-import { ApiLobby, ApiPlayer } from '../../api/model';
-import { GlobalState } from '../../reducers';
-import { actions } from '../../redux/actions/lobby';
-import { getCurrentGame } from '../../redux/games';
-import { getCurrentPlayer } from '../../redux/user';
-import { RadialPlayerList } from './RadialPlayerList';
-
-export type LobbyStateProps = {
- currentGame: ApiLobby | null,
- currentPlayer: ApiPlayer | null,
- players: List<ApiPlayer>,
-}
-
-export type LobbyDispatchProps = {
- startGame: () => void,
-}
-
-export type LobbyProps = LobbyStateProps & LobbyDispatchProps
-
-class LobbyPresenter extends Component<LobbyProps> {
-
- render() {
- const {currentGame, currentPlayer, players, startGame} = this.props;
- if (!currentGame || !currentPlayer) {
- return <div>Error: no current game.</div>
- }
- return (
- <div>
- <h2>{currentGame.name + ' — Lobby'}</h2>
- <RadialPlayerList players={players}/>
- {currentPlayer.gameOwner && <Button text="START" className={Classes.LARGE} intent={Intent.PRIMARY} icon='play'
- onClick={startGame} disabled={players.size < 3}/>}
- </div>
- );
- }
-}
-
-function mapStateToProps(state: GlobalState): LobbyStateProps {
- const game = getCurrentGame(state);
- console.info(game);
- return {
- currentGame: game,
- currentPlayer: getCurrentPlayer(state),
- players: game ? List(game.players) : List(),
- };
-}
-
-const mapDispatchToProps = {
- startGame: actions.requestStartGame,
-};
-
-export const Lobby = connect(mapStateToProps, mapDispatchToProps)(LobbyPresenter);
diff --git a/frontend/src/components/lobby/PlayerList.tsx b/frontend/src/components/lobby/PlayerList.tsx
deleted file mode 100644
index bfc3a56c..00000000
--- a/frontend/src/components/lobby/PlayerList.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Classes, Icon } from '@blueprintjs/core'
-import { List } from 'immutable';
-import * as React from 'react';
-import { Flex } from 'reflexbox';
-import { ApiPlayer } from '../../api/model';
-
-type PlayerListItemProps = {
- player: ApiPlayer,
- isOwner: boolean,
- isUser: boolean,
-};
-
-const PlayerListItem = ({player, isOwner, isUser}: PlayerListItemProps) => (
- <tr>
- <td>
- <Flex align='center'>
- {isOwner && <Icon icon='badge' title='Game owner'/>}
- {isUser && <Icon icon='user' title='This is you'/>}
- </Flex>
- </td>
- <td>{player.displayName}</td>
- <td>{player.username}</td>
- </tr>
-);
-
-type PlayerListProps = {
- players: List<ApiPlayer>,
- owner: string,
- currentPlayer: ApiPlayer,
-};
-
-export const PlayerList = ({players, owner, currentPlayer}: PlayerListProps) => (
- <table className={Classes.HTML_TABLE}>
- <tbody>
- {players.map((player: ApiPlayer) => <PlayerListItem key={player.username}
- player={player}
- isOwner={player.username === owner}
- isUser={player.username === currentPlayer.username}/>)}
- </tbody>
- </table>
-);
diff --git a/frontend/src/components/lobby/RadialPlayerList.tsx b/frontend/src/components/lobby/RadialPlayerList.tsx
deleted file mode 100644
index 88db55fc..00000000
--- a/frontend/src/components/lobby/RadialPlayerList.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import { Icon, IconName, Intent } from '@blueprintjs/core';
-import { List } from 'immutable';
-import * as React from 'react';
-import { ReactNode } from 'react';
-import { Flex } from 'reflexbox';
-import { ApiPlayer } from '../../api/model';
-import { RadialList } from './radial-list/RadialList';
-import roundTable from './round-table.png';
-
-type PlayerItemProps = {
- player: ApiPlayer
-};
-
-const PlayerItem = ({player}: PlayerItemProps) => (
- <Flex column align='center'>
- <UserIcon isOwner={player.gameOwner} isUser={player.user} title={player.gameOwner ? 'Game owner' : null}/>
- <h5 style={{margin: 0}}>{player.displayName}</h5>
- </Flex>
-);
-
-const PlayerPlaceholder = () => (
- <Flex column align='center' style={{opacity: 0.3}}>
- <UserIcon isOwner={false} isUser={false} title='Waiting for player...'/>
- <h5 style={{margin: 0}}>?</h5>
- </Flex>
-);
-
-type UserIconProps = {
- isUser: boolean,
- isOwner: boolean,
- title: string | null,
-};
-
-const UserIcon = ({isUser, isOwner, title}: UserIconProps) => {
- const icon: IconName = isOwner ? 'badge' : 'user';
- const intent: Intent = isUser ? Intent.WARNING : Intent.NONE;
- return <Icon icon={icon} iconSize={50} intent={intent} title={title}/>;
-};
-
-type RadialPlayerListProps = {
- players: List<ApiPlayer>
-};
-
-export const RadialPlayerList = ({players}: RadialPlayerListProps) => {
- const orderedPlayers = placeUserFirst(players.toArray());
- const playerItems = orderedPlayers.map(player => <PlayerItem key={player.username} player={player}/>);
- const tableImg = <img src={roundTable} alt='Round table' style={{width: 200, height: 200}}/>;
- return <RadialList items={completeWithPlaceholders(playerItems)}
- centerElement={tableImg}
- radius={175}
- offsetDegrees={180}
- itemWidth={120}
- itemHeight={100}/>;
-};
-
-function placeUserFirst(players: ApiPlayer[]): ApiPlayer[] {
- while (!players[0].user) {
- players.push(players.shift()!);
- }
- return players;
-}
-
-function completeWithPlaceholders(playerItems: Array<ReactNode>): Array<ReactNode> {
- while (playerItems.length < 3) {
- playerItems.push(<PlayerPlaceholder/>);
- }
- return playerItems;
-}
-
diff --git a/frontend/src/components/lobby/radial-list/RadialList.css b/frontend/src/components/lobby/radial-list/RadialList.css
deleted file mode 100644
index 3b0f3a79..00000000
--- a/frontend/src/components/lobby/radial-list/RadialList.css
+++ /dev/null
@@ -1,23 +0,0 @@
-.radial-list-container {
- margin: 0;
- padding: 0;
- position: relative;
-}
-
-.radial-list {
- margin: 0;
- padding: 0;
- transition: all 500ms ease-in-out;
- z-index: 1;
-}
-
-.radial-list-center {
- z-index: 0;
-}
-
-.absolute-center {
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
-}
diff --git a/frontend/src/components/lobby/radial-list/RadialList.tsx b/frontend/src/components/lobby/radial-list/RadialList.tsx
deleted file mode 100644
index 806cdd08..00000000
--- a/frontend/src/components/lobby/radial-list/RadialList.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import React, { ReactNode } from 'react';
-import { CartesianCoords, RadialConfig } from './radial-math';
-import { offsetsFromCenter, CLOCKWISE, COUNTERCLOCKWISE } from './radial-math';
-import './RadialList.css';
-import { RadialListItem } from './RadialListItem';
-
-type RadialListProps = {
- items: Array<ReactNode>,
- centerElement?: ReactNode,
- radius?: number, // 120px by default
- offsetDegrees?: number, // defaults to 0 = 12 o'clock
- arc?: number, // defaults to 360 (full circle)
- clockwise?: boolean, // defaults to true
- itemWidth?: number,
- itemHeight?: number,
-};
-
-export const RadialList = ({items, centerElement, radius = 120, offsetDegrees = 0, arc = 360, clockwise = true, itemWidth = 20, itemHeight = 20}: RadialListProps) => {
- const diameter = radius * 2;
- const containerStyle = {
- width: diameter + itemWidth,
- height: diameter + itemHeight,
- };
- const direction = clockwise ? CLOCKWISE : COUNTERCLOCKWISE;
- const radialConfig: RadialConfig = {radius, arc, offsetDegrees, direction};
-
- return <div className='radial-list-container' style={containerStyle}>
- <RadialListItems items={items} radialConfig={radialConfig}/>
- <RadialListCenter centerElement={centerElement}/>
- </div>;
-};
-
-type RadialListItemsProps = {
- items: Array<React.ReactNode>,
- radialConfig: RadialConfig,
-};
-
-const RadialListItems = ({items, radialConfig}: RadialListItemsProps) => {
- const diameter = radialConfig.radius * 2;
- const ulStyle = {
- width: diameter,
- height: diameter,
- };
- const itemOffsets: Array<CartesianCoords> = offsetsFromCenter(items.length, radialConfig);
-
- return <ul className='radial-list absolute-center' style={ulStyle}>
- {items.map((item, i) => (<RadialListItem
- key={i}
- item={item}
- offsets={itemOffsets[i]}
- />))}
- </ul>;
-};
-
-type RadialListCenterProps = {
- centerElement?: ReactNode,
-};
-
-const RadialListCenter = ({centerElement}: RadialListCenterProps) => {
- if (!centerElement) {
- return null;
- }
- return <div className='radial-list-center absolute-center'>{centerElement}</div>;
-};
diff --git a/frontend/src/components/lobby/radial-list/RadialListItem.css b/frontend/src/components/lobby/radial-list/RadialListItem.css
deleted file mode 100644
index 65bb9661..00000000
--- a/frontend/src/components/lobby/radial-list/RadialListItem.css
+++ /dev/null
@@ -1,11 +0,0 @@
-.radial-list-item {
- display: block;
- position: absolute;
- top: 50%;
- left: 50%;
- margin: 0;
- padding: 0;
- list-style: unset;
- transition: all 500ms ease-in-out;
- z-index: 1;
-}
diff --git a/frontend/src/components/lobby/radial-list/RadialListItem.tsx b/frontend/src/components/lobby/radial-list/RadialListItem.tsx
deleted file mode 100644
index 19a27638..00000000
--- a/frontend/src/components/lobby/radial-list/RadialListItem.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as React from 'react';
-import { ReactNode } from 'react';
-import { CartesianCoords } from './radial-math';
-import './RadialListItem.css';
-
-type RadialListItemProps = {
- item: ReactNode,
- offsets: CartesianCoords,
-};
-
-export const RadialListItem = ({item, offsets}: RadialListItemProps) => {
- // Y-axis points down, hence the minus sign
- const liStyle = {
- transform: `translate(${offsets.x}px, ${-offsets.y}px) translate(-50%, -50%)`,
- };
-
- return <li className='radial-list-item' style={liStyle}>{item}</li>;
-};
diff --git a/frontend/src/components/lobby/radial-list/radial-math.ts b/frontend/src/components/lobby/radial-list/radial-math.ts
deleted file mode 100644
index f0f411f5..00000000
--- a/frontend/src/components/lobby/radial-list/radial-math.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-export type CartesianCoords = {
- x: number,
- y: number,
-}
-type PolarCoords = {
- radius: number,
- angleDeg: number,
-}
-
-const toRad = (deg: number) => deg * (Math.PI / 180);
-const roundedProjection = (radius: number, thetaRad: number, trigFn: (angle: number) => number) => Math.round(radius * trigFn(thetaRad));
-const xProjection = (radius: number, thetaRad: number) => roundedProjection(radius, thetaRad, Math.cos);
-const yProjection = (radius: number, thetaRad: number) => roundedProjection(radius, thetaRad, Math.sin);
-
-const toCartesian = ({radius, angleDeg}: PolarCoords): CartesianCoords => ({
- x: xProjection(radius, toRad(angleDeg)),
- y: yProjection(radius, toRad(angleDeg)),
-});
-
-export type Direction = -1 | 1;
-export const CLOCKWISE: Direction = -1;
-export const COUNTERCLOCKWISE: Direction = 1;
-
-export type RadialConfig = {
- radius: number,
- arc: number,
- offsetDegrees: number,
- direction: Direction,
-}
-const DEFAULT_CONFIG: RadialConfig = {
- radius: 120,
- arc: 360,
- offsetDegrees: 0,
- direction: CLOCKWISE,
-};
-
-const DEFAULT_START = 90; // Up
-
-export function offsetsFromCenter(nbItems: number, radialConfig: RadialConfig = DEFAULT_CONFIG): Array<CartesianCoords> {
- return Array.from({length: nbItems}, (v, i) => itemCartesianOffsets(i, nbItems, radialConfig));
-}
-
-function itemCartesianOffsets(index: number, nbItems: number, {radius, arc, direction, offsetDegrees}: RadialConfig): CartesianCoords {
- const startAngle = DEFAULT_START + direction * offsetDegrees;
- const angleStep = arc / nbItems;
- const itemAngle = startAngle + direction * angleStep * index;
- return toCartesian({radius, angleDeg: itemAngle});
-}
diff --git a/frontend/src/components/lobby/round-table.png b/frontend/src/components/lobby/round-table.png
deleted file mode 100644
index f277376d..00000000
--- a/frontend/src/components/lobby/round-table.png
+++ /dev/null
Binary files differ
diff --git a/frontend/src/global-styles.css b/frontend/src/global-styles.css
deleted file mode 100644
index e69de29b..00000000
--- a/frontend/src/global-styles.css
+++ /dev/null
diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx
deleted file mode 100644
index fce90915..00000000
--- a/frontend/src/index.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import '@blueprintjs/core/lib/css/blueprint.css';
-import React from 'react';
-import ReactDOM from 'react-dom';
-import { Provider } from 'react-redux';
-import { ConnectedRouter } from 'react-router-redux';
-import { Application } from './components/Application';
-import { INITIAL_STATE } from './reducers';
-import { configureStore } from './store';
-
-const { store, history } = configureStore(INITIAL_STATE);
-
-const rootElement = document.getElementById('root');
-if (rootElement) {
- ReactDOM.render(<Provider store={store}>
- <ConnectedRouter history={history}>
- <Application/>
- </ConnectedRouter>
- </Provider>, rootElement);
-} else {
- console.error('Element with ID "root" was not found, cannot bootstrap react app');
-}
diff --git a/frontend/src/react-app-env.d.ts b/frontend/src/react-app-env.d.ts
deleted file mode 100644
index 6431bc5f..00000000
--- a/frontend/src/react-app-env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="react-scripts" />
diff --git a/frontend/src/reducers.ts b/frontend/src/reducers.ts
deleted file mode 100644
index f885f642..00000000
--- a/frontend/src/reducers.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { routerReducer } from 'react-router-redux';
-import { combineReducers } from 'redux';
-import { ApiPlayer } from './api/model';
-import { CurrentGameState, EMPTY_CURRENT_GAME } from './redux/currentGame';
-import { createCurrentGameReducer } from './redux/currentGame';
-import { EMPTY_GAMES, GamesState } from './redux/games';
-import { createGamesReducer } from './redux/games';
-import { currentUserReducer } from './redux/user';
-
-export type GlobalState = {
- currentGame: CurrentGameState;
- currentUser: ApiPlayer | null;
- games: GamesState;
- routing: any;
-}
-
-export const INITIAL_STATE: GlobalState = {
- currentGame: EMPTY_CURRENT_GAME,
- currentUser: null,
- games: EMPTY_GAMES,
- routing: null,
-};
-
-export function createReducer() {
- return combineReducers({
- currentGame: createCurrentGameReducer(),
- currentUser: currentUserReducer,
- games: createGamesReducer(),
- routing: routerReducer,
- });
-}
diff --git a/frontend/src/redux/actions/all.ts b/frontend/src/redux/actions/all.ts
deleted file mode 100644
index 57d2a443..00000000
--- a/frontend/src/redux/actions/all.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { GameAction } from './game';
-import { LobbyAction } from './lobby';
-import { PlayerAction } from './user';
-
-export type Action = PlayerAction | LobbyAction | GameAction
diff --git a/frontend/src/redux/actions/game.ts b/frontend/src/redux/actions/game.ts
deleted file mode 100644
index b67ea1dc..00000000
--- a/frontend/src/redux/actions/game.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { ApiPlayerMove, ApiPlayerTurnInfo, ApiPreparedCard, ApiTable } from '../../api/model';
-
-export const REQUEST_SAY_READY = 'GAME/REQUEST_SAY_READY';
-export const REQUEST_PREPARE_MOVE = 'GAME/REQUEST_PREPARE_MOVE';
-export const PLAYER_READY_RECEIVED = 'GAME/PLAYER_READY_RECEIVED';
-export const TABLE_UPDATE_RECEIVED = 'GAME/TABLE_UPDATE_RECEIVED';
-export const PREPARED_CARD_RECEIVED = 'GAME/PREPARED_CARD_RECEIVED';
-export const TURN_INFO_RECEIVED = 'GAME/TURN_INFO_RECEIVED';
-
-export type SayReadyAction = { type: typeof REQUEST_SAY_READY };
-export type PrepareMoveAction = { type: typeof REQUEST_PREPARE_MOVE, move: ApiPlayerMove };
-export type PlayerReadyEvent = { type: typeof PLAYER_READY_RECEIVED, username: string };
-export type TableUpdateEvent = { type: typeof TABLE_UPDATE_RECEIVED, table: ApiTable };
-export type PreparedCardEvent = { type: typeof PREPARED_CARD_RECEIVED, card: ApiPreparedCard };
-export type TurnInfoEvent = { type: typeof TURN_INFO_RECEIVED, turnInfo: ApiPlayerTurnInfo };
-
-export type GameAction =
- SayReadyAction
- | PrepareMoveAction
- | PlayerReadyEvent
- | TableUpdateEvent
- | PreparedCardEvent
- | TurnInfoEvent;
-
-export const actions = {
- sayReady: () => ({ type: REQUEST_SAY_READY }),
- prepareMove: (move: ApiPlayerMove) => ({ type: REQUEST_PREPARE_MOVE, move }),
- receivePlayerReady: (username: string) => ({ type: PLAYER_READY_RECEIVED, username }),
- receiveTableUpdate: (table: ApiTable) => ({ type: TABLE_UPDATE_RECEIVED, table }),
- receivePreparedCard: (card: ApiPreparedCard) => ({ type: PREPARED_CARD_RECEIVED, card }),
- receiveTurnInfo: (turnInfo: ApiPlayerTurnInfo) => ({ type: TURN_INFO_RECEIVED, turnInfo }),
-};
diff --git a/frontend/src/redux/actions/lobby.ts b/frontend/src/redux/actions/lobby.ts
deleted file mode 100644
index c121b022..00000000
--- a/frontend/src/redux/actions/lobby.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { ApiLobby } from '../../api/model';
-
-export const UPDATE_GAMES = 'GAMES/UPDATE_GAMES';
-export const REQUEST_CREATE_GAME = 'GAMES/REQUEST_CREATE_GAME';
-export const REQUEST_JOIN_GAME = 'GAMES/REQUEST_JOIN_GAME';
-export const REQUEST_START_GAME = 'GAMES/REQUEST_START_GAME';
-export const ENTER_LOBBY = 'GAMES/ENTER_LOBBY';
-export const ENTER_GAME = 'GAMES/ENTER_GAME';
-
-export type UpdateGamesAction = { type: typeof UPDATE_GAMES, games: ApiLobby[]};
-export type RequestCreateGameAction = { type: typeof REQUEST_CREATE_GAME, gameName: string };
-export type RequestJoinGameAction = { type: typeof REQUEST_JOIN_GAME, gameId: number };
-export type RequestStartGameAction = { type: typeof REQUEST_START_GAME };
-export type EnterLobbyAction = { type: typeof ENTER_LOBBY, gameId: number };
-export type EnterGameAction = { type: typeof ENTER_GAME, gameId: number };
-
-export type LobbyAction =
- | UpdateGamesAction
- | RequestCreateGameAction
- | RequestJoinGameAction
- | RequestStartGameAction
- | EnterLobbyAction
- | EnterGameAction;
-
-export const actions = {
- updateGames: (games: ApiLobby[]): UpdateGamesAction => ({ type: UPDATE_GAMES, games }),
- requestJoinGame: (gameId: number): RequestJoinGameAction => ({ type: REQUEST_JOIN_GAME, gameId }),
- requestCreateGame: (gameName: string): RequestCreateGameAction => ({ type: REQUEST_CREATE_GAME, gameName }),
- requestStartGame: (): RequestStartGameAction => ({ type: REQUEST_START_GAME }),
- enterLobby: (gameId: number): EnterLobbyAction => ({ type: ENTER_LOBBY, gameId }),
- enterGame: (gameId: number): EnterGameAction => ({ type: ENTER_GAME, gameId }),
-};
diff --git a/frontend/src/redux/actions/user.ts b/frontend/src/redux/actions/user.ts
deleted file mode 100644
index 29c85707..00000000
--- a/frontend/src/redux/actions/user.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Map } from 'immutable';
-import { ApiPlayer } from '../../api/model';
-
-export const REQUEST_CHOOSE_USERNAME = 'USER/REQUEST_CHOOSE_USERNAME';
-export const SET_CURRENT_PLAYER = 'USER/SET_CURRENT_PLAYER';
-export const UPDATE_PLAYERS = 'USER/UPDATE_PLAYERS';
-
-export type RequestChooseUsernameAction = { type: typeof REQUEST_CHOOSE_USERNAME, username: string };
-export type SetCurrentPlayerAction = { type: typeof SET_CURRENT_PLAYER, player: ApiPlayer };
-export type UpdatePlayersAction = { type: typeof UPDATE_PLAYERS, players: Map<string, ApiPlayer> };
-
-export type PlayerAction = RequestChooseUsernameAction | SetCurrentPlayerAction | UpdatePlayersAction;
-
-export const actions = {
- chooseUsername: (username: string): RequestChooseUsernameAction => ({ type: REQUEST_CHOOSE_USERNAME, username }),
- setCurrentPlayer: (player: ApiPlayer): SetCurrentPlayerAction => ({ type: SET_CURRENT_PLAYER, player }),
-};
diff --git a/frontend/src/redux/currentGame.ts b/frontend/src/redux/currentGame.ts
deleted file mode 100644
index 5e015d60..00000000
--- a/frontend/src/redux/currentGame.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { combineReducers } from 'redux';
-import { ApiPlayerTurnInfo, ApiTable } from '../api/model';
-import { GlobalState } from '../reducers';
-import { Action } from './actions/all';
-import { TABLE_UPDATE_RECEIVED, TURN_INFO_RECEIVED } from './actions/game';
-
-export type CurrentGameState = {
- turnInfo: ApiPlayerTurnInfo | null;
- table: ApiTable | null;
-}
-
-export const EMPTY_CURRENT_GAME: CurrentGameState = {
- turnInfo: null,
- table: null,
-};
-
-export function createCurrentGameReducer() {
- return combineReducers({
- turnInfo: turnInfoReducer,
- table: tableUpdatesReducer,
- });
-}
-
-const turnInfoReducer = (state: ApiPlayerTurnInfo | null = null, action: Action) => {
- switch (action.type) {
- case TURN_INFO_RECEIVED:
- return action.turnInfo;
- case TABLE_UPDATE_RECEIVED:
- return null;
- default:
- return state;
- }
-};
-
-const tableUpdatesReducer = (state: ApiTable | null = null, action: Action) => {
- switch (action.type) {
- case TURN_INFO_RECEIVED:
- return action.turnInfo.table;
- case TABLE_UPDATE_RECEIVED:
- return action.table;
- default:
- return state;
- }
-};
-
-export const getCurrentTurnInfo = (state: GlobalState): ApiPlayerTurnInfo | null => state.currentGame.turnInfo;
diff --git a/frontend/src/redux/games.ts b/frontend/src/redux/games.ts
deleted file mode 100644
index 4df2f1da..00000000
--- a/frontend/src/redux/games.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { List, Map } from 'immutable';
-import { combineReducers } from 'redux';
-import { ApiLobby } from '../api/model';
-import { GlobalState } from '../reducers';
-import { Action } from './actions/all';
-import { ENTER_LOBBY, UPDATE_GAMES } from './actions/lobby';
-
-export type GamesState = {
- all: Map<string, ApiLobby>,
- current: string | null
-};
-
-export const EMPTY_GAMES: GamesState = {
- all: Map(),
- current: null,
-};
-
-export const createGamesReducer = () => {
- return combineReducers({
- all: allGamesReducer,
- current: currentGameIdReducer
- })
-};
-
-export const allGamesReducer = (state: Map<string, ApiLobby> = Map(), action: Action) => {
- switch (action.type) {
- case UPDATE_GAMES:
- const newGames = mapify(action.games);
- return state.merge(newGames);
- default:
- return state;
- }
-};
-
-function mapify(games: ApiLobby[]): Map<string, ApiLobby> {
- let newGames: {[id:string]:ApiLobby} = {};
- games.forEach(g => newGames[`${g.id}`] = g);
- return Map(newGames);
-}
-
-export const currentGameIdReducer = (state: string | null = null, action: Action) => {
- switch (action.type) {
- case ENTER_LOBBY:
- return `${action.gameId}`;
- default:
- return state;
- }
-};
-
-export const getAllGames = (state: GlobalState): List<ApiLobby> => state.games.all.toList();
-export const getCurrentGame = (state: GlobalState): ApiLobby | null => {
- if (state.games.current == null) {
- return null;
- }
- return state.games.all.get(state.games.current) || null;
-};
diff --git a/frontend/src/redux/user.ts b/frontend/src/redux/user.ts
deleted file mode 100644
index 2cc25cc0..00000000
--- a/frontend/src/redux/user.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { ApiPlayer } from '../api/model';
-import { GlobalState } from '../reducers';
-import { Action } from './actions/all';
-import { SET_CURRENT_PLAYER } from './actions/user';
-import { getCurrentGame } from './games';
-
-export type User = {
- username: string,
- displayName: string,
-}
-
-export const currentUserReducer = (state: User | null = null, action: Action) => {
- switch (action.type) {
- case SET_CURRENT_PLAYER:
- return {
- username: action.player.username,
- displayName: action.player.displayName
- };
- default:
- return state;
- }
-};
-
-export function getCurrentUser(state: GlobalState): User | null {
- return state.currentUser
-}
-
-export function getCurrentPlayer(state: GlobalState): ApiPlayer | null {
- if (state.currentUser == null) {
- return null;
- }
- let game = getCurrentGame(state);
- if (game == null) {
- return null;
- }
- for (let i = 0; i < game.players.length; i++) {
- let player = game.players[i];
- if (player.username === state.currentUser.username) {
- return player;
- }
- }
- return null;
-}
diff --git a/frontend/src/sagas.ts b/frontend/src/sagas.ts
deleted file mode 100644
index 03c71b63..00000000
--- a/frontend/src/sagas.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { SagaIterator } from 'redux-saga';
-import { call, fork } from 'redux-saga/effects';
-import { connectToGame, SevenWondersSession } from './api/sevenWondersApi';
-import { errorHandlingSaga } from './sagas/errors';
-import { gameSaga } from './sagas/game';
-import { gameBrowserSaga } from './sagas/gameBrowser';
-import { homeSaga } from './sagas/home';
-import { lobbySaga } from './sagas/lobby';
-
-export function* rootSaga(): SagaIterator {
- let sevenWondersSession: SevenWondersSession;
- try {
- sevenWondersSession = yield call(connectToGame);
- } catch (error) {
- console.error('Could not connect to socket', error);
- return;
- }
- yield fork(errorHandlingSaga, sevenWondersSession);
- yield fork(homeSaga, sevenWondersSession);
- yield fork(gameBrowserSaga, sevenWondersSession);
- yield fork(lobbySaga, sevenWondersSession);
- yield fork(gameSaga, sevenWondersSession);
-}
diff --git a/frontend/src/sagas/errors.ts b/frontend/src/sagas/errors.ts
deleted file mode 100644
index b27dfa95..00000000
--- a/frontend/src/sagas/errors.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import {Toaster} from '@blueprintjs/core';
-import {Channel, eventChannel} from 'redux-saga';
-import {apply, cancelled, take} from 'redux-saga/effects';
-import {ApiError} from '../api/model';
-import {SevenWondersSession} from '../api/sevenWondersApi';
-
-const ErrorToaster = Toaster.create();
-
-export function* errorHandlingSaga(session: SevenWondersSession): any {
- const errorChannel: Channel<ApiError> = yield eventChannel(session.watchErrors());
- try {
- while (true) {
- const error: ApiError = yield take(errorChannel);
- yield* handleOneError(error);
- }
- } finally {
- if (yield cancelled()) {
- console.log('Error management saga cancelled');
- yield apply(errorChannel, errorChannel.close);
- }
- }
-}
-
-function* handleOneError(err: ApiError): any {
- console.error('Error received on web socket channel', err);
- const msg = buildMsg(err);
- yield apply(ErrorToaster, ErrorToaster.show, [{ intent: 'danger', icon: 'error', message: msg }]);
-}
-
-function buildMsg(err: ApiError): string {
- if (err.details.length > 0) {
- return err.details.map(d => d.message).join('\n');
- } else {
- return err.message;
- }
-}
diff --git a/frontend/src/sagas/game.ts b/frontend/src/sagas/game.ts
deleted file mode 100644
index a60ab2d3..00000000
--- a/frontend/src/sagas/game.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import { eventChannel, SagaIterator } from 'redux-saga';
-import { apply, call, put, take } from 'redux-saga/effects';
-import { ApiPlayerTurnInfo, ApiPreparedCard, ApiTable } from '../api/model';
-import { SevenWondersSession } from '../api/sevenWondersApi';
-import { actions, REQUEST_PREPARE_MOVE, REQUEST_SAY_READY } from '../redux/actions/game';
-import { ENTER_GAME } from '../redux/actions/lobby';
-
-function* watchPlayerReady(session: SevenWondersSession, gameId: number) {
- const channel = yield eventChannel(session.watchPlayerReady(gameId));
- try {
- while (true) {
- const username = yield take(channel);
- yield put(actions.receivePlayerReady(username));
- }
- } finally {
- yield apply(channel, channel.close);
- }
-}
-
-function* watchTableUpdates(session: SevenWondersSession, gameId: number) {
- const channel = yield eventChannel(session.watchTableUpdates(gameId));
- try {
- while (true) {
- const table: ApiTable = yield take(channel);
- yield put(actions.receiveTableUpdate(table));
- }
- } finally {
- yield apply(channel, channel.close);
- }
-}
-
-function* watchPreparedCards(session: SevenWondersSession, gameId: number) {
- const channel = yield eventChannel(session.watchPreparedCards(gameId));
- try {
- while (true) {
- const preparedCard: ApiPreparedCard = yield take(channel);
- yield put(actions.receivePreparedCard(preparedCard));
- }
- } finally {
- yield apply(channel, channel.close);
- }
-}
-
-function* sayReady(session: SevenWondersSession): SagaIterator {
- while (true) {
- yield take(REQUEST_SAY_READY);
- yield apply(session, session.sayReady);
- }
-}
-
-function* prepareMove(session: SevenWondersSession): SagaIterator {
- while (true) {
- let action = yield take(REQUEST_PREPARE_MOVE);
- yield apply(session, session.prepareMove, [action.move]);
- }
-}
-
-function* watchTurnInfo(session: SevenWondersSession) {
- const channel = yield eventChannel(session.watchTurnInfo());
- try {
- while (true) {
- const turnInfo: ApiPlayerTurnInfo = yield take(channel);
- yield put(actions.receiveTurnInfo(turnInfo));
- }
- } finally {
- yield apply(channel, channel.close);
- }
-}
-
-export function* gameSaga(session: SevenWondersSession): SagaIterator {
- const { gameId } = yield take(ENTER_GAME);
- console.log('Entered game!', gameId);
- yield [
- call(watchPlayerReady, session, gameId),
- call(watchTableUpdates, session, gameId),
- call(watchPreparedCards, session, gameId),
- call(sayReady, session),
- call(prepareMove, session),
- call(watchTurnInfo, session)
- ];
-}
diff --git a/frontend/src/sagas/gameBrowser.ts b/frontend/src/sagas/gameBrowser.ts
deleted file mode 100644
index 868ec471..00000000
--- a/frontend/src/sagas/gameBrowser.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { push } from 'react-router-redux';
-import { eventChannel, SagaIterator } from 'redux-saga';
-import { all, apply, call, put, take } from 'redux-saga/effects';
-import { ApiLobby } from '../api/model';
-import { SevenWondersSession } from '../api/sevenWondersApi';
-import { actions as gameActions, REQUEST_CREATE_GAME, REQUEST_JOIN_GAME } from '../redux/actions/lobby';
-
-function* watchGames(session: SevenWondersSession): any {
- const gamesChannel = yield eventChannel(session.watchGames());
- try {
- while (true) {
- const gameList = yield take(gamesChannel);
- yield put(gameActions.updateGames(gameList));
- }
- } finally {
- yield apply(gamesChannel, gamesChannel.close);
- }
-}
-
-function* watchLobbyJoined(session: SevenWondersSession): any {
- const joinedLobbyChannel = yield eventChannel(session.watchLobbyJoined());
- try {
- const joinedLobby: ApiLobby = yield take(joinedLobbyChannel);
- yield put(gameActions.updateGames([joinedLobby]));
- yield put(gameActions.enterLobby(joinedLobby.id));
- yield put(push(`/lobby/${joinedLobby.id}`));
- } finally {
- yield apply(joinedLobbyChannel, joinedLobbyChannel.close);
- }
-}
-
-function* createGame(session: SevenWondersSession): SagaIterator {
- while (true) {
- const { gameName } = yield take(REQUEST_CREATE_GAME);
- // $FlowFixMe
- yield apply(session, session.createGame, [gameName]);
- }
-}
-
-function* joinGame(session: SevenWondersSession): SagaIterator {
- while (true) {
- const { gameId } = yield take(REQUEST_JOIN_GAME);
- // $FlowFixMe
- yield apply(session, session.joinGame, [gameId]);
- }
-}
-
-export function* gameBrowserSaga(session: SevenWondersSession): SagaIterator {
- yield all([
- call(watchGames, session),
- call(watchLobbyJoined, session),
- call(createGame, session),
- call(joinGame, session),
- ]);
-}
diff --git a/frontend/src/sagas/home.ts b/frontend/src/sagas/home.ts
deleted file mode 100644
index 585c536e..00000000
--- a/frontend/src/sagas/home.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { push } from 'react-router-redux';
-import { eventChannel, SagaIterator } from 'redux-saga';
-import { all, apply, call, put, take } from 'redux-saga/effects';
-import { ApiPlayer } from '../api/model';
-import { SevenWondersSession } from '../api/sevenWondersApi';
-import { actions, REQUEST_CHOOSE_USERNAME } from '../redux/actions/user';
-
-function* sendUsername(session: SevenWondersSession): SagaIterator {
- while (true) {
- const { username } = yield take(REQUEST_CHOOSE_USERNAME);
- // $FlowFixMe
- yield apply(session, session.chooseName, [username]);
- }
-}
-
-function* validateUsername(session: SevenWondersSession): any {
- const usernameChannel = yield eventChannel(session.watchNameChoice());
- while (true) {
- const user: ApiPlayer = yield take(usernameChannel);
- yield put(actions.setCurrentPlayer(user));
- yield apply(usernameChannel, usernameChannel.close);
- yield put(push('/games'));
- }
-}
-
-export function* homeSaga(session: SevenWondersSession): SagaIterator {
- yield all([call(sendUsername, session), call(validateUsername, session)]);
-}
diff --git a/frontend/src/sagas/lobby.ts b/frontend/src/sagas/lobby.ts
deleted file mode 100644
index 09360b02..00000000
--- a/frontend/src/sagas/lobby.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { push } from 'react-router-redux';
-import { Channel, eventChannel, SagaIterator } from 'redux-saga';
-import { all, apply, call, put, take } from 'redux-saga/effects';
-import { SevenWondersSession } from '../api/sevenWondersApi';
-import { actions as gameActions, ENTER_LOBBY, REQUEST_START_GAME } from '../redux/actions/lobby';
-
-function* watchLobbyUpdates(session: SevenWondersSession, lobbyId: number): any {
- const lobbyUpdatesChannel: Channel<Object> = yield eventChannel(session.watchLobbyUpdated(lobbyId));
- try {
- while (true) {
- const lobby = yield take(lobbyUpdatesChannel);
- yield put(gameActions.updateGames([lobby]));
- }
- } finally {
- yield apply(lobbyUpdatesChannel, lobbyUpdatesChannel.close);
- }
-}
-
-function* watchGameStart(session: SevenWondersSession, lobbyId: number): any {
- const gameStartedChannel = yield eventChannel(session.watchGameStarted(lobbyId));
- try {
- yield take(gameStartedChannel);
- yield put(gameActions.enterGame(lobbyId));
- yield put(push(`/game/${lobbyId}`));
- } finally {
- yield apply(gameStartedChannel, gameStartedChannel.close);
- }
-}
-
-function* startGame(session: SevenWondersSession): SagaIterator {
- while (true) {
- yield take(REQUEST_START_GAME);
- yield apply(session, session.startGame);
- }
-}
-
-export function* lobbySaga(session: SevenWondersSession): SagaIterator {
- const { gameId } = yield take(ENTER_LOBBY);
- yield all([
- call(watchLobbyUpdates, session, gameId),
- call(watchGameStart, session, gameId),
- call(startGame, session)
- ]);
-}
diff --git a/frontend/src/setupProxy.js b/frontend/src/setupProxy.js
deleted file mode 100644
index 88831e6e..00000000
--- a/frontend/src/setupProxy.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const proxy = require('http-proxy-middleware');
-
-module.exports = function(app) {
- app.use(proxy('/seven-wonders-websocket', {
- "target": "http://localhost:8080",
- "ws": true
- }));
-};
diff --git a/frontend/src/store.ts b/frontend/src/store.ts
deleted file mode 100644
index 54a65509..00000000
--- a/frontend/src/store.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import createHistory from 'history/createBrowserHistory';
-import { routerMiddleware } from 'react-router-redux';
-import { applyMiddleware, createStore } from 'redux';
-import { composeWithDevTools } from 'redux-devtools-extension';
-import createSagaMiddleware from 'redux-saga';
-import { GlobalState } from './reducers';
-import { createReducer } from './reducers';
-import { rootSaga } from './sagas';
-
-export function configureStore(initialState: GlobalState) {
- const sagaMiddleware = createSagaMiddleware();
-
- const history = createHistory();
-
- const middlewares = [sagaMiddleware, routerMiddleware(history)];
-
- const enhancers = [applyMiddleware(...middlewares)];
-
- const store = createStore(createReducer(), initialState, composeWithDevTools(...enhancers));
-
- sagaMiddleware.run(rootSaga);
-
- return {
- store,
- history,
- };
-}
bgstack15