diff options
25 files changed, 196 insertions, 280 deletions
diff --git a/frontend/package.json b/frontend/package.json index 4c10e520..fc082b18 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -32,7 +32,7 @@ "test": "react-scripts test --env=jsdom", "test:oneshot": "set CI=true && react-scripts test --env=jsdom", "eject": "react-scripts eject", - "prettier": "prettier --write '{src,__{tests,mocks}__}/**/*.js'" + "prettier": "prettier --single-quote --trailing-comma es5 --print-width 120 --write '{src,__{tests,mocks}__}/**/*.js'" }, "eslintConfig": { "extends": "react-app" diff --git a/frontend/src/components/errors/Error404.js b/frontend/src/components/errors/Error404.js index bf12453d..32ab8e8d 100644 --- a/frontend/src/components/errors/Error404.js +++ b/frontend/src/components/errors/Error404.js @@ -1,5 +1,5 @@ -import React from "react"; -import { Link } from "react-router"; +import React from 'react'; +import { Link } from 'react-router'; const Error404 = () => ( <div> diff --git a/frontend/src/components/gameList.js b/frontend/src/components/gameList.js index e1d011e1..f3a0d381 100644 --- a/frontend/src/components/gameList.js +++ b/frontend/src/components/gameList.js @@ -1,7 +1,7 @@ -import React from "react"; -import { Flex } from "reflexbox"; -import { Text, Space, Button } from "rebass"; -import Immutable from "seamless-immutable"; +import React from 'react'; +import { Flex } from 'reflexbox'; +import { Text, Space, Button } from 'rebass'; +import Immutable from 'seamless-immutable'; const GameList = props => ( <div> diff --git a/frontend/src/components/modals/username.js b/frontend/src/components/modals/username.js index 826bce85..c00262a7 100644 --- a/frontend/src/components/modals/username.js +++ b/frontend/src/components/modals/username.js @@ -1,37 +1,18 @@ -import React from "react"; -import { - Overlay, - Panel, - PanelHeader, - PanelFooter, - Button, - Input, - Close, - Space -} from "rebass"; +import React from 'react'; +import { Overlay, Panel, PanelHeader, PanelFooter, Button, Input, Close, Space } from 'rebass'; const Modal = ({ modalOpen, toggleModal }) => ( - <Overlay open={modalOpen} onDismiss={toggleModal("usernameModal")}> + <Overlay open={modalOpen} onDismiss={toggleModal('usernameModal')}> <Panel theme="info"> <PanelHeader> What's your username ? <Space auto /> - <Close onClick={toggleModal("usernameModal")} /> + <Close onClick={toggleModal('usernameModal')} /> </PanelHeader> - <Input - label="Username" - name="username" - placeholder="Cesar92" - rounded - type="text" - /> + <Input label="Username" name="username" placeholder="Cesar92" rounded type="text" /> <PanelFooter> <Space auto /> - <Button - theme="success" - onClick={toggleModal("usernameModal")} - children="Ok" - /> + <Button theme="success" onClick={toggleModal('usernameModal')} children="Ok" /> </PanelFooter> </Panel> </Overlay> diff --git a/frontend/src/components/playerList.js b/frontend/src/components/playerList.js index b7f6e7c3..1a68b067 100644 --- a/frontend/src/components/playerList.js +++ b/frontend/src/components/playerList.js @@ -1,7 +1,7 @@ -import React from "react"; -import { Flex } from "reflexbox"; -import { Text } from "rebass"; -import Immutable from "seamless-immutable"; +import React from 'react'; +import { Flex } from 'reflexbox'; +import { Text } from 'rebass'; +import Immutable from 'seamless-immutable'; const PlayerList = props => ( <div> diff --git a/frontend/src/containers/gameBrowser.js b/frontend/src/containers/gameBrowser.js index d9d3d363..643dbebc 100644 --- a/frontend/src/containers/gameBrowser.js +++ b/frontend/src/containers/gameBrowser.js @@ -1,11 +1,11 @@ -import React, { Component } from "react"; -import { connect } from "react-redux"; -import { Space, InlineForm, Text } from "rebass"; -import { Flex } from "reflexbox"; -import GameList from "../components/gameList"; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { Space, InlineForm, Text } from 'rebass'; +import { Flex } from 'reflexbox'; +import GameList from '../components/gameList'; -import { getCurrentPlayer } from "../redux/players"; -import { getAllGames, actions } from "../redux/games"; +import { getCurrentPlayer } from '../redux/players'; +import { getAllGames, actions } from '../redux/games'; class GameBrowser extends Component { createGame = e => { @@ -29,7 +29,7 @@ class GameBrowser extends Component { <Space auto /> <Text> <b>Username:</b> - {" "} + {' '} {this.props.currentPlayer && this.props.currentPlayer.displayName} </Text> <Space x={1} /> @@ -41,13 +41,13 @@ class GameBrowser extends Component { } const mapStateToProps = state => ({ - currentPlayer: getCurrentPlayer(state) || { displayName: "[ERROR]" }, - games: getAllGames(state) + currentPlayer: getCurrentPlayer(state) || { displayName: '[ERROR]' }, + games: getAllGames(state), }); const mapDispatchToProps = { createGame: actions.requestCreateGame, - joinGame: actions.requestJoinGame + joinGame: actions.requestJoinGame, }; export default connect(mapStateToProps, mapDispatchToProps)(GameBrowser); diff --git a/frontend/src/containers/home.js b/frontend/src/containers/home.js index 40c2efb3..f60c1c52 100644 --- a/frontend/src/containers/home.js +++ b/frontend/src/containers/home.js @@ -1,7 +1,7 @@ -import React, { Component } from "react"; -import { connect } from "react-redux"; -import { Button, Container, Input } from "rebass"; -import { actions } from "../redux/players"; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { Button, Container, Input } from 'rebass'; +import { actions } from '../redux/players'; class HomePage extends Component { play = e => { @@ -32,7 +32,7 @@ class HomePage extends Component { const mapStateToProps = state => ({}); const mapDispatchToProps = { - chooseUsername: actions.chooseUsername + chooseUsername: actions.chooseUsername, }; export default connect(mapStateToProps, mapDispatchToProps)(HomePage); diff --git a/frontend/src/containers/lobby.js b/frontend/src/containers/lobby.js index 8c3e5e4c..f3489db4 100644 --- a/frontend/src/containers/lobby.js +++ b/frontend/src/containers/lobby.js @@ -1,16 +1,16 @@ -import React, { Component } from "react"; -import { connect } from "react-redux"; -import Immutable from "seamless-immutable"; -import { Button } from "rebass"; -import PlayerList from "../components/playerList"; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import Immutable from 'seamless-immutable'; +import { Button } from 'rebass'; +import PlayerList from '../components/playerList'; -import { getPlayers } from "../redux/players"; -import { getCurrentGame, actions } from "../redux/games"; +import { getPlayers } from '../redux/players'; +import { getCurrentGame, actions } from '../redux/games'; class Lobby extends Component { getTitle() { if (this.props.currentGame) { - return this.props.currentGame.name + " — Lobby"; + return this.props.currentGame.name + ' — Lobby'; } else { return "What are you doing here? You haven't joined a game yet!"; } @@ -31,12 +31,12 @@ const mapStateToProps = state => { const game = getCurrentGame(state); return { currentGame: game, - players: game ? getPlayers(state, game.players) : Immutable([]) + players: game ? getPlayers(state, game.players) : Immutable([]), }; }; const mapDispatchToProps = { - startGame: actions.requestStartGame + startGame: actions.requestStartGame, }; export default connect(mapStateToProps, mapDispatchToProps)(Lobby); diff --git a/frontend/src/index.js b/frontend/src/index.js index 5fd52c01..a627dd07 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -1,13 +1,13 @@ -import "babel-polyfill"; -import "./global-styles.css"; +import 'babel-polyfill'; +import './global-styles.css'; -import React from "react"; -import ReactDOM from "react-dom"; -import { Router } from "react-router"; -import { Provider } from "react-redux"; +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Router } from 'react-router'; +import { Provider } from 'react-redux'; -import configureStore from "./store"; -import { routes } from "./routes"; +import configureStore from './store'; +import { routes } from './routes'; const initialState = {}; const { store, history } = configureStore(initialState); @@ -16,5 +16,5 @@ ReactDOM.render( <Provider store={store}> <Router history={history} routes={routes} /> </Provider>, - document.getElementById("root") + document.getElementById('root') ); diff --git a/frontend/src/layouts/HomeLayout.js b/frontend/src/layouts/HomeLayout.js index 77231c77..87462adb 100644 --- a/frontend/src/layouts/HomeLayout.js +++ b/frontend/src/layouts/HomeLayout.js @@ -1,8 +1,8 @@ -import React from "react"; -import { Banner } from "rebass"; -import logo from "./logo-7-wonders.png"; -import background from "./background-zeus-temple.jpg"; -import ReduxToastr from "react-redux-toastr"; +import React from 'react'; +import { Banner } from 'rebass'; +import logo from './logo-7-wonders.png'; +import background from './background-zeus-temple.jpg'; +import ReduxToastr from 'react-redux-toastr'; export default props => ( <div> @@ -10,11 +10,6 @@ export default props => ( <img src={logo} alt="Seven Wonders" /> {props.children} </Banner> - <ReduxToastr - timeOut={4000} - preventDuplicates - position="bottom-left" - progressBar - /> + <ReduxToastr timeOut={4000} preventDuplicates position="bottom-left" progressBar /> </div> ); diff --git a/frontend/src/layouts/LobbyLayout.js b/frontend/src/layouts/LobbyLayout.js index 84d3998f..effdfebb 100644 --- a/frontend/src/layouts/LobbyLayout.js +++ b/frontend/src/layouts/LobbyLayout.js @@ -1,23 +1,18 @@ -import React from "react"; -import { Banner } from "rebass"; -import logo from "./logo-7-wonders.png"; -import ReduxToastr from "react-redux-toastr"; +import React from 'react'; +import { Banner } from 'rebass'; +import logo from './logo-7-wonders.png'; +import ReduxToastr from 'react-redux-toastr'; export default props => ( <div> <Banner align="center" - style={{ minHeight: "30vh", marginBottom: 0 }} + style={{ minHeight: '30vh', marginBottom: 0 }} backgroundImage="https://images.unsplash.com/photo-1431207446535-a9296cf995b1?dpr=1&auto=format&fit=crop&w=1199&h=799&q=80&cs=tinysrgb&crop=" > <img src={logo} alt="Seven Wonders Logo" /> </Banner> {props.children} - <ReduxToastr - timeOut={4000} - preventDuplicates - position="bottom-left" - progressBar - /> + <ReduxToastr timeOut={4000} preventDuplicates position="bottom-left" progressBar /> </div> ); diff --git a/frontend/src/layouts/index.js b/frontend/src/layouts/index.js index f09b2a20..1db9db61 100644 --- a/frontend/src/layouts/index.js +++ b/frontend/src/layouts/index.js @@ -1,2 +1,2 @@ -export { default as HomeLayout } from "./HomeLayout"; -export { default as LobbyLayout } from "./LobbyLayout"; +export { default as HomeLayout } from './HomeLayout'; +export { default as LobbyLayout } from './LobbyLayout'; diff --git a/frontend/src/reducers.js b/frontend/src/reducers.js index a5d4a9fd..a7bba09a 100644 --- a/frontend/src/reducers.js +++ b/frontend/src/reducers.js @@ -1,9 +1,9 @@ -import { combineReducers, routerReducer } from "redux-seamless-immutable"; -import { reducer as toastrReducer } from "react-redux-toastr"; +import { combineReducers, routerReducer } from 'redux-seamless-immutable'; +import { reducer as toastrReducer } from 'react-redux-toastr'; -import errorsReducer from "./redux/errors"; -import gamesReducer from "./redux/games"; -import playersReducer from "./redux/players"; +import errorsReducer from './redux/errors'; +import gamesReducer from './redux/games'; +import playersReducer from './redux/players'; export default function createReducer() { return combineReducers({ @@ -11,6 +11,6 @@ export default function createReducer() { games: gamesReducer, players: playersReducer, routing: routerReducer, - toastr: toastrReducer + toastr: toastrReducer, }); } diff --git a/frontend/src/redux/errors.js b/frontend/src/redux/errors.js index eb807fdc..ec1e30b6 100644 --- a/frontend/src/redux/errors.js +++ b/frontend/src/redux/errors.js @@ -1,29 +1,26 @@ -import Immutable from "seamless-immutable"; +import Immutable from 'seamless-immutable'; export const types = { - ERROR_RECEIVED_ON_WS: "ERROR/RECEIVED_ON_WS" + ERROR_RECEIVED_ON_WS: 'ERROR/RECEIVED_ON_WS', }; export const actions = { errorReceived: error => ({ type: types.ERROR_RECEIVED_ON_WS, - error - }) + error, + }), }; const initialState = Immutable.from({ nextId: 0, - history: [] + history: [], }); export default (state = initialState, action) => { switch (action.type) { case types.ERROR_RECEIVED_ON_WS: - let error = Object.assign( - { id: state.nextId, timestamp: new Date() }, - action.error - ); - let newState = state.set("nextId", state.nextId + 1); + let error = Object.assign({ id: state.nextId, timestamp: new Date() }, action.error); + let newState = state.set('nextId', state.nextId + 1); newState = addErrorToHistory(newState, error); return newState; default: @@ -32,7 +29,7 @@ export default (state = initialState, action) => { }; function addErrorToHistory(state, error) { - return addToArray(state, "history", error); + return addToArray(state, 'history', error); } function addToArray(state, arrayKey, element) { diff --git a/frontend/src/redux/games.js b/frontend/src/redux/games.js index a7115dcc..9ef0e7cd 100644 --- a/frontend/src/redux/games.js +++ b/frontend/src/redux/games.js @@ -1,12 +1,12 @@ -import Immutable from "seamless-immutable"; +import Immutable from 'seamless-immutable'; export const types = { - UPDATE_GAMES: "GAME/UPDATE_GAMES", - REQUEST_CREATE_GAME: "GAME/REQUEST_CREATE_GAME", - REQUEST_JOIN_GAME: "GAME/REQUEST_JOIN_GAME", - REQUEST_START_GAME: "GAME/REQUEST_JOIN_GAME", - ENTER_LOBBY: "GAME/ENTER_LOBBY", - ENTER_GAME: "GAME/ENTER_GAME" + UPDATE_GAMES: 'GAME/UPDATE_GAMES', + REQUEST_CREATE_GAME: 'GAME/REQUEST_CREATE_GAME', + REQUEST_JOIN_GAME: 'GAME/REQUEST_JOIN_GAME', + REQUEST_START_GAME: 'GAME/REQUEST_JOIN_GAME', + ENTER_LOBBY: 'GAME/ENTER_LOBBY', + ENTER_GAME: 'GAME/ENTER_GAME', }; export const actions = { @@ -14,16 +14,16 @@ export const actions = { requestJoinGame: gameId => ({ type: types.REQUEST_JOIN_GAME, gameId }), requestCreateGame: gameName => ({ type: types.REQUEST_CREATE_GAME, - gameName + gameName, }), requestStartGame: () => ({ type: types.REQUEST_START_GAME }), enterLobby: lobby => ({ type: types.ENTER_LOBBY, lobby: Immutable(lobby) }), - enterGame: () => ({ type: types.ENTER_GAME }) + enterGame: () => ({ type: types.ENTER_GAME }), }; const initialState = Immutable.from({ all: {}, - current: "" + current: '', }); export default (state = initialState, action) => { @@ -31,7 +31,7 @@ export default (state = initialState, action) => { case types.UPDATE_GAMES: return Immutable.merge(state, { all: action.games }, { deep: true }); case types.ENTER_LOBBY: - return state.set("current", action.lobby.id); + return state.set('current', action.lobby.id); default: return state; } diff --git a/frontend/src/redux/players.js b/frontend/src/redux/players.js index 4016076f..b11e920f 100644 --- a/frontend/src/redux/players.js +++ b/frontend/src/redux/players.js @@ -1,37 +1,37 @@ -import Immutable from "seamless-immutable"; +import Immutable from 'seamless-immutable'; export const types = { - REQUEST_CHOOSE_USERNAME: "USER/REQUEST_CHOOSE_USERNAME", - SET_CURRENT_PLAYER: "USER/SET_CURRENT_PLAYER", - UPDATE_PLAYERS: "USER/UPDATE_PLAYERS" + REQUEST_CHOOSE_USERNAME: 'USER/REQUEST_CHOOSE_USERNAME', + SET_CURRENT_PLAYER: 'USER/SET_CURRENT_PLAYER', + UPDATE_PLAYERS: 'USER/UPDATE_PLAYERS', }; export const actions = { chooseUsername: username => ({ type: types.REQUEST_CHOOSE_USERNAME, - username + username, }), setCurrentPlayer: player => ({ type: types.SET_CURRENT_PLAYER, - player + player, }), updatePlayers: players => ({ type: types.UPDATE_PLAYERS, - players - }) + players, + }), }; const initialState = Immutable.from({ all: {}, - current: "" + current: '', }); export default (state = initialState, action) => { switch (action.type) { case types.SET_CURRENT_PLAYER: const player = action.player; - const withNewPlayer = state.setIn(["all", player.username], player); - return Immutable.set(withNewPlayer, "current", player.username); + const withNewPlayer = state.setIn(['all', player.username], player); + return Immutable.set(withNewPlayer, 'current', player.username); case types.UPDATE_PLAYERS: return Immutable.merge(state, { all: action.players }, { deep: true }); default: @@ -39,8 +39,6 @@ export default (state = initialState, action) => { } }; -export const getCurrentPlayer = state => - state.players.all && state.players.all[state.players.current]; +export const getCurrentPlayer = state => state.players.all && state.players.all[state.players.current]; export const getPlayer = (state, username) => state.players.all[username]; -export const getPlayers = (state, usernames) => - usernames.map(u => getPlayer(state, u)); +export const getPlayers = (state, usernames) => usernames.map(u => getPlayer(state, u)); diff --git a/frontend/src/routes.js b/frontend/src/routes.js index e49a7e2c..29894c3a 100644 --- a/frontend/src/routes.js +++ b/frontend/src/routes.js @@ -1,42 +1,39 @@ -import { fork } from "redux-saga/effects"; -import homeSaga from "./sagas/home"; -import gameBrowserSaga from "./sagas/gameBrowser"; -import lobbySaga from "./sagas/lobby"; +import { fork } from 'redux-saga/effects'; +import homeSaga from './sagas/home'; +import gameBrowserSaga from './sagas/gameBrowser'; +import lobbySaga from './sagas/lobby'; -import { HomeLayout, LobbyLayout } from "./layouts"; -import HomePage from "./containers/home"; -import GameBrowser from "./containers/gameBrowser"; -import Lobby from "./containers/lobby"; -import Error404 from "./components/errors/Error404"; +import { HomeLayout, LobbyLayout } from './layouts'; +import HomePage from './containers/home'; +import GameBrowser from './containers/gameBrowser'; +import Lobby from './containers/lobby'; +import Error404 from './components/errors/Error404'; export const makeSagaRoutes = wsConnection => ({ - *"/"() { + *'/'() { yield fork(homeSaga, wsConnection); }, - *"/games"() { + *'/games'() { yield fork(gameBrowserSaga, wsConnection); }, - *"/lobby/*"() { + *'/lobby/*'() { yield fork(lobbySaga, wsConnection); - } + }, }); export const routes = [ { - path: "/", + path: '/', component: HomeLayout, - indexRoute: { component: HomePage } + indexRoute: { component: HomePage }, }, { - path: "/", + path: '/', component: LobbyLayout, - childRoutes: [ - { path: "/games", component: GameBrowser }, - { path: "/lobby/*", component: Lobby } - ] + childRoutes: [{ path: '/games', component: GameBrowser }, { path: '/lobby/*', component: Lobby }], }, { - path: "*", - component: Error404 - } + path: '*', + component: Error404, + }, ]; diff --git a/frontend/src/sagas.js b/frontend/src/sagas.js index ff66453e..a28c7c72 100644 --- a/frontend/src/sagas.js +++ b/frontend/src/sagas.js @@ -1,16 +1,16 @@ -import { router } from "redux-saga-router"; -import { call, fork } from "redux-saga/effects"; +import { router } from 'redux-saga-router'; +import { call, fork } from 'redux-saga/effects'; -import { makeSagaRoutes } from "./routes"; -import { createWsConnection } from "./utils/websocket"; -import errorHandlingSaga from "./sagas/errors"; +import { makeSagaRoutes } from './routes'; +import { createWsConnection } from './utils/websocket'; +import errorHandlingSaga from './sagas/errors'; export default function* rootSaga(history) { let wsConnection; try { wsConnection = yield call(createWsConnection); } catch (error) { - console.error("Could not connect to socket"); + console.error('Could not connect to socket'); return; } yield fork(errorHandlingSaga, wsConnection); diff --git a/frontend/src/sagas/errors.js b/frontend/src/sagas/errors.js index 42994610..41eb6902 100644 --- a/frontend/src/sagas/errors.js +++ b/frontend/src/sagas/errors.js @@ -1,16 +1,12 @@ -import { apply, call, cancelled, put, take } from "redux-saga/effects"; +import { apply, call, cancelled, put, take } from 'redux-saga/effects'; -import { createSubscriptionChannel } from "../utils/websocket"; -import { actions } from "../redux/errors"; +import { createSubscriptionChannel } from '../utils/websocket'; +import { actions } from '../redux/errors'; -import { toastr } from "react-redux-toastr"; +import { toastr } from 'react-redux-toastr'; export default function* errorHandlingSaga({ socket }) { - const errorChannel = yield call( - createSubscriptionChannel, - socket, - "/user/queue/errors" - ); + const errorChannel = yield call(createSubscriptionChannel, socket, '/user/queue/errors'); try { while (true) { const error = yield take(errorChannel); @@ -18,22 +14,22 @@ export default function* errorHandlingSaga({ socket }) { } } finally { if (yield cancelled()) { - console.log("Error management saga cancelled"); + console.log('Error management saga cancelled'); yield apply(errorChannel, errorChannel.close); } } } function* handleOneError(err) { - console.error("Error received on web socket channel", err); + console.error('Error received on web socket channel', err); const msg = buildMsg(err); - yield apply(toastr, toastr.error, [msg, { icon: "error" }]); + yield apply(toastr, toastr.error, [msg, { icon: 'error' }]); yield put(actions.errorReceived(err)); } function buildMsg(err) { if (err.details.length > 0) { - return err.details.map(d => d.message).join("\n"); + return err.details.map(d => d.message).join('\n'); } else { return err.message; } diff --git a/frontend/src/sagas/gameBrowser.js b/frontend/src/sagas/gameBrowser.js index 9f7e1565..5492107a 100644 --- a/frontend/src/sagas/gameBrowser.js +++ b/frontend/src/sagas/gameBrowser.js @@ -1,30 +1,21 @@ -import { call, put, take, apply } from "redux-saga/effects"; -import { createSubscriptionChannel } from "../utils/websocket"; -import { push } from "react-router-redux"; +import { call, put, take, apply } from 'redux-saga/effects'; +import { createSubscriptionChannel } from '../utils/websocket'; +import { push } from 'react-router-redux'; -import { normalize } from "normalizr"; -import { - game as gameSchema, - gameList as gameListSchema -} from "../schemas/games"; +import { normalize } from 'normalizr'; +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"; +import { actions as gameActions, types } from '../redux/games'; +import { actions as playerActions } from '../redux/players'; function* watchGames({ socket }) { - const gamesChannel = yield call( - createSubscriptionChannel, - socket, - "/topic/games" - ); + const gamesChannel = yield call(createSubscriptionChannel, socket, '/topic/games'); try { while (true) { const gameList = yield take(gamesChannel); const normGameList = normalize(gameList, gameListSchema); // for an empty game array, there is no players/games entity maps - yield put( - playerActions.updatePlayers(normGameList.entities.players || {}) - ); + yield put(playerActions.updatePlayers(normGameList.entities.players || {})); yield put(gameActions.updateGames(normGameList.entities.games || {})); } } finally { @@ -33,11 +24,7 @@ function* watchGames({ socket }) { } function* watchLobbyJoined({ socket }) { - const joinedLobbyChannel = yield call( - createSubscriptionChannel, - socket, - "/user/queue/lobby/joined" - ); + const joinedLobbyChannel = yield call(createSubscriptionChannel, socket, '/user/queue/lobby/joined'); try { const joinedLobby = yield take(joinedLobbyChannel); const normalized = normalize(joinedLobby, gameSchema); @@ -54,22 +41,14 @@ function* watchLobbyJoined({ socket }) { function* createGame({ socket }) { while (true) { const { gameName } = yield take(types.REQUEST_CREATE_GAME); - yield apply(socket, socket.send, [ - "/app/lobby/create", - JSON.stringify({ gameName }), - {} - ]); + yield apply(socket, socket.send, ['/app/lobby/create', JSON.stringify({ gameName }), {}]); } } function* joinGame({ socket }) { while (true) { const { gameId } = yield take(types.REQUEST_JOIN_GAME); - yield apply(socket, socket.send, [ - "/app/lobby/join", - JSON.stringify({ gameId }), - {} - ]); + yield apply(socket, socket.send, ['/app/lobby/join', JSON.stringify({ gameId }), {}]); } } @@ -78,7 +57,7 @@ function* gameBrowserSaga(socketConnection) { call(watchGames, socketConnection), call(watchLobbyJoined, socketConnection), call(createGame, socketConnection), - call(joinGame, socketConnection) + call(joinGame, socketConnection), ]; } diff --git a/frontend/src/sagas/home.js b/frontend/src/sagas/home.js index 15f95162..579c7fd6 100644 --- a/frontend/src/sagas/home.js +++ b/frontend/src/sagas/home.js @@ -1,39 +1,29 @@ -import { apply, call, put, take } from "redux-saga/effects"; -import { createSubscriptionChannel } from "../utils/websocket"; -import { push } from "react-router-redux"; +import { apply, call, put, take } from 'redux-saga/effects'; +import { createSubscriptionChannel } from '../utils/websocket'; +import { push } from 'react-router-redux'; -import { actions, types } from "../redux/players"; +import { actions, types } from '../redux/players'; function* sendUsername({ socket }) { while (true) { const { username } = yield take(types.REQUEST_CHOOSE_USERNAME); - yield apply(socket, socket.send, [ - "/app/chooseName", - JSON.stringify({ playerName: username }) - ]); + yield apply(socket, socket.send, ['/app/chooseName', JSON.stringify({ playerName: username })]); } } function* validateUsername({ socket }) { - const usernameChannel = yield call( - createSubscriptionChannel, - socket, - "/user/queue/nameChoice" - ); + const usernameChannel = yield call(createSubscriptionChannel, socket, '/user/queue/nameChoice'); while (true) { const user = yield take(usernameChannel); yield put(actions.setCurrentPlayer(user)); yield apply(usernameChannel, usernameChannel.close); - yield put(push("/games")); + yield put(push('/games')); } } function* usernameChoiceSaga(wsConnection) { // TODO: Run sendUsername in loop when we have the ability to cancel saga on route change - yield [ - call(sendUsername, wsConnection), - call(validateUsername, wsConnection) - ]; + yield [call(sendUsername, wsConnection), call(validateUsername, wsConnection)]; } export default usernameChoiceSaga; diff --git a/frontend/src/sagas/lobby.js b/frontend/src/sagas/lobby.js index f092fdb7..d11511e8 100644 --- a/frontend/src/sagas/lobby.js +++ b/frontend/src/sagas/lobby.js @@ -1,25 +1,21 @@ -import { call, put, take, apply } from "redux-saga/effects"; -import { createSubscriptionChannel } from "../utils/websocket"; -import { push } from "react-router-redux"; +import { call, put, take, apply } from 'redux-saga/effects'; +import { createSubscriptionChannel } from '../utils/websocket'; +import { push } from 'react-router-redux'; -import { normalize } from "normalizr"; -import { game as gameSchema } from "../schemas/games"; +import { normalize } from 'normalizr'; +import { game as gameSchema } from '../schemas/games'; -import { actions as gameActions, types } from "../redux/games"; -import { actions as playerActions } from "../redux/players"; +import { actions as gameActions, types } from '../redux/games'; +import { actions as playerActions } from '../redux/players'; function getCurrentGameId() { const path = window.location.pathname; - return path.split("lobby/")[1]; + return path.split('lobby/')[1]; } function* watchLobbyUpdates({ socket }) { const currentGameId = getCurrentGameId(); - const lobbyUpdatesChannel = yield call( - createSubscriptionChannel, - socket, - `/topic/lobby/${currentGameId}/updated` - ); + const lobbyUpdatesChannel = yield call(createSubscriptionChannel, socket, `/topic/lobby/${currentGameId}/updated`); try { while (true) { const lobby = yield take(lobbyUpdatesChannel); @@ -34,15 +30,11 @@ function* watchLobbyUpdates({ socket }) { function* watchGameStart({ socket }) { const currentGameId = getCurrentGameId(); - const gameStartedChannel = yield call( - createSubscriptionChannel, - socket, - `/topic/lobby/${currentGameId}/started` - ); + const gameStartedChannel = yield call(createSubscriptionChannel, socket, `/topic/lobby/${currentGameId}/started`); try { yield take(gameStartedChannel); yield put(gameActions.enterGame()); - yield put(push("/game")); + yield put(push('/game')); } finally { yield apply(gameStartedChannel, gameStartedChannel.close); } @@ -51,7 +43,7 @@ function* watchGameStart({ socket }) { function* startGame({ socket }) { while (true) { yield take(types.REQUEST_START_GAME); - yield apply(socket, socket.send, ["/app/lobby/startGame", {}]); + yield apply(socket, socket.send, ['/app/lobby/startGame', {}]); } } @@ -59,7 +51,7 @@ function* lobbySaga(socketConnection) { yield [ call(watchLobbyUpdates, socketConnection), call(watchGameStart, socketConnection), - call(startGame, socketConnection) + call(startGame, socketConnection), ]; } diff --git a/frontend/src/schemas/games.js b/frontend/src/schemas/games.js index 9c9681da..68d14fb4 100644 --- a/frontend/src/schemas/games.js +++ b/frontend/src/schemas/games.js @@ -1,15 +1,15 @@ -import { schema } from "normalizr"; +import { schema } from 'normalizr'; const player = new schema.Entity( - "players", + 'players', {}, { - idAttribute: "username" + idAttribute: 'username', } ); -export const game = new schema.Entity("games", { - players: [player] +export const game = new schema.Entity('games', { + players: [player], }); export const gameList = [game]; diff --git a/frontend/src/store.js b/frontend/src/store.js index ef9038eb..4bd22184 100644 --- a/frontend/src/store.js +++ b/frontend/src/store.js @@ -1,12 +1,12 @@ -import { createStore, applyMiddleware, compose } from "redux"; -import { browserHistory } from "react-router"; -import { syncHistoryWithStore, routerMiddleware } from "react-router-redux"; -import Immutable from "seamless-immutable"; +import { createStore, applyMiddleware, compose } from 'redux'; +import { browserHistory } from 'react-router'; +import { syncHistoryWithStore, routerMiddleware } from 'react-router-redux'; +import Immutable from 'seamless-immutable'; -import createReducer from "./reducers"; -import createSagaMiddleware from "redux-saga"; -import rootSaga from "./sagas"; -import { makeSelectLocationState } from "./redux/app"; +import createReducer from './reducers'; +import createSagaMiddleware from 'redux-saga'; +import rootSaga from './sagas'; +import { makeSelectLocationState } from './redux/app'; export default function configureStore(initialState = {}) { const sagaMiddleware = createSagaMiddleware(); @@ -15,24 +15,20 @@ export default function configureStore(initialState = {}) { const enhancers = [applyMiddleware(...middlewares)]; - const composeEnhancers = process.env.NODE_ENV !== "production" && - typeof window === "object" && + const composeEnhancers = process.env.NODE_ENV !== 'production' && + typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose; - const store = createStore( - createReducer(), - Immutable.from(initialState), - composeEnhancers(...enhancers) - ); + const store = createStore(createReducer(), Immutable.from(initialState), composeEnhancers(...enhancers)); sagaMiddleware.run(rootSaga, browserHistory); return { store, history: syncHistoryWithStore(browserHistory, store, { - selectLocationState: makeSelectLocationState() - }) + selectLocationState: makeSelectLocationState(), + }), }; } diff --git a/frontend/src/utils/websocket.js b/frontend/src/utils/websocket.js index 4a07d532..b33b2d50 100644 --- a/frontend/src/utils/websocket.js +++ b/frontend/src/utils/websocket.js @@ -1,13 +1,13 @@ -import SockJS from "sockjs-client"; -import Stomp from "webstomp-client"; -import { eventChannel } from "redux-saga"; +import SockJS from 'sockjs-client'; +import Stomp from 'webstomp-client'; +import { eventChannel } from 'redux-saga'; -const wsURL = "/seven-wonders-websocket"; +const wsURL = '/seven-wonders-websocket'; export const createWsConnection = (headers = {}) => new Promise((resolve, reject) => { let socket = Stomp.over(new SockJS(wsURL), { - debug: process.env.NODE_ENV !== "production" + debug: process.env.NODE_ENV !== 'production', }); socket.connect(headers, frame => resolve({ frame, socket }), reject); }); |