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, gameList as gameListSchema } from "../schemas/games"; import { actions as gameActions, types } from "../redux/games"; import { actions as playerActions } from "../redux/players"; 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); } } function* watchLobbyJoined({ socket }) { const joinedLobbyChannel = yield call( createSubscriptionChannel, socket, "/user/queue/lobby/joined" ); try { 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 { yield apply(joinedLobbyChannel, joinedLobbyChannel.close); } } function* createGame({ socket }) { while (true) { const { gameName } = yield take(types.REQUEST_CREATE_GAME); yield apply(socket, socket.send, [ "/app/lobby/create", JSON.stringify({ gameName }), {} ]); } } function* joinGame({ socket }) { while (true) { const { gameId } = yield take(types.REQUEST_JOIN_GAME); yield apply(socket, socket.send, [ "/app/lobby/join", JSON.stringify({ gameId }), {} ]); } } function* gameBrowserSaga(socketConnection) { yield [ call(watchGames, socketConnection), call(watchLobbyJoined, socketConnection), call(createGame, socketConnection), call(joinGame, socketConnection) ]; } export default gameBrowserSaga;