Associate remote participant w/ JitsiConference (_JOINED)
The plan set in motion here is to associate remote participants with the JitsiConference instances that created them in order to be able to remove remote participants when a JitsiConference is no longer the primary focus of the jitsi-meet app. And that's supposed to alleviate a problem with multiplying remote thumbnails. Doing all of the above in a single commit is a bit of a high order. So I'm splitting the whole into multiple successive commits for the purposes of observability, comprehension. Each commit is supposed to be safe even if subsequent commits are not accepted, are reverted, whatever. Obviously, without the successive commits, a commit may be "unused". One of the important pieces of the multiplying remote thumbnails "fix" offered is removing remote participants who are no longer of interest i.e. PARTICIPANT_LEFT. But in order for _LEFT to be implemented, _JOINED must be implemented first.
This commit is contained in:
parent
fcca15c827
commit
983e62ffe9
|
@ -1688,6 +1688,7 @@ export default {
|
|||
const displayName = user.getDisplayName();
|
||||
|
||||
APP.store.dispatch(participantJoined({
|
||||
conference: room,
|
||||
id,
|
||||
name: displayName,
|
||||
role: user.getRole()
|
||||
|
|
|
@ -306,6 +306,7 @@ export default class SharedVideoManager {
|
|||
SHARED_VIDEO_CONTAINER_TYPE, self.sharedVideo);
|
||||
|
||||
APP.store.dispatch(participantJoined({
|
||||
conference: APP.conference,
|
||||
id: self.url,
|
||||
isBot: true,
|
||||
name: 'YouTube'
|
||||
|
|
|
@ -140,6 +140,7 @@ function _addConferenceListeners(conference, dispatch) {
|
|||
conference.on(
|
||||
JitsiConferenceEvents.USER_JOINED,
|
||||
(id, user) => dispatch(participantJoined({
|
||||
conference,
|
||||
id,
|
||||
name: user.getDisplayName(),
|
||||
role: user.getRole()
|
||||
|
|
|
@ -214,11 +214,16 @@ export function participantDisplayNameChanged(id, displayName = '') {
|
|||
*
|
||||
* @param {Participant} participant - Information about participant.
|
||||
* @returns {{
|
||||
* type: PARTICIPANT_JOINED,
|
||||
* participant: Participant
|
||||
* type: PARTICIPANT_JOINED,
|
||||
* participant: Participant
|
||||
* }}
|
||||
*/
|
||||
export function participantJoined(participant) {
|
||||
if (!participant.local && !participant.conference) {
|
||||
throw Error(
|
||||
'A remote participant must be associated with a JitsiConference!');
|
||||
}
|
||||
|
||||
return {
|
||||
type: PARTICIPANT_JOINED,
|
||||
participant
|
||||
|
@ -393,7 +398,5 @@ export function showParticipantJoinedNotification(displayName) {
|
|||
joinedParticipantsNames.push(
|
||||
displayName || interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME);
|
||||
|
||||
return dispatch => {
|
||||
_throttledNotifyParticipantConnected(dispatch);
|
||||
};
|
||||
return dispatch => _throttledNotifyParticipantConnected(dispatch);
|
||||
}
|
||||
|
|
|
@ -139,15 +139,15 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
*/
|
||||
function _localParticipantJoined({ getState, dispatch }, next, action) {
|
||||
const result = next(action);
|
||||
|
||||
const settings = getState()['features/base/settings'];
|
||||
const localParticipant = {
|
||||
|
||||
dispatch(localParticipantJoined({
|
||||
avatarID: settings.avatarID,
|
||||
avatarURL: settings.avatarURL,
|
||||
email: settings.email,
|
||||
name: settings.displayName
|
||||
};
|
||||
|
||||
dispatch(localParticipantJoined(localParticipant));
|
||||
}));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -204,7 +204,10 @@ function _participantJoinedOrUpdated({ getState }, next, action) {
|
|||
if (local) {
|
||||
const { conference } = getState()['features/base/conference'];
|
||||
|
||||
conference.setLocalParticipantProperty('raisedHand', raisedHand);
|
||||
conference
|
||||
&& conference.setLocalParticipantProperty(
|
||||
'raisedHand',
|
||||
raisedHand);
|
||||
}
|
||||
|
||||
if (typeof APP === 'object') {
|
||||
|
|
|
@ -39,6 +39,35 @@ declare var APP: Object;
|
|||
const PARTICIPANT_PROPS_TO_OMIT_WHEN_UPDATE
|
||||
= [ 'dominantSpeaker', 'id', 'local', 'pinned' ];
|
||||
|
||||
/**
|
||||
* 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));
|
||||
|
||||
case PARTICIPANT_JOINED:
|
||||
return [ ...state, _participantJoined(action) ];
|
||||
|
||||
case PARTICIPANT_LEFT:
|
||||
return state.filter(p => p.id !== action.participant.id);
|
||||
}
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
/**
|
||||
* Reducer function for a single participant.
|
||||
*
|
||||
|
@ -67,52 +96,6 @@ function _participant(state: Object = {}, action) {
|
|||
}
|
||||
break;
|
||||
|
||||
case PARTICIPANT_JOINED: {
|
||||
const { participant } = action; // eslint-disable-line no-shadow
|
||||
const {
|
||||
avatarURL,
|
||||
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);
|
||||
}
|
||||
|
||||
// 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.
|
||||
if (!id && local) {
|
||||
id = LOCAL_PARTICIPANT_DEFAULT_ID;
|
||||
}
|
||||
|
||||
return {
|
||||
avatarID,
|
||||
avatarURL,
|
||||
connectionStatus,
|
||||
dominantSpeaker: dominantSpeaker || false,
|
||||
email,
|
||||
id,
|
||||
isBot,
|
||||
local: local || false,
|
||||
name,
|
||||
pinned: pinned || false,
|
||||
role: role || PARTICIPANT_ROLE.NONE
|
||||
};
|
||||
}
|
||||
|
||||
case PARTICIPANT_UPDATED: {
|
||||
const { participant } = action; // eslint-disable-line no-shadow
|
||||
let { id } = participant;
|
||||
|
@ -147,31 +130,60 @@ function _participant(state: Object = {}, action) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Listen for actions which add, remove, or update the set of participants in
|
||||
* the conference.
|
||||
* Reduces a specific redux action of type {@link PARTICIPANT_JOINED} in the
|
||||
* feature base/participants.
|
||||
*
|
||||
* @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[]}
|
||||
* @param {Action} action - The redux action of type {@code PARTICIPANT_JOINED}
|
||||
* to reduce.
|
||||
* @private
|
||||
* @returns {Object} The new participant derived from the payload of the
|
||||
* specified {@code action} to be added into the redux state of the feature
|
||||
* base/participants after the reduction of the specified
|
||||
* {@code action}.
|
||||
*/
|
||||
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));
|
||||
function _participantJoined({ participant }) {
|
||||
const {
|
||||
avatarURL,
|
||||
connectionStatus,
|
||||
dominantSpeaker,
|
||||
email,
|
||||
isBot,
|
||||
local,
|
||||
name,
|
||||
pinned,
|
||||
role
|
||||
} = participant;
|
||||
let { avatarID, conference, id } = participant;
|
||||
|
||||
case PARTICIPANT_JOINED:
|
||||
return [ ...state, _participant(undefined, action) ];
|
||||
if (local) {
|
||||
// avatarID
|
||||
//
|
||||
// TODO Get the avatarID of the local participant from localStorage.
|
||||
avatarID || (avatarID = randomHexString(32));
|
||||
|
||||
case PARTICIPANT_LEFT:
|
||||
return state.filter(p => p.id !== action.participant.id);
|
||||
// conference
|
||||
//
|
||||
// XXX The local participant is not identified in association with a
|
||||
// JitsiConference because it is identified by the very fact that it is
|
||||
// the local participant.
|
||||
conference = undefined;
|
||||
|
||||
default:
|
||||
return state;
|
||||
// id
|
||||
id || (id = LOCAL_PARTICIPANT_DEFAULT_ID);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
avatarID,
|
||||
avatarURL,
|
||||
conference,
|
||||
connectionStatus,
|
||||
dominantSpeaker: dominantSpeaker || false,
|
||||
email,
|
||||
id,
|
||||
isBot,
|
||||
local: local || false,
|
||||
name,
|
||||
pinned: pinned || false,
|
||||
role: role || PARTICIPANT_ROLE.NONE
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue