Compare commits

...

2 Commits

Author SHA1 Message Date
damencho
90cc52835f feat: fix leave and lower interval of batching and remove participant pane. 2021-06-25 15:22:58 +03:00
damencho
3a9e69518d feat: batch. 2021-06-24 16:29:27 +03:00
29 changed files with 259 additions and 49 deletions

View File

@@ -82,8 +82,12 @@ import {
getLocalParticipant,
getNormalizedDisplayName,
getParticipantById,
hiddenParticipantJoined,
hiddenParticipantLeft,
localParticipantConnectionStatusChanged,
localParticipantRoleChanged,
MULTIPLE_PARTICIPANTS_JOINED,
MULTIPLE_PARTICIPANTS_LEFT,
participantConnectionStatusChanged,
participantKicked,
participantMutedUs,
@@ -442,6 +446,108 @@ function _connectionFailedHandler(error) {
}
}
/**
* Accumulates events.
*/
class EventsAccumulator {
eventsReceived = new Map();
// eslint-disable-next-line require-jsdoc
constructor(isJoin, conference) {
this.isJoin = isJoin;
this.conference = conference;
console.log('createeeeeeeee', isJoin);
this._scheduleCheck();
}
// eslint-disable-next-line require-jsdoc
_scheduleCheck() {
setTimeout(() => {
if (this.eventsReceived.size > 0) {
const eventsCopy = new Map(this.eventsReceived);
console.log('executeeeeeeeee', eventsCopy);
this.eventsReceived.clear();
const usersToProcess = [];
eventsCopy.forEach(user => {
if (this.isJoin) {
const id = user.getId();
const displayName = user.getDisplayName();
if (user.isHidden()) {
APP.store.dispatch(hiddenParticipantJoined(id, displayName));
} else {
const isReplacing = user.isReplacing && user.isReplacing();
usersToProcess.push({
botType: user.getBotType(),
connectionStatus: user.getConnectionStatus(),
conference: this.conference,
id,
name: displayName,
presence: user.getStatus(),
role: user.getRole(),
isReplacing
});
}
if (user.isHidden()) {
return;
}
APP.store.dispatch(updateRemoteParticipantFeatures(user));
logger.log(`USER ${id} connected:`, user);
APP.UI.addUser(user);
} else {
const id = user.getId();
if (user.isHidden()) {
APP.store.dispatch(hiddenParticipantLeft(id));
} else {
const isReplaced = user.isReplaced && user.isReplaced();
usersToProcess.push({
id,
conference: this.conference,
isReplaced
});
}
if (user.isHidden()) {
return;
}
logger.log(`USER ${id} LEFT:`, user);
}
});
if (this.isJoin) {
APP.store.dispatch({
type: MULTIPLE_PARTICIPANTS_JOINED,
participants: usersToProcess
});
} else {
APP.store.dispatch({
type: MULTIPLE_PARTICIPANTS_LEFT,
participants: usersToProcess
});
}
}
this._scheduleCheck();
}, 250);
}
// eslint-disable-next-line valid-jsdoc,require-jsdoc
add(id, user) {
this.eventsReceived.set(id, user);
}
}
export default {
/**
* Flag used to delay modification of the muted status of local media tracks
@@ -473,6 +579,10 @@ export default {
*/
localVideo: null,
joinAccumulator: null,
leftAccumulator: null,
/**
* Returns an object containing a promise which resolves with the created tracks &
* the errors resulting from that process.
@@ -1993,28 +2103,33 @@ export default {
room.on(JitsiConferenceEvents.PARTCIPANT_FEATURES_CHANGED, user => {
APP.store.dispatch(updateRemoteParticipantFeatures(user));
});
this.joinAccumulator = new EventsAccumulator(true, room);
room.on(JitsiConferenceEvents.USER_JOINED, (id, user) => {
// The logic shared between RN and web.
commonUserJoinedHandling(APP.store, room, user);
// commonUserJoinedHandling(APP.store, room, user);
//
// if (user.isHidden()) {
// return;
// }
//
// APP.store.dispatch(updateRemoteParticipantFeatures(user));
// logger.log(`USER ${id} connected:`, user);
// APP.UI.addUser(user);
if (user.isHidden()) {
return;
}
APP.store.dispatch(updateRemoteParticipantFeatures(user));
logger.log(`USER ${id} connected:`, user);
APP.UI.addUser(user);
this.joinAccumulator.add(id, user);
});
this.leftAccumulator = new EventsAccumulator(false, room);
room.on(JitsiConferenceEvents.USER_LEFT, (id, user) => {
// The logic shared between RN and web.
commonUserLeftHandling(APP.store, room, user);
this.leftAccumulator.add(id, user);
if (user.isHidden()) {
return;
}
logger.log(`USER ${id} LEFT:`, user);
// // The logic shared between RN and web.
// commonUserLeftHandling(APP.store, room, user);
//
// if (user.isHidden()) {
// return;
// }
//
// logger.log(`USER ${id} LEFT:`, user);
});
room.on(JitsiConferenceEvents.USER_STATUS_CHANGED, (id, status) => {

View File

@@ -81,6 +81,7 @@ export function commonUserJoinedHandling(
{ dispatch }: Object,
conference: Object,
user: Object) {
// joined
const id = user.getId();
const displayName = user.getDisplayName();
@@ -117,6 +118,7 @@ export function commonUserLeftHandling(
{ dispatch }: Object,
conference: Object,
user: Object) {
// left
const id = user.getId();
if (user.isHidden()) {

View File

@@ -30,9 +30,9 @@ MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case APP_STATE_CHANGED:
case CONFERENCE_JOINED:
case PARTICIPANT_JOINED:
case PARTICIPANT_JOINED: // joined
case PARTICIPANT_KICKED:
case PARTICIPANT_LEFT:
case PARTICIPANT_LEFT: // left
case SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED:
case SELECT_LARGE_VIDEO_PARTICIPANT:
case SET_AUDIO_ONLY:
@@ -53,6 +53,7 @@ MiddlewareRegistry.register(store => next => action => {
* @returns {void}
*/
function _updateLastN({ dispatch, getState }) {
// participants dependent
const state = getState();
const { conference } = state['features/base/conference'];
const { enabled: audioOnly } = state['features/base/audio-only'];

View File

@@ -39,6 +39,7 @@ MiddlewareRegistry.register(store => next => action => {
break;
case PARTICIPANT_LEFT:
// left
action.participant.local && store.dispatch(disposeLib());
break;

View File

@@ -90,6 +90,16 @@ export const PARTICIPANT_ROLE_CHANGED = 'PARTICIPANT_ROLE_CHANGED';
*/
export const PARTICIPANT_JOINED = 'PARTICIPANT_JOINED';
/**
* Action to signal that a participant has joined.
*
* {
* type: MULTIPLE_PARTICIPANTS_JOINED,
* participant: Participant
* }
*/
export const MULTIPLE_PARTICIPANTS_JOINED = 'MULTIPLE_PARTICIPANTS_JOINED';
/**
* Action to signal that a participant has been removed from a conference by
* another participant.
@@ -114,6 +124,18 @@ export const PARTICIPANT_KICKED = 'PARTICIPANT_KICKED';
*/
export const PARTICIPANT_LEFT = 'PARTICIPANT_LEFT';
/**
* Action to handle case when participant lefts.
*
* {
* type: PARTICIPANT_LEFT,
* participant: {
* id: string
* }
* }
*/
export const MULTIPLE_PARTICIPANTS_LEFT = 'MULTIPLE_PARTICIPANTS_LEFT';
/**
* Action to handle case when info about participant changes.
*

View File

@@ -266,10 +266,9 @@ export function participantJoined(participant) {
// conference. The following check is really necessary because a
// JitsiConference may have moved into leaving but may still manage to
// sneak a PARTICIPANT_JOINED in if its leave is delayed for any purpose
// (which is not outragous given that leaving involves network
// (which is not outrageous given that leaving involves network
// requests.)
const stateFeaturesBaseConference
= getState()['features/base/conference'];
const stateFeaturesBaseConference = getState()['features/base/conference'];
if (conference === stateFeaturesBaseConference.conference
|| conference === stateFeaturesBaseConference.joining) {

View File

@@ -256,6 +256,7 @@ export function getPinnedParticipant(stateful: Object | Function) {
* @returns {Participant[]}
*/
function _getAllParticipants(stateful) {
// where we use this
return (
Array.isArray(stateful)
? stateful

View File

@@ -178,6 +178,7 @@ MiddlewareRegistry.register(store => next => action => {
* features/base/conference by ensuring that the former does not contain remote
* participants no longer relevant to the latter. Introduced to address an issue
* with multiplying thumbnails in the filmstrip.
* What is this????
*/
StateListenerRegistry.register(
/* selector */ state => getCurrentConference(state),

View File

@@ -4,6 +4,8 @@ import { ReducerRegistry, set } from '../redux';
import {
DOMINANT_SPEAKER_CHANGED,
MULTIPLE_PARTICIPANTS_JOINED,
MULTIPLE_PARTICIPANTS_LEFT,
PARTICIPANT_ID_CHANGED,
PARTICIPANT_JOINED,
PARTICIPANT_LEFT,
@@ -71,10 +73,23 @@ ReducerRegistry.register('features/base/participants', (state = [], action) => {
case PIN_PARTICIPANT:
return state.map(p => _participant(p, action));
case PARTICIPANT_JOINED:
case PARTICIPANT_JOINED: // joined
return [ ...state, _participantJoined(action) ];
case PARTICIPANT_LEFT: {
case MULTIPLE_PARTICIPANTS_JOINED: { // joined
const participants = action.participants;
const newParticipants = participants.map(p => _participantJoined({ participant: p }));
return [ ...state, ...newParticipants ];
}
case MULTIPLE_PARTICIPANTS_LEFT: { // left
const participants = action.participants;
return state.filter(p => !participants.find(p1 => p1.id === p.id));
}
case PARTICIPANT_LEFT: { // left
// XXX A remote participant is uniquely identified by their id in a
// specific JitsiConference instance. The local participant is uniquely
// identified by the very fact that there is only one local participant

View File

@@ -412,6 +412,7 @@ export function getTrackByMediaTypeAndParticipant(
tracks,
mediaType,
participantId) {
// ???
return tracks.find(
t => Boolean(t.jitsiTrack) && t.participantId === participantId && t.mediaType === mediaType
);
@@ -501,6 +502,7 @@ export function isLocalVideoTrackDesktop(state) {
* @returns {boolean}
*/
export function isRemoteTrackMuted(tracks, mediaType, participantId) {
// ???
const track = getTrackByMediaTypeAndParticipant(
tracks, mediaType, participantId);

View File

@@ -21,7 +21,7 @@ MiddlewareRegistry.register(store => next => async action => {
break;
}
case PARTICIPANT_JOINED: {
case PARTICIPANT_JOINED: { // joined
const shouldCount = !store.getState()['features/billing-counter'].endpointCounted
&& !action.participant.local;

View File

@@ -250,6 +250,8 @@ function _handleChatError({ dispatch }, error) {
* @returns {void}
*/
function _handleReceivedMessage({ dispatch, getState }, { id, message, privateMessage, timestamp }) {
// participant dependent
// Logic for all platforms:
const state = getState();
const { isOpen: isChatOpen } = state['features/chat'];

View File

@@ -15,7 +15,7 @@ import { Filmstrip } from '../../../filmstrip';
import { CalleeInfoContainer } from '../../../invite';
import { LargeVideo } from '../../../large-video';
import { KnockingParticipantList, LobbyScreen } from '../../../lobby';
import { ParticipantsPane } from '../../../participants-pane/components';
// import { ParticipantsPane } from '../../../participants-pane/components';
import { getParticipantsPaneOpen } from '../../../participants-pane/functions';
import { Prejoin, isPrejoinPageVisible } from '../../../prejoin';
import { fullScreenChanged, showToolbox } from '../../../toolbox/actions.web';
@@ -247,7 +247,7 @@ class Conference extends AbstractConference<Props, *> {
{ _showPrejoin && <Prejoin />}
</div>
<ParticipantsPane />
{/*<ParticipantsPane />*/}
</div>
);
}

View File

@@ -139,11 +139,11 @@ MiddlewareRegistry.register(store => next => action => {
{ id: action.kicker });
break;
case PARTICIPANT_LEFT:
case PARTICIPANT_LEFT: // left
APP.API.notifyUserLeft(action.participant.id);
break;
case PARTICIPANT_JOINED: {
case PARTICIPANT_JOINED: { // joined
const { participant } = action;
const { id, local, name } = participant;

View File

@@ -46,6 +46,7 @@ StateListenerRegistry.register(
StateListenerRegistry.register(
/* selector */ state => state['features/large-video'].participantId,
/* listener */ (participantId, store) => {
// ???
const videoTrack = getTrackByMediaTypeAndParticipant(
store.getState()['features/base/tracks'], MEDIA_TYPE.VIDEO, participantId);

View File

@@ -1,6 +1,10 @@
// @flow
import { PARTICIPANT_JOINED, PARTICIPANT_LEFT } from '../base/participants';
import {
MULTIPLE_PARTICIPANTS_JOINED, MULTIPLE_PARTICIPANTS_LEFT,
PARTICIPANT_JOINED,
PARTICIPANT_LEFT
} from '../base/participants';
import { ReducerRegistry } from '../base/redux';
import {
@@ -145,7 +149,7 @@ ReducerRegistry.register(
visibleParticipantsEndIndex: action.endIndex,
visibleParticipants: state.remoteParticipants.slice(action.startIndex, action.endIndex + 1)
};
case PARTICIPANT_JOINED: {
case PARTICIPANT_JOINED: { // join
const { id, local } = action.participant;
if (!local) {
@@ -160,7 +164,22 @@ ReducerRegistry.register(
return state;
}
case PARTICIPANT_LEFT: {
case MULTIPLE_PARTICIPANTS_JOINED: { // joined
const participants = action.participants;
const newParticipants = participants.map(p => p.id);
state.remoteParticipants = [ ...state.remoteParticipants, ...newParticipants ];
const { visibleParticipantsStartIndex: startIndex, visibleParticipantsEndIndex: endIndex } = state;
if (state.remoteParticipants.length - 1 <= endIndex) {
state.visibleParticipants = state.remoteParticipants.slice(startIndex, endIndex + 1);
}
return state;
}
case PARTICIPANT_LEFT: { // left
const { id, local } = action.participant;
if (local) {
@@ -189,6 +208,33 @@ ReducerRegistry.register(
return state;
}
case MULTIPLE_PARTICIPANTS_LEFT: { // left
const participants = action.participants;
// return state.filter(p => participants.find(p1 => p1.id === p.id));
let removedParticipantIndex = 0;
state.remoteParticipants = state.remoteParticipants.filter((participantId, index) => {
if (participants.find(p1 => p1.id === participantId)) {
removedParticipantIndex = index;
return false;
}
return true;
});
const { visibleParticipantsStartIndex: startIndex, visibleParticipantsEndIndex: endIndex } = state;
if (removedParticipantIndex >= startIndex && removedParticipantIndex <= endIndex) {
state.visibleParticipants = state.remoteParticipants.slice(startIndex, endIndex + 1);
}
participants.forEach(p => delete state.participantsVolume[p.id]);
return state;
}
}
return state;

View File

@@ -67,7 +67,7 @@ MiddlewareRegistry.register(store => next => action => {
});
break;
}
case PARTICIPANT_LEFT:
case PARTICIPANT_LEFT: // left
if (store.getState()['features/follow-me'].moderator === action.participant.id) {
store.dispatch(setFollowMeModerator());
}

View File

@@ -76,7 +76,7 @@ MiddlewareRegistry.register(store => next => action => {
const state = getState();
if (action.type === PARTICIPANT_UPDATED
|| action.type === PARTICIPANT_LEFT) {
|| action.type === PARTICIPANT_LEFT) { // left
oldParticipantPresence
= getParticipantPresenceStatus(state, action.participant.id);
}
@@ -109,8 +109,8 @@ MiddlewareRegistry.register(store => next => action => {
_onConferenceJoined(store);
break;
case PARTICIPANT_JOINED:
case PARTICIPANT_LEFT:
case PARTICIPANT_JOINED: // joined
case PARTICIPANT_LEFT: // left
case PARTICIPANT_UPDATED: {
_maybeHideCalleeInfo(action, store);

View File

@@ -44,8 +44,8 @@ MiddlewareRegistry.register(store => next => action => {
break;
}
case PARTICIPANT_JOINED:
case PARTICIPANT_LEFT:
case PARTICIPANT_JOINED: // joined
case PARTICIPANT_LEFT: // left
case PIN_PARTICIPANT:
case TRACK_ADDED:
case TRACK_REMOVED:

View File

@@ -181,8 +181,8 @@ MiddlewareRegistry.register(store => next => action => {
break;
}
case PARTICIPANT_JOINED:
case PARTICIPANT_LEFT: {
case PARTICIPANT_JOINED: // join
case PARTICIPANT_LEFT: { // left
const { participant } = action;
sendEvent(

View File

@@ -29,7 +29,7 @@ declare var interfaceConfig: Object;
*/
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case PARTICIPANT_JOINED: {
case PARTICIPANT_JOINED: { // join
const result = next(action);
const { participant: p } = action;
const { dispatch, getState } = store;
@@ -58,7 +58,7 @@ MiddlewareRegistry.register(store => next => action => {
return result;
}
case PARTICIPANT_LEFT: {
case PARTICIPANT_LEFT: { // left
if (!joinLeaveNotificationsDisabled()) {
const participant = getParticipantById(
store.getState(),

View File

@@ -64,7 +64,7 @@ MiddlewareRegistry.register(store => next => async action => {
return result;
}
case PARTICIPANT_LEFT: {
case PARTICIPANT_LEFT: { // left
const { getState, dispatch } = store;
const state = getState();
const { id } = action.participant;

View File

@@ -39,7 +39,7 @@ MiddlewareRegistry.register(store => next => action => {
case CONFERENCE_LEFT:
dispatch(resetSharedVideoStatus());
break;
case PARTICIPANT_LEFT:
case PARTICIPANT_LEFT: // left
if (action.participant.id === stateOwnerId) {
batch(() => {
dispatch(resetSharedVideoStatus());

View File

@@ -75,7 +75,7 @@ class Captions
function mapStateToProps(state) {
return {
..._abstractMapStateToProps(state),
_isLifted: state['features/base/participants'].length < 2
_isLifted: state['features/base/participants'].length < 2 // getParticipantCount
};
}

View File

@@ -60,7 +60,7 @@ export function getMovableButtons(width: number): Set<string> {
export function isToolboxVisible(stateful: Object | Function) {
const state = toState(stateful);
const { alwaysVisible, enabled, visible } = state['features/toolbox'];
const { length: participantCount } = state['features/base/participants'];
const { length: participantCount } = state['features/base/participants']; // change to getParticipantCount
const alwaysVisibleFlag = getFeatureFlag(state, TOOLBOX_ALWAYS_VISIBLE, false);
const enabledFlag = getFeatureFlag(state, TOOLBOX_ENABLED, true);

View File

@@ -37,7 +37,7 @@ MiddlewareRegistry.register(store => next => action => {
case _TRANSCRIBER_LEFT:
store.dispatch(showStoppedTranscribingNotification());
break;
case HIDDEN_PARTICIPANT_JOINED:
case HIDDEN_PARTICIPANT_JOINED: // join hidden
if (action.displayName
&& action.displayName === TRANSCRIBER_DISPLAY_NAME) {
store.dispatch(transcriberJoined(action.id));
@@ -46,7 +46,7 @@ MiddlewareRegistry.register(store => next => action => {
}
break;
case HIDDEN_PARTICIPANT_LEFT:
case HIDDEN_PARTICIPANT_LEFT: // left hidden
if (action.id === transcriberJID) {
store.dispatch(transcriberLeft(action.id));
}

View File

@@ -101,6 +101,7 @@ export function getTileViewGridDimensions(state: Object) {
// When in tile view mode, we must discount ourselves (the local participant) because our
// tile is not visible.
const { iAmRecorder } = state['features/base/config'];
// getParticipantCount
const numberOfParticipants = state['features/base/participants'].length - (iAmRecorder ? 1 : 0);
const columnsToMaintainASquare = Math.ceil(Math.sqrt(numberOfParticipants));

View File

@@ -32,7 +32,7 @@ MiddlewareRegistry.register(store => next => action => {
let shouldUpdateAutoPin = false;
switch (action.type) {
case PARTICIPANT_LEFT: {
case PARTICIPANT_LEFT: { // left
if (!getAutoPinSetting() || isFollowMeActive(store)) {
break;
}

View File

@@ -36,7 +36,7 @@ MiddlewareRegistry.register(store => next => action => {
VideoLayout.reset();
break;
case PARTICIPANT_JOINED:
case PARTICIPANT_JOINED: // join
if (!action.participant.local) {
VideoLayout.updateVideoMutedForNoTracks(action.participant.id);
}
@@ -62,6 +62,7 @@ MiddlewareRegistry.register(store => next => action => {
case TRACK_ADDED:
if (action.track.mediaType !== MEDIA_TYPE.AUDIO) {
// participant dependent
VideoLayout._updateLargeVideoIfDisplayed(action.track.participantId, true);
}