push state to client

This commit is contained in:
Connor Turland 2016-10-21 00:59:02 -04:00
parent 7a09a1c620
commit b26fe651db
15 changed files with 163 additions and 80 deletions

View file

@ -5,6 +5,8 @@
], ],
"plugins": [ "plugins": [
"lodash", "lodash",
"transform-class-properties" "transform-class-properties",
"transform-es2015-destructuring",
"transform-object-rest-spread"
] ]
} }

View file

@ -1,8 +1,7 @@
/* EVENTS SENDABLE */ /* EVENTS SENDABLE */
export const REQUEST_LIVE_MAPS = 'REQUEST_LIVE_MAPS'
export const JOIN_MAP = 'JOIN_MAP' export const JOIN_MAP = 'JOIN_MAP'
export const LEAVE_MAP = 'LEAVE_MAP'
export const CHECK_FOR_CALL = 'CHECK_FOR_CALL' export const CHECK_FOR_CALL = 'CHECK_FOR_CALL'
export const LEAVE_MAP = 'LEAVE_MAP'
export const ACCEPT_CALL = 'ACCEPT_CALL' export const ACCEPT_CALL = 'ACCEPT_CALL'
export const DENY_CALL = 'DENY_CALL' export const DENY_CALL = 'DENY_CALL'
export const DENY_INVITE = 'DENY_INVITE' export const DENY_INVITE = 'DENY_INVITE'
@ -25,6 +24,7 @@ export const DELETE_SYNAPSE = 'DELETE_SYNAPSE'
export const UPDATE_MAP = 'UPDATE_MAP' export const UPDATE_MAP = 'UPDATE_MAP'
/* EVENTS RECEIVABLE */ /* EVENTS RECEIVABLE */
export const JUNTO_UPDATED = 'JUNTO_UPDATED'
export const INVITED_TO_CALL = 'INVITED_TO_CALL' export const INVITED_TO_CALL = 'INVITED_TO_CALL'
export const INVITED_TO_JOIN = 'INVITED_TO_JOIN' export const INVITED_TO_JOIN = 'INVITED_TO_JOIN'
export const CALL_ACCEPTED = 'CALL_ACCEPTED' export const CALL_ACCEPTED = 'CALL_ACCEPTED'
@ -49,6 +49,3 @@ export const SYNAPSE_REMOVED = 'SYNAPSE_REMOVED'
export const SYNAPSE_DELETED = 'SYNAPSE_DELETED' export const SYNAPSE_DELETED = 'SYNAPSE_DELETED'
export const PEER_COORDS_UPDATED = 'PEER_COORDS_UPDATED' export const PEER_COORDS_UPDATED = 'PEER_COORDS_UPDATED'
export const MAP_UPDATED = 'MAP_UPDATED' export const MAP_UPDATED = 'MAP_UPDATED'
export const LIVE_MAPS_RECEIVED = 'LIVE_MAPS_RECEIVED'
export const MAP_WENT_LIVE = 'MAP_WENT_LIVE'
export const MAP_CEASED_LIVE = 'MAP_CEASED_LIVE'

View file

