summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontend/package.json2
-rw-r--r--frontend/public/index.html1
-rw-r--r--frontend/src/components/errors/errorToast9
-rw-r--r--frontend/src/components/gameList.js1
-rw-r--r--frontend/src/layouts/HomeLayout.js10
-rw-r--r--frontend/src/layouts/LobbyLayout.js10
-rw-r--r--frontend/src/reducers.js2
-rw-r--r--frontend/src/redux/errors.js20
-rw-r--r--frontend/src/sagas/errors.js20
-rw-r--r--frontend/src/sagas/gameBrowser.js16
-rw-r--r--frontend/src/sagas/home.js17
-rw-r--r--frontend/yarn.lock40
12 files changed, 94 insertions, 54 deletions
diff --git a/frontend/package.json b/frontend/package.json
index 49fe9cc6..6c129927 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -11,9 +11,9 @@
"react": "latest",
"react-dom": "latest",
"react-redux": "latest",
+ "react-redux-toastr": "latest",
"react-router": "^3.0.2",
"react-router-redux": "latest",
- "react-toastify": "latest",
"rebass": "latest",
"redux": "latest",
"redux-saga": "latest",
diff --git a/frontend/public/index.html b/frontend/public/index.html
index aab5e3b0..6a375403 100644
--- a/frontend/public/index.html
+++ b/frontend/public/index.html
@@ -4,6 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
+ <link href="http://diegoddox.github.io/react-redux-toastr/5.0/react-redux-toastr.min.css" rel="stylesheet" type="text/css">
<!--
Notice the use of %PUBLIC_URL% in the tag above.
It will be replaced with the URL of the `public` folder during the build.
diff --git a/frontend/src/components/errors/errorToast b/frontend/src/components/errors/errorToast
new file mode 100644
index 00000000..39020088
--- /dev/null
+++ b/frontend/src/components/errors/errorToast
@@ -0,0 +1,9 @@
+import React from 'react'
+
+const MyToastContent = (props) => (
+ <div>
+ <span>{props.myContent.message}</span>
+ </div>
+)
+
+export default MyToastContent
diff --git a/frontend/src/components/gameList.js b/frontend/src/components/gameList.js
index f49a7589..b4167927 100644
--- a/frontend/src/components/gameList.js
+++ b/frontend/src/components/gameList.js
@@ -6,7 +6,6 @@ import Immutable from 'seamless-immutable'
const GameList = (props) => (
<div>
{Immutable.asMutable(props.games).map((game, index) => {
-
const joinGame = () => props.joinGame(game.id)
return (<Flex key={index}>
diff --git a/frontend/src/layouts/HomeLayout.js b/frontend/src/layouts/HomeLayout.js
index 4b93a163..76236383 100644
--- a/frontend/src/layouts/HomeLayout.js
+++ b/frontend/src/layouts/HomeLayout.js
@@ -1,9 +1,8 @@
import React from 'react'
-import {
- Banner
-} from 'rebass'
+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>
@@ -11,5 +10,10 @@ export default (props) => (
<img src={logo} alt="Seven Wonders"/>
{props.children}
</Banner>
+ <ReduxToastr
+ timeOut={4000}
+ preventDuplicates
+ position="bottom-left"
+ progressBar/>
</div>
)
diff --git a/frontend/src/layouts/LobbyLayout.js b/frontend/src/layouts/LobbyLayout.js
index 83c210a1..dba3d589 100644
--- a/frontend/src/layouts/LobbyLayout.js
+++ b/frontend/src/layouts/LobbyLayout.js
@@ -1,8 +1,7 @@
import React from 'react'
-import {
- Banner,
-} from 'rebass'
+import { Banner } from 'rebass'
import logo from './logo-7-wonders.png'
+import ReduxToastr from 'react-redux-toastr'
export default (props) => (
<div>
@@ -14,5 +13,10 @@ export default (props) => (
<img src={logo} alt="Seven Wonders Logo"/>
</Banner>
{props.children}
+ <ReduxToastr
+ timeOut={4000}
+ preventDuplicates
+ position="bottom-left"
+ progressBar/>
</div>
)
diff --git a/frontend/src/reducers.js b/frontend/src/reducers.js
index 7e5fba26..f5063ac1 100644
--- a/frontend/src/reducers.js
+++ b/frontend/src/reducers.js
@@ -1,4 +1,5 @@
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'
@@ -10,5 +11,6 @@ export default function createReducer() {
games: gamesReducer,
players: playersReducer,
routing: routerReducer,
+ toastr: toastrReducer
})
}
diff --git a/frontend/src/redux/errors.js b/frontend/src/redux/errors.js
index 1c247955..7d113db1 100644
--- a/frontend/src/redux/errors.js
+++ b/frontend/src/redux/errors.js
@@ -8,16 +8,30 @@ export const actions = {
errorReceived: (error) => ({
type: types.ERROR_RECEIVED_ON_WS,
error
- })
+ }),
}
-const initialState = Immutable.from([])
+const initialState = Immutable.from({
+ nextId: 0,
+ history: []
+})
export default (state = initialState, action) => {
switch (action.type) {
case types.ERROR_RECEIVED_ON_WS:
- return state.concat([ action.error ])
+ 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:
return state
}
}
+
+function addErrorToHistory(state, error) {
+ return addToArray(state, 'history', error);
+}
+
+function addToArray(state, arrayKey, element) {
+ return state.set(arrayKey, state[arrayKey].concat([ element ]));
+}
diff --git a/frontend/src/sagas/errors.js b/frontend/src/sagas/errors.js
index 441f3fb5..9808fe41 100644
--- a/frontend/src/sagas/errors.js
+++ b/frontend/src/sagas/errors.js
@@ -1,8 +1,11 @@
+import React from 'react'
import { apply, call, cancelled, put, take } from 'redux-saga/effects'
import { createSubscriptionChannel } from '../utils/websocket'
import { actions } from '../redux/errors'
+import {toastr} from 'react-redux-toastr'
+
export default function *errorHandlingSaga({ socket }) {
const errorChannel = yield call(createSubscriptionChannel, socket, '/user/queue/errors')
try {
@@ -12,12 +15,23 @@ export default function *errorHandlingSaga({ socket }) {
}
} finally {
if (yield cancelled()) {
+ console.log('Error management saga cancelled')
yield apply(errorChannel, errorChannel.close)
}
}
}
-function *handleOneError(error) {
- console.error("Error received on web socket channel", error)
- yield put(actions.errorReceived(error))
+function *handleOneError(err) {
+ console.error("Error received on web socket channel", err)
+ const msg = buildMsg(err)
+ 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')
+ } else {
+ return err.message
+ }
}
diff --git a/frontend/src/sagas/gameBrowser.js b/frontend/src/sagas/gameBrowser.js
index 10d6ec1d..b12587ef 100644
--- a/frontend/src/sagas/gameBrowser.js
+++ b/frontend/src/sagas/gameBrowser.js
@@ -3,7 +3,7 @@ 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 { game as gameSchema, gameList as gameListSchema } from '../schemas/games'
import { actions as gameActions, types } from '../redux/games'
import { actions as playerActions } from '../redux/players'
@@ -39,15 +39,17 @@ function *watchLobbyJoined({socket}) {
}
function *createGame({socket}) {
- const {gameName} = yield take(types.REQUEST_CREATE_GAME)
-
- yield apply(socket, socket.send, ['/app/lobby/create', JSON.stringify({gameName}), {}])
+ while (true) {
+ const {gameName} = yield take(types.REQUEST_CREATE_GAME)
+ yield apply(socket, socket.send, ['/app/lobby/create', JSON.stringify({gameName}), {}])
+ }
}
function *joinGame({socket}) {
- const {gameId} = yield take(types.REQUEST_JOIN_GAME)
-
- yield apply(socket, socket.send, ['/app/lobby/join', JSON.stringify({gameId}), {}])
+ while (true) {
+ const {gameId} = yield take(types.REQUEST_JOIN_GAME)
+ yield apply(socket, socket.send, ['/app/lobby/join', JSON.stringify({gameId}), {}])
+ }
}
function *gameBrowserSaga(socketConnection) {
diff --git a/frontend/src/sagas/home.js b/frontend/src/sagas/home.js
index 99e6f954..151fcb57 100644
--- a/frontend/src/sagas/home.js
+++ b/frontend/src/sagas/home.js
@@ -5,17 +5,20 @@ import { push } from 'react-router-redux'
import { actions, types } from '../redux/players'
function *sendUsername({ socket }) {
- const {username} = yield take(types.REQUEST_CHOOSE_USERNAME)
-
- yield apply(socket, socket.send, ['/app/chooseName', JSON.stringify({ playerName: username })])
+ while (true) {
+ const {username} = yield take(types.REQUEST_CHOOSE_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 user = yield take(usernameChannel)
- yield put(actions.setCurrentPlayer(user))
- yield apply(usernameChannel, usernameChannel.close)
- yield put(push('/games'))
+ while (true) {
+ const user = yield take(usernameChannel)
+ yield put(actions.setCurrentPlayer(user))
+ yield apply(usernameChannel, usernameChannel.close)
+ yield put(push('/games'))
+ }
}
function *usernameChoiceSaga(wsConnection) {
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 545eb202..fd465aac 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -1065,10 +1065,6 @@ center-align@^0.1.1:
align-text "^0.1.3"
lazy-cache "^1.0.3"
-chain-function@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc"
-
chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -1591,10 +1587,6 @@ dom-converter@~0.1:
dependencies:
utila "~0.3"
-dom-helpers@^3.2.0:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a"
-
dom-serializer@0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
@@ -1939,6 +1931,10 @@ eventemitter3@1.x.x:
version "1.2.0"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508"
+eventemitter3@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba"
+
events@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
@@ -2379,7 +2375,7 @@ history@^3.0.0:
query-string "^4.2.2"
warning "^3.0.0"
-history@^4.3.0, history@latest:
+history@^4.3.0:
version "4.6.1"
resolved "https://registry.yarnpkg.com/history/-/history-4.6.1.tgz#911cf8eb65728555a94f2b12780a0c531a14d2fd"
dependencies:
@@ -4092,7 +4088,7 @@ promise@7.1.1, promise@^7.1.1:
dependencies:
asap "~2.0.3"
-prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@~15.5.7:
+prop-types@^15.5.6, prop-types@^15.5.7, prop-types@~15.5.7:
version "15.5.10"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
dependencies:
@@ -4211,6 +4207,14 @@ react-redux:
lodash-es "^4.2.0"
loose-envify "^1.1.0"
+react-redux-toastr@latest:
+ version "6.2.6"
+ resolved "https://registry.yarnpkg.com/react-redux-toastr/-/react-redux-toastr-6.2.6.tgz#d02166bb9f172fa383bc9d59cf6c25308fe5735b"
+ dependencies:
+ classnames "^2.2.3"
+ eventemitter3 "^2.0.3"
+ prop-types "^15.5.7"
+
react-router-redux@^4.0.0, react-router-redux@latest:
version "4.0.8"
resolved "https://registry.yarnpkg.com/react-router-redux/-/react-router-redux-4.0.8.tgz#227403596b5151e182377dab835b5d45f0f8054e"
@@ -4272,22 +4276,6 @@ react-scripts@latest:
optionalDependencies:
fsevents "1.0.17"
-react-toastify@latest:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-1.5.0.tgz#e9857e0b5d640064e5ba6caf7a96bb1578273de7"
- dependencies:
- prop-types "^15.5.8"
- react-transition-group "^1.1.2"
-
-react-transition-group@^1.1.2:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.1.3.tgz#5e02cf6e44a863314ff3c68a0c826c2d9d70b221"
- dependencies:
- chain-function "^1.0.0"
- dom-helpers "^3.2.0"
- prop-types "^15.5.6"
- warning "^3.0.0"
-
react@latest:
version "15.5.4"
resolved "https://registry.yarnpkg.com/react/-/react-15.5.4.tgz#fa83eb01506ab237cdc1c8c3b1cea8de012bf047"
bgstack15