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;