jiti-meet/react/features/base/participants/reducer.js

178 lines
5.1 KiB
JavaScript
Raw Normal View History

2017-10-13 19:31:05 +00:00
// @flow
import { ReducerRegistry, set } from '../redux';
import { randomHexString } from '../util';
import {
DOMINANT_SPEAKER_CHANGED,
PARTICIPANT_ID_CHANGED,
PARTICIPANT_JOINED,
PARTICIPANT_LEFT,
PARTICIPANT_UPDATED,
PIN_PARTICIPANT
} from './actionTypes';
import { LOCAL_PARTICIPANT_DEFAULT_ID, PARTICIPANT_ROLE } from './constants';
/**
* Participant object.
* @typedef {Object} Participant
* @property {string} id - Participant ID.
* @property {string} name - Participant name.
* @property {string} avatar - Path to participant avatar if any.
* @property {string} role - Participant role.
* @property {boolean} local - If true, participant is local.
* @property {boolean} pinned - If true, participant is currently a
* "PINNED_ENDPOINT".
* @property {boolean} dominantSpeaker - If this participant is the dominant
* speaker in the (associated) conference, {@code true}; otherwise,
* {@code false}.
* @property {string} email - Participant email.
*/
2017-10-13 19:31:05 +00:00
declare var APP: Object;
/**
* These properties should not be bulk assigned when updating a particular
* @see Participant.
* @type {string[]}
*/
const PARTICIPANT_PROPS_TO_OMIT_WHEN_UPDATE
= [ 'dominantSpeaker', 'id', 'local', 'pinned' ];
/**
* Reducer function for a single participant.
*
* @param {Participant|undefined} state - Participant to be modified.
* @param {Object} action - Action object.
* @param {string} action.type - Type of action.
* @param {Participant} action.participant - Information about participant to be
* added/modified.
* @param {JitsiConference} action.conference - Conference instance.
* @private
2017-10-13 19:31:05 +00:00
* @returns {Participant}
*/
2017-10-13 19:31:05 +00:00
function _participant(state: Object = {}, action) {
switch (action.type) {
case DOMINANT_SPEAKER_CHANGED:
// Only one dominant speaker is allowed.
return (
set(state, 'dominantSpeaker', state.id === action.participant.id));
case PARTICIPANT_ID_CHANGED:
if (state.id === action.oldValue) {
return {
...state,
id: action.newValue
};
}
break;
case PARTICIPANT_JOINED: {
2017-10-18 18:21:46 +00:00
const { participant } = action; // eslint-disable-line no-shadow
const {
avatarURL,
2017-04-05 09:01:57 +00:00
connectionStatus,
dominantSpeaker,
email,
isBot,
local,
name,
pinned,
role
} = participant;
let { avatarID, id } = participant;
// avatarID
//
// TODO Get the avatarID of the local participant from localStorage.
if (!avatarID && local) {
avatarID = randomHexString(32);
}
2017-03-07 16:50:17 +00:00
// id
//
// XXX The situation of not having an ID for a remote participant should
// not happen. Maybe we should raise an error in this case or generate a
// random ID.
2017-03-07 16:50:17 +00:00
if (!id && local) {
id = LOCAL_PARTICIPANT_DEFAULT_ID;
}
return {
avatarID,
avatarURL,
2017-04-05 09:01:57 +00:00
connectionStatus,
2017-03-07 16:50:17 +00:00
dominantSpeaker: dominantSpeaker || false,
2017-02-27 21:42:28 +00:00
email,
id,
isBot,
2017-03-07 16:50:17 +00:00
local: local || false,
name,
2017-03-07 16:50:17 +00:00
pinned: pinned || false,
role: role || PARTICIPANT_ROLE.NONE
};
}
2017-03-07 16:50:17 +00:00
case PARTICIPANT_UPDATED: {
2017-10-18 18:21:46 +00:00
const { participant } = action; // eslint-disable-line no-shadow
let { id } = participant;
2017-10-18 18:21:46 +00:00
const { local } = participant;
if (!id && local) {
id = LOCAL_PARTICIPANT_DEFAULT_ID;
}
2017-03-07 16:50:17 +00:00
if (state.id === id) {
const newState = { ...state };
2017-03-07 16:50:17 +00:00
for (const key in participant) {
if (participant.hasOwnProperty(key)
&& PARTICIPANT_PROPS_TO_OMIT_WHEN_UPDATE.indexOf(key)
=== -1) {
2017-03-07 16:50:17 +00:00
newState[key] = participant[key];
}
}
return newState;
}
break;
2017-03-07 16:50:17 +00:00
}
case PIN_PARTICIPANT:
// Currently, only one pinned participant is allowed.
return set(state, 'pinned', state.id === action.participant.id);
}
return state;
}
/**
* Listen for actions which add, remove, or update the set of participants in
* the conference.
*
* @param {Participant[]} state - List of participants to be modified.
* @param {Object} action - Action object.
* @param {string} action.type - Type of action.
* @param {Participant} action.participant - Information about participant to be
* added/removed/modified.
* @returns {Participant[]}
*/
ReducerRegistry.register('features/base/participants', (state = [], action) => {
switch (action.type) {
case DOMINANT_SPEAKER_CHANGED:
case PARTICIPANT_ID_CHANGED:
case PARTICIPANT_UPDATED:
case PIN_PARTICIPANT:
return state.map(p => _participant(p, action));
2017-10-13 19:31:05 +00:00
case PARTICIPANT_JOINED:
return [ ...state, _participant(undefined, action) ];
case PARTICIPANT_LEFT:
return state.filter(p => p.id !== action.participant.id);
default:
return state;
}
});