diff options
-rw-r--r-- | frontend/src/components/gameList.js | 10 | ||||
-rw-r--r-- | frontend/src/containers/gameBrowser.js | 10 | ||||
-rw-r--r-- | frontend/src/models/games.js | 2 | ||||
-rw-r--r-- | frontend/src/redux/games.js | 12 | ||||
-rw-r--r-- | frontend/src/sagas.js | 7 | ||||
-rw-r--r-- | frontend/src/sagas/gameBrowser.js | 13 | ||||
-rw-r--r-- | frontend/src/utils/websocket.js | 37 |
7 files changed, 65 insertions, 26 deletions
diff --git a/frontend/src/components/gameList.js b/frontend/src/components/gameList.js index 17dad16f..22366c5c 100644 --- a/frontend/src/components/gameList.js +++ b/frontend/src/components/gameList.js @@ -1,12 +1,16 @@ +// @flow import React from 'react'; import { Flex } from 'reflexbox'; import { Text, Space, Button } from 'rebass'; -const GameList = ({ games, joinGame }) => ( +import type { List } from 'immutable'; +import type { Game } from '../models/games'; + +const GameList = ({ games, joinGame }: { games: List<Game>, joinGame: (gameId: string) => void }) => ( <div> - {games.map((game, index) => { + {games.map((game: Game, index: number) => { return ( - <Flex key={index}> + <Flex key={game.get('displayName', index)}> <Text>{game.name}</Text> <Space auto /> <Button onClick={() => joinGame(game.id)}>Join</Button> diff --git a/frontend/src/containers/gameBrowser.js b/frontend/src/containers/gameBrowser.js index 89ac56e3..b654e9d9 100644 --- a/frontend/src/containers/gameBrowser.js +++ b/frontend/src/containers/gameBrowser.js @@ -2,8 +2,8 @@ import React, { Component } from 'react'; import type { List } from 'immutable'; -import type { GamesType } from '../models/games'; -import type { PlayerType } from '../models/players'; +import type { Games } from '../models/games'; +import type { Player } from '../models/players'; import { connect } from 'react-redux'; import { Space, InlineForm, Text } from 'rebass'; @@ -15,8 +15,10 @@ import { getAllGames, actions } from '../redux/games'; class GameBrowser extends Component { props: { - currentPlayer: PlayerType, - games: List<GamesType> + currentPlayer: Player, + games: List<Games>, + createGame: (gameName: string) => void, + joinGame: (gameId: string) => void }; _gameName: string | void = undefined; diff --git a/frontend/src/models/games.js b/frontend/src/models/games.js index e48bf23f..aab37aea 100644 --- a/frontend/src/models/games.js +++ b/frontend/src/models/games.js @@ -55,7 +55,7 @@ const GameRecord: GameType = Record({ export class Game extends GameRecord {} export type GamesShape = { - all: Map<Games>, + all: Map<Game>, current: string }; export type GamesType = Record<GamesShape>; diff --git a/frontend/src/redux/games.js b/frontend/src/redux/games.js index 6cc8f4c5..8926e84b 100644 --- a/frontend/src/redux/games.js +++ b/frontend/src/redux/games.js @@ -1,7 +1,9 @@ // @flow import { fromJS } from 'immutable'; import GamesState from '../models/games'; -import type { GameMapType, GameNormalMapType, GameShape } from "../models/games"; +import type { GameMapType, GameNormalMapType, GameShape, Game } from '../models/games'; +import type { Map, List } from 'immutable'; + export const types = { UPDATE_GAMES: 'GAME/UPDATE_GAMES', REQUEST_CREATE_GAME: 'GAME/REQUEST_CREATE_GAME', @@ -36,7 +38,7 @@ export default (state: GamesState = new GamesState(), action: Actions) => { } }; -export const getAllGamesById = games => games.all; -export const getAllGames = games => getAllGamesById(games).toList(); -export const getGame = (games, id) => getAllGamesById(games).get(`${id}`); -export const getCurrentGame = games => getGame(games, games.current); +export const getAllGamesById = (games: GamesState): Map<string, Game> => games.all; +export const getAllGames = (games: GamesState): List<Game> => getAllGamesById(games).toList(); +export const getGame = (games: GamesState, id: string | number): Game => getAllGamesById(games).get(`${id}`); +export const getCurrentGame = (games: GamesState) => getGame(games, games.current); diff --git a/frontend/src/sagas.js b/frontend/src/sagas.js index 9606d552..037aa9ed 100644 --- a/frontend/src/sagas.js +++ b/frontend/src/sagas.js @@ -6,8 +6,11 @@ import { makeSagaRoutes } from './routes'; import { createWsConnection } from './utils/websocket'; import errorHandlingSaga from './sagas/errors'; -export default function* rootSaga(history) { - let wsConnection; +import type { SocketObjectType } from './utils/websocket'; +import type { History } from 'react-router'; + +export default function* rootSaga(history: History): * { + let wsConnection: SocketObjectType | void; try { wsConnection = yield call(createWsConnection); } catch (error) { diff --git a/frontend/src/sagas/gameBrowser.js b/frontend/src/sagas/gameBrowser.js index 5492107a..55927bf2 100644 --- a/frontend/src/sagas/gameBrowser.js +++ b/frontend/src/sagas/gameBrowser.js @@ -1,3 +1,4 @@ +// @flow import { call, put, take, apply } from 'redux-saga/effects'; import { createSubscriptionChannel } from '../utils/websocket'; import { push } from 'react-router-redux'; @@ -8,7 +9,9 @@ import { game as gameSchema, gameList as gameListSchema } from '../schemas/games import { actions as gameActions, types } from '../redux/games'; import { actions as playerActions } from '../redux/players'; -function* watchGames({ socket }) { +import type { SocketObjectType, SocketType } from '../utils/websocket'; + +function* watchGames({ socket }: { socket: SocketType }): * { const gamesChannel = yield call(createSubscriptionChannel, socket, '/topic/games'); try { while (true) { @@ -23,7 +26,7 @@ function* watchGames({ socket }) { } } -function* watchLobbyJoined({ socket }) { +function* watchLobbyJoined({ socket }: { socket: SocketType }): * { const joinedLobbyChannel = yield call(createSubscriptionChannel, socket, '/user/queue/lobby/joined'); try { const joinedLobby = yield take(joinedLobbyChannel); @@ -38,21 +41,21 @@ function* watchLobbyJoined({ socket }) { } } -function* createGame({ socket }) { +function* createGame({ socket }: { socket: SocketType }): * { while (true) { const { gameName } = yield take(types.REQUEST_CREATE_GAME); yield apply(socket, socket.send, ['/app/lobby/create', JSON.stringify({ gameName }), {}]); } } -function* joinGame({ socket }) { +function* joinGame({ socket }: { socket: SocketType }): * { while (true) { const { gameId } = yield take(types.REQUEST_JOIN_GAME); yield apply(socket, socket.send, ['/app/lobby/join', JSON.stringify({ gameId }), {}]); } } -function* gameBrowserSaga(socketConnection) { +function* gameBrowserSaga(socketConnection: SocketObjectType): * { yield [ call(watchGames, socketConnection), call(watchLobbyJoined, socketConnection), diff --git a/frontend/src/utils/websocket.js b/frontend/src/utils/websocket.js index 2751b16c..b01531cf 100644 --- a/frontend/src/utils/websocket.js +++ b/frontend/src/utils/websocket.js @@ -5,17 +5,42 @@ import { eventChannel } from 'redux-saga'; const wsURL = '/seven-wonders-websocket'; -export const createWsConnection = (headers: Object = {}) => +export type FrameType = { + body: string, + command: string, + header: { + 'heart-beat': number, + 'user-name': string, + version: string + } +}; +export type SocketType = { + connect: (headers: Object, onSucces: (frame: FrameType) => void, onReject: (error: any) => void) => void, + subscribe: (path: string, callback: (event: any) => void) => Object +}; +export type SocketSubscriptionType = { + id: string, + unsubscribe: () => void +}; +export type SocketEventType = { + body: string +}; +export type SocketObjectType = { + frame: FrameType, + socket: SocketType +}; + +export const createWsConnection = (headers: Object = {}): Promise<SocketObjectType> => new Promise((resolve, reject) => { - let socket = Stomp.over(new SockJS(wsURL), { + let socket: SocketType = Stomp.over(new SockJS(wsURL), { debug: process.env.NODE_ENV !== 'production', }); - socket.connect(headers, frame => resolve({ frame, socket }), reject); + socket.connect(headers, (frame: FrameType) => resolve({ frame, socket }), reject); }); -export const createSubscriptionChannel = (socket: any, path: string) => { - return eventChannel(emitter => { - const socketSubscription = socket.subscribe(path, event => { +export const createSubscriptionChannel = (socket: SocketType, path: string) => { + return eventChannel((emitter: (data: any) => void) => { + const socketSubscription: SocketSubscriptionType = socket.subscribe(path, (event: SocketEventType) => { emitter(JSON.parse(event.body)); }); return () => socketSubscription.unsubscribe(); |