diff options
author | Joffrey BION <joffrey.bion@gmail.com> | 2017-05-13 22:18:56 +0200 |
---|---|---|
committer | Joffrey BION <joffrey.bion@gmail.com> | 2017-05-13 22:18:56 +0200 |
commit | e7606b72118f71097a0a7f75fb735750f905c24a (patch) | |
tree | 6cf01487cf2c669e6231c2c16ea3d50093319b0b /frontend/src/sagas | |
parent | Fix getPlayers that in fact takes an immutable List instead of JS array (diff) | |
download | seven-wonders-e7606b72118f71097a0a7f75fb735750f905c24a.tar.gz seven-wonders-e7606b72118f71097a0a7f75fb735750f905c24a.tar.bz2 seven-wonders-e7606b72118f71097a0a7f75fb735750f905c24a.zip |
Migrate to seamless immutable
Resolves:
https://github.com/luxons/seven-wonders/issues/6
Diffstat (limited to 'frontend/src/sagas')
-rw-r--r-- | frontend/src/sagas/errors.js | 23 | ||||
-rw-r--r-- | frontend/src/sagas/gameBrowser.js | 33 | ||||
-rw-r--r-- | frontend/src/sagas/home.js | 29 | ||||
-rw-r--r-- | frontend/src/sagas/usernameChoice.js | 41 |
4 files changed, 66 insertions, 60 deletions
diff --git a/frontend/src/sagas/errors.js b/frontend/src/sagas/errors.js new file mode 100644 index 00000000..6d4df93d --- /dev/null +++ b/frontend/src/sagas/errors.js @@ -0,0 +1,23 @@ +import { apply, call, cancelled, put, take } from 'redux-saga/effects' + +import { createSubscriptionChannel } from '../utils/websocket' +import { actions } from '../redux/errors' + +export default function *errorHandlingSaga({ socket }) { + const errorChannel = yield call(createSubscriptionChannel, socket, '/user/queue/error') + try { + while (true) { + const error = yield take(errorChannel) + yield* handleOneError(error) + } + } finally { + if (yield cancelled()) { + yield apply(errorChannel, errorChannel.close) + } + } +} + +function *handleOneError(error) { + console.error("Error received on web socket channel", error) + yield put(actions.errorReceived(error)) +} diff --git a/frontend/src/sagas/gameBrowser.js b/frontend/src/sagas/gameBrowser.js index 596da428..4f3309c3 100644 --- a/frontend/src/sagas/gameBrowser.js +++ b/frontend/src/sagas/gameBrowser.js @@ -1,6 +1,5 @@ import { call, put, take, apply } from 'redux-saga/effects' -import { eventChannel} from 'redux-saga' -import { fromJS } from 'immutable' +import { eventChannel } from 'redux-saga' import { push } from 'react-router-redux' import { normalize } from 'normalizr' @@ -14,7 +13,7 @@ function gameBrowserChannel(socket) { const makeHandler = type => event => { const response = JSON.parse(event.body) - emit({ type, response }) + emit({type, response}) } const newGame = socket.subscribe('/topic/games', makeHandler(types.UPDATE_GAMES)) @@ -27,22 +26,22 @@ function gameBrowserChannel(socket) { }) } -export function *watchGames({ socket }) { +export function *watchGames({socket}) { const socketChannel = gameBrowserChannel(socket) try { while (true) { - const { type, response } = yield take(socketChannel) + const {type, response} = yield take(socketChannel) switch (type) { case types.UPDATE_GAMES: const normGameList = normalize(response, gameList) - yield put(playerActions.updatePlayers(fromJS(normGameList.entities.players))) - yield put(gameActions.updateGames(fromJS(normGameList.entities.games))) + yield put(playerActions.updatePlayers(normGameList.entities.players || {})) + yield put(gameActions.updateGames(normGameList.entities.games || {})) break case types.ENTER_LOBBY: const normGame = normalize(response, game) - yield put(gameActions.enterLobby(fromJS(normGame.entities.games[normGame.result]))) + yield put(gameActions.enterLobby(normGame.entities.games[normGame.result])) socketChannel.close() yield put(push('/lobby')) break @@ -55,24 +54,20 @@ export function *watchGames({ socket }) { } } -export function *createGame({ socket }) { - const { name } = yield take(types.REQUEST_CREATE_GAME) +export function *createGame({socket}) { + const {gameName} = yield take(types.REQUEST_CREATE_GAME) - yield apply(socket, socket.send, ["/app/lobby/create", JSON.stringify({ gameName: name }), {}]) + yield apply(socket, socket.send, ['/app/lobby/create', JSON.stringify({gameName}), {}]) } -export function *joinGame({ socket }) { - const { id } = yield take(types.REQUEST_JOIN_GAME) +export function *joinGame({socket}) { + const {gameId} = yield take(types.REQUEST_JOIN_GAME) - yield apply(socket, socket.send, ["/app/lobby/join", JSON.stringify({ gameId: id }), {}]) + yield apply(socket, socket.send, ['/app/lobby/join', JSON.stringify({gameId}), {}]) } export function *gameBrowserSaga(socketConnection) { - yield [ - call(watchGames, socketConnection), - call(createGame, socketConnection), - call(joinGame, socketConnection) - ] + yield [call(watchGames, socketConnection), call(createGame, socketConnection), call(joinGame, socketConnection)] } export default gameBrowserSaga diff --git a/frontend/src/sagas/home.js b/frontend/src/sagas/home.js new file mode 100644 index 00000000..99e6f954 --- /dev/null +++ b/frontend/src/sagas/home.js @@ -0,0 +1,29 @@ +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' + +function *sendUsername({ socket }) { + 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')) +} + +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), + ] +} + +export default usernameChoiceSaga diff --git a/frontend/src/sagas/usernameChoice.js b/frontend/src/sagas/usernameChoice.js deleted file mode 100644 index ad5b5341..00000000 --- a/frontend/src/sagas/usernameChoice.js +++ /dev/null @@ -1,41 +0,0 @@ -import { call, take, put } from 'redux-saga/effects' -import { eventChannel } from 'redux-saga' -import { push } from 'react-router-redux' -import { fromJS } from 'immutable' - -import { actions, types } from '../redux/players' - -function usernameValidationChannel(socket) { - return eventChannel(emitter => { - const receiveUsernameHandler = socket.subscribe('/user/queue/nameChoice', event => { - emitter(fromJS(JSON.parse(event.body))) - }) - return () => receiveUsernameHandler.unsubscribe() - }) -} - -function *usernameValidation({ socket }) { - const usernameChannel = yield call(usernameValidationChannel, socket) - const user = yield take(usernameChannel) - yield put(actions.setCurrentPlayer(user)) - usernameChannel.close() - yield put(push('/games')) -} - -function *sendUsername({ socket }) { - const { username } = yield take(types.REQUEST_CHOOSE_USERNAME) - - yield socket.send('/app/chooseName', JSON.stringify({ - playerName: username - })) -} - -function *usernameChoiceSaga(wsConnection) { - // TODO: Run sendUsername in loop when we have the ability to cancel saga on route change - yield [ - call(sendUsername, wsConnection), - call(usernameValidation, wsConnection), - ] -} - -export default usernameChoiceSaga |