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