diff options
-rw-r--r-- | frontend/src/containers/gameBrowser.js | 17 | ||||
-rw-r--r-- | frontend/src/index.js | 1 | ||||
-rw-r--r-- | frontend/src/layouts/HomeLayout.js | 7 | ||||
-rw-r--r-- | frontend/src/layouts/LobbyLayout.js | 6 | ||||
-rw-r--r-- | frontend/src/models/games.js | 50 | ||||
-rw-r--r-- | frontend/src/models/players.js | 33 | ||||
-rw-r--r-- | frontend/src/reducers.js | 1 | ||||
-rw-r--r-- | frontend/src/redux/app.js | 1 | ||||
-rw-r--r-- | frontend/src/redux/games.js | 15 | ||||
-rw-r--r-- | frontend/src/routes.js | 1 | ||||
-rw-r--r-- | frontend/src/sagas.js | 1 | ||||
-rw-r--r-- | frontend/src/schemas/games.js | 8 | ||||
-rw-r--r-- | frontend/src/store.js | 3 | ||||
-rw-r--r-- | frontend/src/utils/websocket.js | 5 |
14 files changed, 109 insertions, 40 deletions
diff --git a/frontend/src/containers/gameBrowser.js b/frontend/src/containers/gameBrowser.js index ac3f1504..89ac56e3 100644 --- a/frontend/src/containers/gameBrowser.js +++ b/frontend/src/containers/gameBrowser.js @@ -1,4 +1,10 @@ +// @flow import React, { Component } from 'react'; + +import type { List } from 'immutable'; +import type { GamesType } from '../models/games'; +import type { PlayerType } from '../models/players'; + import { connect } from 'react-redux'; import { Space, InlineForm, Text } from 'rebass'; import { Flex } from 'reflexbox'; @@ -8,7 +14,14 @@ import { getCurrentPlayer } from '../redux/players'; import { getAllGames, actions } from '../redux/games'; class GameBrowser extends Component { - createGame = e => { + props: { + currentPlayer: PlayerType, + games: List<GamesType> + }; + + _gameName: string | void = undefined; + + createGame = (e: SyntheticEvent): void => { e.preventDefault(); if (this._gameName !== undefined) { this.props.createGame(this._gameName); @@ -23,7 +36,7 @@ class GameBrowser extends Component { buttonLabel="Create Game" label="Game name" name="game_name" - onChange={e => (this._gameName = e.target.value)} + onChange={(e: SyntheticInputEvent) => (this._gameName = e.target.value)} onClick={this.createGame} /> <Space auto /> diff --git a/frontend/src/index.js b/frontend/src/index.js index 37d8fcf8..a3fbe7ce 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -1,3 +1,4 @@ +// @flow import 'babel-polyfill'; import './global-styles.css'; diff --git a/frontend/src/layouts/HomeLayout.js b/frontend/src/layouts/HomeLayout.js index 613f2876..61eef427 100644 --- a/frontend/src/layouts/HomeLayout.js +++ b/frontend/src/layouts/HomeLayout.js @@ -1,14 +1,15 @@ -import React from 'react'; +// @flow +import React, { type Children } from 'react'; import { Banner } from 'rebass'; import logo from './logo-7-wonders.png'; import background from './background-zeus-temple.jpg'; import ErrorToastContainer from '../components/errors/errorToastContainer'; -export default props => ( +export default ({ children }: { children: Children }) => ( <div> <Banner align="center" backgroundImage={background}> <img src={logo} alt="Seven Wonders" /> - {props.children} + {children} </Banner> <ErrorToastContainer /> </div> diff --git a/frontend/src/layouts/LobbyLayout.js b/frontend/src/layouts/LobbyLayout.js index 27757176..865641dd 100644 --- a/frontend/src/layouts/LobbyLayout.js +++ b/frontend/src/layouts/LobbyLayout.js @@ -1,9 +1,9 @@ -import React from 'react'; +import React, { type Children } from 'react'; import { Banner } from 'rebass'; import logo from './logo-7-wonders.png'; import ErrorToastContainer from '../components/errors/errorToastContainer'; -export default props => ( +export default ({ children }: { children: Children }) => ( <div> <Banner align="center" @@ -12,7 +12,7 @@ export default props => ( > <img src={logo} alt="Seven Wonders Logo" /> </Banner> - {props.children} + {children} <ErrorToastContainer /> </div> ); diff --git a/frontend/src/models/games.js b/frontend/src/models/games.js index 95bf8015..e48bf23f 100644 --- a/frontend/src/models/games.js +++ b/frontend/src/models/games.js @@ -1,6 +1,23 @@ import { Record, Map, List } from 'immutable'; -const SettingsRecord = Record({ +export type SettingsShape = { + initialGold: number, + lostPointsPerDefeat: number, + timeLimitInSeconds: number, + randomSeedForTests: number, + discardedCardGold: number, + defaultTradingCost: number, + wonPointsPerVictoryPerAge: { + '1': number, + '2': number, + '3': number + }, + wonderSidePickMethod: 'EACH_RANDOM' | 'TODO', + pointsPer3Gold: number +}; +export type SettingsType = Record<SettingsShape>; + +const SettingsRecord: SettingsType = Record({ initialGold: 3, lostPointsPerDefeat: 1, timeLimitInSeconds: 45, @@ -17,7 +34,18 @@ const SettingsRecord = Record({ }); export class Settings extends SettingsRecord {} -const GameRecord = Record({ +export type GameShape = { + id: number, + name: string | void, + players: List<string>, + settings: SettingsType, + state: 'LOBBY' | 'TODO' +}; +export type GameType = Record<GameShape>; +export type GameMapType = Map<string, GameShape>; +export type GameNormalMapType = { [string]: GameShape }; + +const GameRecord: GameType = Record({ id: -1, name: null, players: new List(), @@ -26,16 +54,22 @@ const GameRecord = Record({ }); export class Game extends GameRecord {} -const GamesRecord = Record({ +export type GamesShape = { + all: Map<Games>, + current: string +}; +export type GamesType = Record<GamesShape>; + +const GamesRecord: GamesType = Record({ all: new Map(), - current: '', + current: null, }); export default class GamesState extends GamesRecord { - addGame(g) { - const game = new Game(g); + addGame(g: GameShape) { + const game: Game = new Game(g); return this.mergeDeepIn(['all', game.id], game); } - addGames(games) { - return this.mergeIn(['all'], games.map(game => new Game(game))); + addGames(games: GameNormalMapType) { + return this.mergeIn(['all'], games.map((game: GameShape): Game => new Game(game))); } } diff --git a/frontend/src/models/players.js b/frontend/src/models/players.js index 3df32c57..13d5ad51 100644 --- a/frontend/src/models/players.js +++ b/frontend/src/models/players.js @@ -1,26 +1,43 @@ +// @flow import { Record, Map } from 'immutable'; -const PlayerRecord = Record({ +export type PlayerShape = { + username: string, + displayName: string, + index: number, + ready: boolean +}; +export type PlayerType = Record<PlayerShape>; + +const PlayerRecord: PlayerType = Record({ username: null, displayName: null, index: 0, ready: false, }); +// $FlowFixMe export class Player extends PlayerRecord {} -const PlayersRecord = Record({ +export type PlayersShape = { + all: Map<string, PlayerType>, + current: string +}; +export type PlayersType = Record<PlayersShape>; + +const PlayersRecord: PlayersType = Record({ all: new Map(), current: '', }); +// $FlowFixMe export default class PlayerState extends PlayersRecord { - addPlayer(p) { - const player = new Player(p); - const playerMap = new Map({ [player.username]: player }); + addPlayer(p: PlayerShape) { + const player: Player = new Player(p); + const playerMap = new Map(({ [player.username]: player }: { [key: string]: Player })); return this.addPlayers(playerMap).set('current', player.username); } - addPlayers(p) { - const players = new Map(p); - return this.mergeIn(['all'], players.map(player => new Player(player))); + addPlayers(p: Map<string, PlayerShape>) { + const players: Map<string, PlayerShape> = new Map(p); + return this.mergeIn(['all'], players.map((player: PlayerShape): Player => new Player(player))); } } diff --git a/frontend/src/reducers.js b/frontend/src/reducers.js index 8a4c3083..f4e88297 100644 --- a/frontend/src/reducers.js +++ b/frontend/src/reducers.js @@ -1,3 +1,4 @@ +// @flow import { combineReducers } from 'redux-immutable'; import { routerReducer } from 'react-router-redux'; import { reducer as toastrReducer } from 'react-redux-toastr'; diff --git a/frontend/src/redux/app.js b/frontend/src/redux/app.js index 614e7d93..70074abd 100644 --- a/frontend/src/redux/app.js +++ b/frontend/src/redux/app.js @@ -1,3 +1,4 @@ +// @flow export const makeSelectLocationState = () => { return state => { return state.get('routing'); diff --git a/frontend/src/redux/games.js b/frontend/src/redux/games.js index d5953db1..f2df2492 100644 --- a/frontend/src/redux/games.js +++ b/frontend/src/redux/games.js @@ -1,5 +1,6 @@ +// @flow import { fromJS } from 'immutable'; -import GamesState from '../models/games'; +import GamesState, { type GameMapType, type GameNormalMapType, type GameShape } from '../models/games'; export const types = { UPDATE_GAMES: 'GAME/UPDATE_GAMES', @@ -10,19 +11,21 @@ export const types = { ENTER_GAME: 'GAME/ENTER_GAME', }; +type Actions = { type: 'GAME/UPDATE_GAMES', games: GameMapType } | { type: 'GAME/REQUEST_CREATE_GAME', gameId: string }; + export const actions = { - updateGames: games => ({ type: types.UPDATE_GAMES, games: fromJS(games) }), - requestJoinGame: gameId => ({ type: types.REQUEST_JOIN_GAME, gameId }), - requestCreateGame: gameName => ({ + updateGames: (games: GameNormalMapType) => ({ type: types.UPDATE_GAMES, games: fromJS(games) }), + requestJoinGame: (gameId: string) => ({ type: types.REQUEST_JOIN_GAME, gameId }), + requestCreateGame: (gameName: string) => ({ type: types.REQUEST_CREATE_GAME, gameName, }), requestStartGame: () => ({ type: types.REQUEST_START_GAME }), - enterLobby: lobby => ({ type: types.ENTER_LOBBY, lobby: fromJS(lobby) }), + enterLobby: (lobby: GameShape) => ({ type: types.ENTER_LOBBY, lobby: fromJS(lobby) }), enterGame: () => ({ type: types.ENTER_GAME }), }; -export default (state = new GamesState(), action) => { +export default (state: GamesState = new GamesState(), action: Actions) => { switch (action.type) { case types.UPDATE_GAMES: return state.addGames(action.games); diff --git a/frontend/src/routes.js b/frontend/src/routes.js index 29894c3a..40906b93 100644 --- a/frontend/src/routes.js +++ b/frontend/src/routes.js @@ -1,3 +1,4 @@ +// @flow import { fork } from 'redux-saga/effects'; import homeSaga from './sagas/home'; import gameBrowserSaga from './sagas/gameBrowser'; diff --git a/frontend/src/sagas.js b/frontend/src/sagas.js index a28c7c72..9606d552 100644 --- a/frontend/src/sagas.js +++ b/frontend/src/sagas.js @@ -1,3 +1,4 @@ +// @flow import { router } from 'redux-saga-router'; import { call, fork } from 'redux-saga/effects'; diff --git a/frontend/src/schemas/games.js b/frontend/src/schemas/games.js index 68d14fb4..bcae0235 100644 --- a/frontend/src/schemas/games.js +++ b/frontend/src/schemas/games.js @@ -1,12 +1,6 @@ import { schema } from 'normalizr'; -const player = new schema.Entity( - 'players', - {}, - { - idAttribute: 'username', - } -); +const player = new schema.Entity('players', {}, { idAttribute: 'username' }); export const game = new schema.Entity('games', { players: [player], diff --git a/frontend/src/store.js b/frontend/src/store.js index 57f43a4f..a095695b 100644 --- a/frontend/src/store.js +++ b/frontend/src/store.js @@ -1,3 +1,4 @@ +// @flow import { createStore, applyMiddleware, compose } from 'redux'; import { browserHistory } from 'react-router'; import { syncHistoryWithStore, routerMiddleware } from 'react-router-redux'; @@ -8,7 +9,7 @@ import createSagaMiddleware from 'redux-saga'; import rootSaga from './sagas'; import { makeSelectLocationState } from './redux/app'; -export default function configureStore(initialState = {}) { +export default function configureStore(initialState: Object = {}) { const sagaMiddleware = createSagaMiddleware(); const middlewares = [sagaMiddleware, routerMiddleware(browserHistory)]; diff --git a/frontend/src/utils/websocket.js b/frontend/src/utils/websocket.js index b33b2d50..2751b16c 100644 --- a/frontend/src/utils/websocket.js +++ b/frontend/src/utils/websocket.js @@ -1,10 +1,11 @@ +// @flow import SockJS from 'sockjs-client'; import Stomp from 'webstomp-client'; import { eventChannel } from 'redux-saga'; const wsURL = '/seven-wonders-websocket'; -export const createWsConnection = (headers = {}) => +export const createWsConnection = (headers: Object = {}) => new Promise((resolve, reject) => { let socket = Stomp.over(new SockJS(wsURL), { debug: process.env.NODE_ENV !== 'production', @@ -12,7 +13,7 @@ export const createWsConnection = (headers = {}) => socket.connect(headers, frame => resolve({ frame, socket }), reject); }); -export const createSubscriptionChannel = (socket, path) => { +export const createSubscriptionChannel = (socket: any, path: string) => { return eventChannel(emitter => { const socketSubscription = socket.subscribe(path, event => { emitter(JSON.parse(event.body)); |