metamaps--metamaps/realtime/reducer.js

76 lines
2.6 KiB
JavaScript
Raw Normal View History

2016-10-21 15:02:53 +08:00
const { omit, omitBy, isNil, mapValues } = require('lodash')
const {
2016-10-21 00:59:02 -04:00
JOIN_MAP,
LEAVE_MAP,
JOIN_CALL,
LEAVE_CALL
2016-10-21 15:02:53 +08:00
} = require('../frontend/src/Metamaps/Realtime/events')
2016-10-21 00:59:02 -04:00
const NOT_IN_CONVERSATION = 0
const IN_CONVERSATION = 1
const addMapperToMap = (map, userId) => { return { ...map, [userId]: NOT_IN_CONVERSATION }}
2016-10-21 15:15:20 +08:00
const reducer = (state = { connectedPeople: {}, liveMaps: {} }, action) => {
2016-10-21 00:59:02 -04:00
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:
2016-10-21 15:15:20 +08:00
return Object.assign({}, state, {
connectedPeople: Object.assign({}, connectedPeople, {
2016-10-21 00:59:02 -04:00
[payload.userid]: {
id: payload.userid,
username: payload.username,
avatar: payload.avatar
}
2016-10-21 15:15:20 +08:00
}),
liveMaps: Object.assign({}, liveMaps, {
2016-10-21 00:59:02 -04:00
[payload.mapid]: addMapperToMap(map || {}, payload.userid)
2016-10-21 15:15:20 +08:00
})
})
2016-10-21 00:59:02 -04:00
case LEAVE_MAP:
2016-10-21 15:15:20 +08:00
// if the map will empty, remove it from liveMaps, if the map will not empty, just remove the mapper
const newLiveMaps = mapWillEmpty
? omit(liveMaps, payload.mapid)
: Object.assign({}, liveMaps, { [payload.mapid]: omit(map, payload.userid) })
2016-10-21 00:59:02 -04:00
return {
connectedPeople: omit(connectedPeople, payload.userid),
2016-10-21 15:15:20 +08:00
liveMaps: omitBy(newLiveMaps, isNil)
2016-10-21 00:59:02 -04:00
}
case JOIN_CALL:
2016-10-21 15:15:20 +08:00
// update the user (payload.id is user id) in the given map to be marked in the conversation
return Object.assign({}, state, {
liveMaps: Object.assign({}, liveMaps, {
[payload.mapid]: Object.assign({}, map, {
2016-10-21 00:59:02 -04:00
[payload.id]: IN_CONVERSATION
2016-10-21 15:15:20 +08:00
})
})
})
2016-10-21 00:59:02 -04:00
case LEAVE_CALL:
2016-10-21 15:15:20 +08:00
const newMap = callWillFinish
? mapValues(map, () => NOT_IN_CONVERSATION)
: Object.assign({}, map, { [payload.userid]: NOT_IN_CONVERSATION })
return Object.assign({}, state, {
liveMaps: Object.assign({}, liveMaps, { map: newMap })
})
2016-10-21 00:59:02 -04:00
case 'DISCONNECT':
const mapWithoutUser = omit(map, payload.userid)
const newMap = callWillFinish ? mapValues(mapWithoutUser, () => NOT_IN_CONVERSATION) : mapWithoutUser
2016-10-21 15:15:20 +08:00
const newLiveMaps = mapWillEmpty ? omit(liveMaps, payload.mapid) : Object.assign({}, liveMaps, { [payload.mapid]: newMap })
2016-10-21 00:59:02 -04:00
return {
connectedPeople: omit(connectedPeople, payload.userid),
2016-10-21 15:15:20 +08:00
liveMaps: omitBy(newLiveMaps, isNil)
2016-10-21 00:59:02 -04:00
}
default:
return state
}
2016-10-21 15:15:20 +08:00
}
module.exports = reducer