@ -27,6 +27,7 @@ import Views from '../Views'
import Visualize from '../Visualize' import Visualize from '../Visualize'
import { import {
JUNTO_UPDATED,
INVITED_TO_CALL, INVITED_TO_CALL,
INVITED_TO_JOIN, INVITED_TO_JOIN,
CALL_ACCEPTED, CALL_ACCEPTED,
@ -34,9 +35,9 @@ import {
INVITE_DENIED, INVITE_DENIED,
CALL_IN_PROGRESS, CALL_IN_PROGRESS,
CALL_STARTED, CALL_STARTED,
MAPPER_LIST_UPDATED,
MAPPER_JOINED_CALL, MAPPER_JOINED_CALL,
MAPPER_LEFT_CALL, MAPPER_LEFT_CALL,
MAPPER_LIST_UPDATED,
NEW_MAPPER, NEW_MAPPER,
LOST_MAPPER, LOST_MAPPER,
MESSAGE_CREATED, MESSAGE_CREATED,
@ -50,13 +51,11 @@ import {
SYNAPSE_REMOVED, SYNAPSE_REMOVED,
SYNAPSE_DELETED, SYNAPSE_DELETED,
PEER_COORDS_UPDATED, PEER_COORDS_UPDATED,
LIVE_MAPS_RECEIVED,
MAP_WENT_LIVE,
MAP_CEASED_LIVE,
MAP_UPDATED MAP_UPDATED
} from './events' } from './events'
import { import {
juntoUpdated,
invitedToCall, invitedToCall,
invitedToJoin, invitedToJoin,
callAccepted, callAccepted,
@ -64,9 +63,9 @@ import {
inviteDenied, inviteDenied,
callInProgress, callInProgress,
callStarted, callStarted,
mapperListUpdated,
mapperJoinedCall, mapperJoinedCall,
mapperLeftCall, mapperLeftCall,
mapperListUpdated,
peerCoordsUpdated, peerCoordsUpdated,
newMapper, newMapper,
lostMapper, lostMapper,
@ -81,13 +80,9 @@ import {
synapseRemoved, synapseRemoved,
synapseDeleted, synapseDeleted,
mapUpdated, mapUpdated,
liveMapsReceived,
mapWentLive,
mapCeasedLive
} from './receivable' } from './receivable'
import { import {
requestLiveMaps,
joinMap, joinMap,
leaveMap, leaveMap,
checkForCall, checkForCall,
@ -98,8 +93,8 @@ import {
inviteACall, inviteACall,
joinCall, joinCall,
leaveCall, leaveCall,
sendMapperInfo,
sendCoords, sendCoords,
sendMapperInfo,
createMessage, createMessage,
dragTopic, dragTopic,
createTopic, createTopic,
@ -114,6 +109,7 @@ import {
} from './sendable' } from './sendable'
let Realtime = { let Realtime = {
juntoState: { connectedPeople: {}, liveMaps: {} },
videoId: 'video-wrapper', videoId: 'video-wrapper',
socket: null, socket: null,
webrtc: null, webrtc: null,
@ -499,7 +495,6 @@ let Realtime = {
} }
const sendables = [ const sendables = [
['requestLiveMaps',requestLiveMaps],
['joinMap',joinMap], ['joinMap',joinMap],
['leaveMap',leaveMap], ['leaveMap',leaveMap],
['checkForCall',checkForCall], ['checkForCall',checkForCall],
@ -529,6 +524,7 @@ sendables.forEach(sendable => {
}) })
const subscribeToEvents = (Realtime, socket) => { const subscribeToEvents = (Realtime, socket) => {
socket.on(JUNTO_UPDATED, juntoUpdated(Realtime))
socket.on(INVITED_TO_CALL, invitedToCall(Realtime)) socket.on(INVITED_TO_CALL, invitedToCall(Realtime))
socket.on(INVITED_TO_JOIN, invitedToJoin(Realtime)) socket.on(INVITED_TO_JOIN, invitedToJoin(Realtime))
socket.on(CALL_ACCEPTED, callAccepted(Realtime)) socket.on(CALL_ACCEPTED, callAccepted(Realtime))
@ -536,9 +532,9 @@ const subscribeToEvents = (Realtime, socket) => {
socket.on(INVITE_DENIED, inviteDenied(Realtime)) socket.on(INVITE_DENIED, inviteDenied(Realtime))
socket.on(CALL_IN_PROGRESS, callInProgress(Realtime)) socket.on(CALL_IN_PROGRESS, callInProgress(Realtime))
socket.on(CALL_STARTED, callStarted(Realtime)) socket.on(CALL_STARTED, callStarted(Realtime))
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(Realtime))
socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(Realtime)) socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(Realtime))
socket.on(MAPPER_LEFT_CALL, mapperLeftCall(Realtime)) socket.on(MAPPER_LEFT_CALL, mapperLeftCall(Realtime))
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(Realtime))
socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(Realtime)) socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(Realtime))
socket.on(NEW_MAPPER, newMapper(Realtime)) socket.on(NEW_MAPPER, newMapper(Realtime))
socket.on(LOST_MAPPER, lostMapper(Realtime)) socket.on(LOST_MAPPER, lostMapper(Realtime))
@ -553,9 +549,6 @@ const subscribeToEvents = (Realtime, socket) => {
socket.on(SYNAPSE_REMOVED, synapseRemoved(Realtime)) socket.on(SYNAPSE_REMOVED, synapseRemoved(Realtime))
socket.on(SYNAPSE_DELETED, synapseDeleted(Realtime)) socket.on(SYNAPSE_DELETED, synapseDeleted(Realtime))
socket.on(MAP_UPDATED, mapUpdated(Realtime)) socket.on(MAP_UPDATED, mapUpdated(Realtime))
socket.on(LIVE_MAPS_RECEIVED, liveMapsReceived(Realtime))
socket.on(MAP_WENT_LIVE, mapWentLive(Realtime))
socket.on(MAP_CEASED_LIVE, mapCeasedLive(Realtime))
} }
export default Realtime export default Realtime

View file

@ -1,7 +1,10 @@
/* globals $ */
/* /*
everthing in this file happens as a result of websocket events everthing in this file happens as a result of websocket events
*/ */
import { JUNTO_UPDATED } from './events'
import Active from '../Active' import Active from '../Active'
import GlobalUI from '../GlobalUI' import GlobalUI from '../GlobalUI'
import Control from '../Control' import Control from '../Control'
@ -12,6 +15,11 @@ import Synapse from '../Synapse'
import Util from '../Util' import Util from '../Util'
import Visualize from '../Visualize' import Visualize from '../Visualize'
export const juntoUpdated = self => state => {
self.juntoState = state
$(document).trigger(JUNTO_UPDATED)
}
export const synapseRemoved = self => data => { export const synapseRemoved = self => data => {
var synapse = Metamaps.Synapses.get(data.mappableid) var synapse = Metamaps.Synapses.get(data.mappableid)
if (synapse) { if (synapse) {
@ -391,6 +399,3 @@ export const callStarted = self => () => {
self.room.conversationInProgress() self.room.conversationInProgress()
} }
export const liveMapsReceived = self => () => {}
export const mapWentLive = self => () => {}
export const mapCeasedLive = self => () => {}

View file

@ -2,7 +2,6 @@ import Active from '../Active'
import GlobalUI from '../GlobalUI' import GlobalUI from '../GlobalUI'
import { import {
REQUEST_LIVE_MAPS,
JOIN_MAP, JOIN_MAP,
LEAVE_MAP, LEAVE_MAP,
CHECK_FOR_CALL, CHECK_FOR_CALL,
@ -28,15 +27,11 @@ import {
UPDATE_MAP UPDATE_MAP
} from './events' } from './events'
export const requestLiveMaps = self => () => {
self.socket.emit(REQUEST_LIVE_MAPS)
}
export const joinMap = self => () => { export const joinMap = self => () => {
self.socket.emit(JOIN_MAP, { self.socket.emit(JOIN_MAP, {
userid: Active.Mapper.id, userid: Active.Mapper.id,
username: Active.Mapper.get('name'), username: Active.Mapper.get('name'),
userimage: Active.Mapper.get('image'), avatar: Active.Mapper.get('image'),
mapid: Active.Map.id, mapid: Active.Map.id,
map: Active.Map.attributes map: Active.Map.attributes
}) })

View file

@ -3,7 +3,9 @@
import React from 'react' import React from 'react'
import ReactDOM from 'react-dom' // TODO ensure this isn't a double import import ReactDOM from 'react-dom' // TODO ensure this isn't a double import
import { JUNTO_UPDATED } from '../Realtime/events'
import Active from '../Active' import Active from '../Active'
import Realtime from '../Realtime'
import Maps from '../../components/Maps' import Maps from '../../components/Maps'
/* /*
@ -27,6 +29,8 @@ const ExploreMaps = {
render: function (mapperObj, cb) { render: function (mapperObj, cb) {
var self = ExploreMaps var self = ExploreMaps
if (!self.collection) return
if (typeof mapperObj === 'function') { if (typeof mapperObj === 'function') {
cb = mapperObj cb = mapperObj
mapperObj = null mapperObj = null
@ -36,6 +40,7 @@ const ExploreMaps = {
currentUser: Active.Mapper, currentUser: Active.Mapper,
section: self.collection.id, section: self.collection.id,
maps: self.collection, maps: self.collection,
juntoState: Realtime.juntoState,
moreToLoad: self.collection.page != 'loadedAll', moreToLoad: self.collection.page != 'loadedAll',
user: mapperObj, user: mapperObj,
loadMore: self.loadMore loadMore: self.loadMore

View file

@ -2,6 +2,15 @@ import ExploreMaps from './ExploreMaps'
import ChatView from './ChatView' import ChatView from './ChatView'
import VideoView from './VideoView' import VideoView from './VideoView'
import Room from './Room' import Room from './Room'
import { JUNTO_UPDATED } from '../Realtime/events'
const Views = { ExploreMaps, ChatView, VideoView, Room } const Views = {
init: () => {
$(document).on(JUNTO_UPDATED, ExploreMaps.render())
},
ExploreMaps,
ChatView,
VideoView,
Room
}
export default Views export default Views

View file

@ -88,7 +88,7 @@ document.addEventListener('DOMContentLoaded', function () {
if (Metamaps.currentSection === 'explore') { if (Metamaps.currentSection === 'explore') {
const capitalize = Metamaps.currentPage.charAt(0).toUpperCase() + Metamaps.currentPage.slice(1) const capitalize = Metamaps.currentPage.charAt(0).toUpperCase() + Metamaps.currentPage.slice(1)
Metamaps.Views.ExploreMaps.setCollection(Metamaps.Maps[capitalize]) Views.ExploreMaps.setCollection(Metamaps.Maps[capitalize])
if (Metamaps.currentPage === 'mapper') { if (Metamaps.currentPage === 'mapper') {
Views.ExploreMaps.fetchUserThenRender() Views.ExploreMaps.fetchUserThenRender()
} else { } else {

View file

@ -33,7 +33,7 @@ class Maps extends Component {
} }
resize = () => { resize = () => {
const { maps, user, currentUser } = this.props const { maps, juntoState, user, currentUser } = this.props
const numCards = maps.length + (user || currentUser ? 1 : 0) const numCards = maps.length + (user || currentUser ? 1 : 0)
const mapSpaces = Math.floor(document.body.clientWidth / MAP_WIDTH) const mapSpaces = Math.floor(document.body.clientWidth / MAP_WIDTH)
const mapsWidth = Math.min(MAX_COLUMNS, Math.min(numCards, mapSpaces)) * MAP_WIDTH const mapsWidth = Math.min(MAX_COLUMNS, Math.min(numCards, mapSpaces)) * MAP_WIDTH
@ -70,6 +70,7 @@ class Maps extends Component {
Maps.propTypes = { Maps.propTypes = {
section: PropTypes.string.isRequired, section: PropTypes.string.isRequired,
maps: PropTypes.object.isRequired, maps: PropTypes.object.isRequired,
juntoState: PropTypes.object.isRequired,
moreToLoad: PropTypes.bool.isRequired, moreToLoad: PropTypes.bool.isRequired,
user: PropTypes.object, user: PropTypes.object,
currentUser: PropTypes.object, currentUser: PropTypes.object,

View file

@ -24,6 +24,8 @@
"babel-loader": "6.2.5", "babel-loader": "6.2.5",
"babel-plugin-lodash": "^3.2.9", "babel-plugin-lodash": "^3.2.9",
"babel-plugin-transform-class-properties": "6.11.5", "babel-plugin-transform-class-properties": "6.11.5",
"babel-plugin-transform-es2015-destructuring": "^6.16.0",
"babel-plugin-transform-object-rest-spread": "^6.16.0",
"babel-preset-es2015": "6.14.0", "babel-preset-es2015": "6.14.0",
"babel-preset-react": "6.11.1", "babel-preset-react": "6.11.1",
"backbone": "1.0.0", "backbone": "1.0.0",
@ -40,6 +42,7 @@
"react": "15.3.2", "react": "15.3.2",
"react-dom": "15.3.2", "react-dom": "15.3.2",
"react-dropzone": "3.6.0", "react-dropzone": "3.6.0",
"redux": "^3.6.0",
"simplewebrtc": "2.2.0", "simplewebrtc": "2.2.0",
"socket.io": "1.3.7", "socket.io": "1.3.7",
"underscore": "1.4.4", "underscore": "1.4.4",

View file

@ -5,13 +5,12 @@ import {
TOPIC_DELETED, TOPIC_DELETED,
SYNAPSE_UPDATED, SYNAPSE_UPDATED,
SYNAPSE_DELETED, SYNAPSE_DELETED,
LIVE_MAPS_RECEIVED,
MAP_WENT_LIVE,
MAP_CEASED_LIVE,
MAP_UPDATED, MAP_UPDATED,
JUNTO_UPDATED,
// server receivable, client sendable // server receivable, client sendable
REQUEST_LIVE_MAPS, JOIN_CALL,
LEAVE_CALL,
JOIN_MAP, JOIN_MAP,
LEAVE_MAP, LEAVE_MAP,
UPDATE_TOPIC, UPDATE_TOPIC,
@ -21,41 +20,20 @@ import {
UPDATE_MAP UPDATE_MAP
} from '../frontend/src/Metamaps/Realtime/events' } from '../frontend/src/Metamaps/Realtime/events'
const adjustAndBroadcast = (io, socket, state, event, data) => {
if (event === JOIN_MAP) {
if (!state.liveMaps[data.mapid]) {
state.liveMaps[data.mapid] = data.map // { name: '', desc: '', numTopics: '' }
state.liveMaps[data.mapid].mapper_count = 1
io.sockets.emit(MAP_WENT_LIVE, state.liveMaps[data.mapid])
}
else {
state.liveMaps[data.mapid].mapper_count++
}
}
else if (event === LEAVE_MAP) {
const mapid = socket.mapid
if (state.liveMaps[mapid] && state.liveMaps[mapid].mapper_count == 1) {
delete state.liveMaps[mapid]
io.sockets.emit(MAP_CEASED_LIVE, { id: mapid })
}
else if (state.liveMaps[mapid]) {
state.liveMaps[mapid].mapper_count--
}
}
}
module.exports = function (io, state) { module.exports = function (io, store) {
io.on('connection', function (socket) { io.on('connection', function (socket) {
socket.on(REQUEST_LIVE_MAPS, function (activeUser) { store.subscribe(() => {
//constrain response to maps visible to user console.log(store.getState())
var maps = Object.keys(state.liveMaps).map(function(key) { return state.liveMaps[key] }) io.sockets.emit(JUNTO_UPDATED, store.getState())
socket.emit(LIVE_MAPS_RECEIVED, maps)
}) })
socket.on(JOIN_MAP, data => adjustAndBroadcast(io, socket, state, JOIN_MAP, data)) socket.on(JOIN_MAP, data => store.dispatch({ type: JOIN_MAP, payload: data}))
socket.on(LEAVE_MAP, () => adjustAndBroadcast(io, socket, state, LEAVE_MAP)) socket.on(LEAVE_MAP, () => store.dispatch({ type: LEAVE_MAP, payload: socket }))
socket.on('disconnect', () => adjustAndBroadcast(io, socket, state, LEAVE_MAP)) socket.on(JOIN_CALL, data => store.dispatch({ type: JOIN_CALL, payload: data }))
socket.on(LEAVE_CALL, () => store.dispatch({ type: LEAVE_CALL, payload: socket }))
socket.on('disconnect', () => store.dispatch({ type: 'DISCONNECT', payload: socket }))
socket.on(UPDATE_TOPIC, function (data) { socket.on(UPDATE_TOPIC, function (data) {
socket.broadcast.emit(TOPIC_UPDATED, data) socket.broadcast.emit(TOPIC_UPDATED, data)

View file

@ -21,7 +21,7 @@ import {
const { mapRoom, userMapRoom } = require('./rooms') const { mapRoom, userMapRoom } = require('./rooms')
module.exports = function (io, state) { module.exports = function (io, store) {
io.on('connection', function (socket) { io.on('connection', function (socket) {
socket.on(CHECK_FOR_CALL, function (data) { socket.on(CHECK_FOR_CALL, function (data) {
@ -39,6 +39,8 @@ module.exports = function (io, state) {
socket.on(ACCEPT_CALL, function (data) { socket.on(ACCEPT_CALL, function (data) {
socket.broadcast.in(userMapRoom(data.inviter, data.mapid)).emit(CALL_ACCEPTED, data.invited) socket.broadcast.in(userMapRoom(data.inviter, data.mapid)).emit(CALL_ACCEPTED, data.invited)
// convert this so that it broadcasts to all sockets and includes the map id
// and who's participating
socket.broadcast.in(mapRoom(data.mapid)).emit(CALL_STARTED) socket.broadcast.in(mapRoom(data.mapid)).emit(CALL_STARTED)
}) })
@ -51,10 +53,14 @@ module.exports = function (io, state) {
}) })
socket.on(JOIN_CALL, function (data) { socket.on(JOIN_CALL, function (data) {
// convert this so that it broadcasts to all sockets and includes the map id
// and info about who joined
socket.broadcast.in(mapRoom(data.mapid)).emit(MAPPER_JOINED_CALL, data.id) socket.broadcast.in(mapRoom(data.mapid)).emit(MAPPER_JOINED_CALL, data.id)
}) })
socket.on(LEAVE_CALL, function (data) { socket.on(LEAVE_CALL, function (data) {
// convert this so that it broadcasts to all sockets and includes the map id
// and info about who joined
socket.broadcast.in(mapRoom(data.mapid)).emit(MAPPER_LEFT_CALL, data.id) socket.broadcast.in(mapRoom(data.mapid)).emit(MAPPER_LEFT_CALL, data.id)
}) })
}) })

View file

@ -13,8 +13,8 @@ import {
JOIN_MAP, JOIN_MAP,
LEAVE_MAP, LEAVE_MAP,
SEND_MAPPER_INFO,
SEND_COORDS, SEND_COORDS,
SEND_MAPPER_INFO,
CREATE_MESSAGE, CREATE_MESSAGE,
DRAG_TOPIC, DRAG_TOPIC,
CREATE_TOPIC, CREATE_TOPIC,
@ -25,7 +25,7 @@ import {
const { mapRoom, userMapRoom } = require('./rooms') const { mapRoom, userMapRoom } = require('./rooms')
module.exports = function (io, state) { module.exports = function (io, store) {
io.on('connection', function (socket) { io.on('connection', function (socket) {
// this will ping everyone on a map that there's a person just joined the map // this will ping everyone on a map that there's a person just joined the map
@ -33,11 +33,11 @@ module.exports = function (io, state) {
socket.mapid = data.mapid socket.mapid = data.mapid
socket.userid = data.userid socket.userid = data.userid
socket.username = data.username socket.username = data.username
socket.userimage = data.userimage socket.avatar = data.avatar
var newUser = { var newUser = {
userid: data.userid, userid: data.userid,
username: data.username, username: data.username,
userimage: data.userimage avatar: data.avatar
} }
socket.join(mapRoom(data.mapid)) socket.join(mapRoom(data.mapid))
socket.join(userMapRoom(data.userid, data.mapid)) socket.join(userMapRoom(data.userid, data.mapid))

View file

@ -6,13 +6,14 @@ map = require('./map'),
global = require('./global'), global = require('./global'),
stunservers = [{"url": "stun:stun.l.google.com:19302"}] stunservers = [{"url": "stun:stun.l.google.com:19302"}]
var state = { import { createStore } from 'redux'
connectedPeople: {}, import { reducer } from './reducer'
liveMaps: {}
} let store = createStore(reducer)
signalling(io, stunservers, state)
junto(io, state) global(io, store)
map(io, state) signalling(io, stunservers, store)
global(io, state) junto(io, store)
map(io, store)
io.listen(5001) io.listen(5001)

88
realtime/reducer.js Normal file
View file

@ -0,0 +1,88 @@
import { omit, omitBy, isNil, mapValues } from 'lodash'
import {
JOIN_MAP,
LEAVE_MAP,
JOIN_CALL,
LEAVE_CALL
} from '../frontend/src/Metamaps/Realtime/events'
const NOT_IN_CONVERSATION = 0
const IN_CONVERSATION = 1
const addMapperToMap = (map, userId) => { return { ...map, [userId]: NOT_IN_CONVERSATION }}
export const reducer = (state = { connectedPeople: {}, liveMaps: {} }, action) => {
const { type, payload } = action
const { connectedPeople, liveMaps } = state
const map = payload && liveMaps[payload.mapid]
const mapWillEmpty = map && Object.keys(map).length === 1
const callWillFinish = map && (type === LEAVE_CALL || type === 'DISCONNECT') && Object.keys(map).length === 2
switch (type) {
case JOIN_MAP:
return {
connectedPeople: {
...connectedPeople,
[payload.userid]: {
id: payload.userid,
username: payload.username,
avatar: payload.avatar
}
},
liveMaps: {
...liveMaps,
[payload.mapid]: addMapperToMap(map || {}, payload.userid)
}
}
case LEAVE_MAP:
return {
connectedPeople: omit(connectedPeople, payload.userid),
// if the map will empty, remove it from liveMaps, if the map will not empty, just remove the mapper
liveMaps: omitBy(mapWillEmpty ? omit(liveMaps, payload.mapid) : { ...liveMaps, [payload.mapid]: omit(liveMaps[payload.mapid], payload.userid) }, isNil)
}
case JOIN_CALL:
return {
// connectedPeople stays the same
connectedPeople,
liveMaps: {
// liveMaps stays the same, except for
...liveMaps,
// the map in question
[payload.mapid]: {
// which stays the same, except for
...map,
// the user in question, which is now marked as being in a conversation
[payload.id]: IN_CONVERSATION
}
}
}
case LEAVE_CALL:
return {
// connectedPeople stays the same
connectedPeople,
liveMaps: {
// liveMaps stays the same, except for
...liveMaps,
// the map in question
[payload.mapid]: callWillFinish ? mapValues(map, () => NOT_IN_CONVERSATION) : {
// which stays the same, except for
...map,
// the user in question, which is now marked as being NOT in conversation
[payload.userid]: NOT_IN_CONVERSATION
}
}
}
case 'DISCONNECT':
const mapWithoutUser = omit(map, payload.userid)
const newMap = callWillFinish ? mapValues(mapWithoutUser, () => NOT_IN_CONVERSATION) : mapWithoutUser
return {
connectedPeople: omit(connectedPeople, payload.userid),
// if the map will empty, remove it from liveMaps, if the map will not empty, just remove the mapper
liveMaps: omitBy(mapWillEmpty ? omit(liveMaps, payload.mapid) :
{ ...liveMaps, [payload.mapid]: newMap }, isNil)
}
default:
return state
}
}