summaryrefslogtreecommitdiff
path: root/frontend/src/sagas
diff options
context:
space:
mode:
authorJoffrey BION <joffrey.bion@gmail.com>2017-05-14 18:43:58 +0200
committerJoffrey BION <joffrey.bion@gmail.com>2017-05-14 18:43:58 +0200
commitb6f54ed56121aa5435dd813c952b292b25b56bfb (patch)
treeb4c88476393b031f00e9a1398f4f2a352f530341 /frontend/src/sagas
parentFix typo in error subscription path (diff)
downloadseven-wonders-b6f54ed56121aa5435dd813c952b292b25b56bfb.tar.gz
seven-wonders-b6f54ed56121aa5435dd813c952b292b25b56bfb.tar.bz2
seven-wonders-b6f54ed56121aa5435dd813c952b292b25b56bfb.zip
Add lobby saga
- Fix lobby's player list updates - Fix lobby's player list order - Add 'start game' button (not restricted to owner yet) Resolves: https://github.com/luxons/seven-wonders/issues/7
Diffstat (limited to 'frontend/src/sagas')
-rw-r--r--frontend/src/sagas/gameBrowser.js77
-rw-r--r--frontend/src/sagas/lobby.js58
2 files changed, 91 insertions, 44 deletions
diff --git a/frontend/src/sagas/gameBrowser.js b/frontend/src/sagas/gameBrowser.js
index 4f3309c3..10d6ec1d 100644
--- a/frontend/src/sagas/gameBrowser.js
+++ b/frontend/src/sagas/gameBrowser.js
@@ -1,73 +1,62 @@
import { call, put, take, apply } from 'redux-saga/effects'
-import { eventChannel } from 'redux-saga'
+import { createSubscriptionChannel } from '../utils/websocket'
import { push } from 'react-router-redux'
import { normalize } from 'normalizr'
-import { game, gameList } 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'
-function gameBrowserChannel(socket) {
- return eventChannel(emit => {
-
- const makeHandler = type => event => {
- const response = JSON.parse(event.body)
- emit({type, response})
- }
-
- const newGame = socket.subscribe('/topic/games', makeHandler(types.UPDATE_GAMES))
- const joinGame = socket.subscribe('/user/queue/lobby/joined', makeHandler(types.ENTER_LOBBY))
-
- return () => {
- newGame.unsubscribe()
- joinGame.unsubscribe()
+function *watchGames({socket}) {
+ 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(gameActions.updateGames(normGameList.entities.games || {}))
}
- })
+ } finally {
+ yield apply(gamesChannel, gamesChannel.close)
+ }
}
-export function *watchGames({socket}) {
- const socketChannel = gameBrowserChannel(socket)
-
+function *watchLobbyJoined({socket}) {
+ const joinedLobbyChannel = yield call(createSubscriptionChannel, socket, '/user/queue/lobby/joined')
try {
- while (true) {
- const {type, response} = yield take(socketChannel)
-
- switch (type) {
- case types.UPDATE_GAMES:
- const normGameList = normalize(response, gameList)
- 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(normGame.entities.games[normGame.result]))
- socketChannel.close()
- yield put(push('/lobby'))
- break
- default:
- console.error('Unknown type')
- }
- }
+ const joinedLobby = yield take(joinedLobbyChannel)
+ const normalized = normalize(joinedLobby, gameSchema)
+ const gameId = normalized.result
+ yield put(playerActions.updatePlayers(normalized.entities.players))
+ yield put(gameActions.updateGames(normalized.entities.games))
+ yield put(gameActions.enterLobby(normalized.entities.games[gameId]))
+ yield put(push(`/lobby/${gameId}`))
} finally {
- console.info('gameBrowserChannel closed')
+ yield apply(joinedLobbyChannel, joinedLobbyChannel.close)
}
}
-export function *createGame({socket}) {
+function *createGame({socket}) {
const {gameName} = yield take(types.REQUEST_CREATE_GAME)
yield apply(socket, socket.send, ['/app/lobby/create', JSON.stringify({gameName}), {}])
}
-export function *joinGame({socket}) {
+function *joinGame({socket}) {
const {gameId} = yield take(types.REQUEST_JOIN_GAME)
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)]
+function *gameBrowserSaga(socketConnection) {
+ yield [
+ call(watchGames, socketConnection),
+ call(watchLobbyJoined, socketConnection),
+ call(createGame, socketConnection),
+ call(joinGame, socketConnection)
+ ]
}
export default gameBrowserSaga
diff --git a/frontend/src/sagas/lobby.js b/frontend/src/sagas/lobby.js
new file mode 100644
index 00000000..f002c897
--- /dev/null
+++ b/frontend/src/sagas/lobby.js
@@ -0,0 +1,58 @@
+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 { 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]
+}
+
+function *watchLobbyUpdates({ socket }) {
+ const currentGameId = getCurrentGameId()
+ const lobbyUpdatesChannel = yield call(createSubscriptionChannel, socket, `/topic/lobby/${currentGameId}/updated`)
+ try {
+ while (true) {
+ const lobby = yield take(lobbyUpdatesChannel)
+ const normalized = normalize(lobby, gameSchema)
+ yield put(gameActions.updateGames(normalized.entities.games))
+ yield put(playerActions.updatePlayers(normalized.entities.players))
+ }
+ } finally {
+ yield apply(lobbyUpdatesChannel, lobbyUpdatesChannel.close)
+ }
+}
+
+function *watchGameStart({ socket }) {
+ const currentGameId = getCurrentGameId()
+ const gameStartedChannel = yield call(createSubscriptionChannel, socket, `/topic/lobby/${currentGameId}/started`)
+ try {
+ yield take(gameStartedChannel)
+ yield put(gameActions.enterGame())
+ yield put(push('/game'))
+ } finally {
+ yield apply(gameStartedChannel, gameStartedChannel.close)
+ }
+}
+
+function *startGame({ socket }) {
+ while (true) {
+ yield take(types.REQUEST_START_GAME)
+ yield apply(socket, socket.send, ['/app/lobby/startGame', {}])
+ }
+}
+
+function *lobbySaga(socketConnection) {
+ yield [
+ call(watchLobbyUpdates, socketConnection),
+ call(watchGameStart, socketConnection),
+ call(startGame, socketConnection)
+ ]
+}
+
+export default lobbySaga
bgstack15