feat(replace-participant): Replace participant with same jwt in the conf
- update lib-jitsi-meet to version with support for replacing participant
This commit is contained in:
parent
60188794b5
commit
342dd4ceca
|
@ -304,10 +304,14 @@ class ConferenceConnector {
|
|||
|
||||
// not enough rights to create conference
|
||||
case JitsiConferenceErrors.AUTHENTICATION_REQUIRED: {
|
||||
const { replaceParticipant }
|
||||
= APP.store.getState()['features/base/config'];
|
||||
|
||||
|
||||
// Schedule reconnect to check if someone else created the room.
|
||||
this.reconnectTimeout = setTimeout(() => {
|
||||
APP.store.dispatch(conferenceWillJoin(room));
|
||||
room.join();
|
||||
room.join(null, replaceParticipant);
|
||||
}, 5000);
|
||||
|
||||
const { password }
|
||||
|
@ -393,8 +397,10 @@ class ConferenceConnector {
|
|||
*
|
||||
*/
|
||||
connect() {
|
||||
const { replaceParticipant } = APP.store.getState()['features/base/config'];
|
||||
|
||||
// the local storage overrides here and in connection.js can be used by jibri
|
||||
room.join(jitsiLocalStorage.getItem('xmpp_conference_password_override'));
|
||||
room.join(jitsiLocalStorage.getItem('xmpp_conference_password_override'), replaceParticipant);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2167,7 +2173,20 @@ export default {
|
|||
JitsiConferenceEvents.LOCK_STATE_CHANGED,
|
||||
(...args) => APP.store.dispatch(lockStateChanged(room, ...args)));
|
||||
|
||||
room.on(JitsiConferenceEvents.KICKED, participant => {
|
||||
room.on(JitsiConferenceEvents.KICKED, (participant, reason, isReplaced) => {
|
||||
if (isReplaced) {
|
||||
// this event triggers when the local participant is kicked, `participant`
|
||||
// is the kicker. In replace participant case, kicker is undefined,
|
||||
// as the server initiated it. We mark in store the local participant
|
||||
// as being replaced based on jwt.
|
||||
const localParticipant = getLocalParticipant(APP.store.getState());
|
||||
|
||||
APP.store.dispatch(participantUpdated({
|
||||
conference: room,
|
||||
id: localParticipant.id,
|
||||
isReplaced
|
||||
}));
|
||||
}
|
||||
APP.store.dispatch(kickedOut(room, participant));
|
||||
});
|
||||
|
||||
|
|
|
@ -209,7 +209,10 @@ function logout(room: Object) {
|
|||
}).then(url => {
|
||||
// de-authenticate conference on the fly
|
||||
if (room.isJoined()) {
|
||||
room.join();
|
||||
const { replaceParticipant }
|
||||
= APP.store.getState()['features/base/config'];
|
||||
|
||||
room.join(null, replaceParticipant);
|
||||
}
|
||||
|
||||
return url;
|
||||
|
|
|
@ -11071,8 +11071,8 @@
|
|||
}
|
||||
},
|
||||
"lib-jitsi-meet": {
|
||||
"version": "github:jitsi/lib-jitsi-meet#2259d4418574841a782e98df27c44370bb84df45",
|
||||
"from": "github:jitsi/lib-jitsi-meet#2259d4418574841a782e98df27c44370bb84df45",
|
||||
"version": "github:jitsi/lib-jitsi-meet#fad985e95a9e8a4fb8a1b8b1ad2cfef75370c866",
|
||||
"from": "github:jitsi/lib-jitsi-meet#fad985e95a9e8a4fb8a1b8b1ad2cfef75370c866",
|
||||
"requires": {
|
||||
"@jitsi/js-utils": "1.0.2",
|
||||
"@jitsi/sdp-interop": "github:jitsi/sdp-interop#5fc4af6dcf8a6e6af9fedbcd654412fd47b1b4ae",
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
"jquery-i18next": "1.2.1",
|
||||
"js-md5": "0.6.1",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#2259d4418574841a782e98df27c44370bb84df45",
|
||||
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#fad985e95a9e8a4fb8a1b8b1ad2cfef75370c866",
|
||||
"libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.1",
|
||||
|
|
|
@ -460,7 +460,7 @@ export function createConference() {
|
|||
|
||||
sendLocalParticipant(state, conference);
|
||||
|
||||
conference.join(password);
|
||||
conference.join(password, config.replaceParticipant);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -477,8 +477,11 @@ export function checkIfCanJoin() {
|
|||
const { authRequired, password }
|
||||
= getState()['features/base/conference'];
|
||||
|
||||
const { replaceParticipant }
|
||||
= getState()['features/base/config'];
|
||||
|
||||
authRequired && dispatch(_conferenceWillJoin(authRequired));
|
||||
authRequired && authRequired.join(password);
|
||||
authRequired && authRequired.join(password, replaceParticipant);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,8 @@ export function commonUserJoinedHandling(
|
|||
if (user.isHidden()) {
|
||||
dispatch(hiddenParticipantJoined(id, displayName));
|
||||
} else {
|
||||
const isReplacing = user.isReplacing && user.isReplacing();
|
||||
|
||||
dispatch(participantJoined({
|
||||
botType: user.getBotType(),
|
||||
connectionStatus: user.getConnectionStatus(),
|
||||
|
@ -94,7 +96,8 @@ export function commonUserJoinedHandling(
|
|||
id,
|
||||
name: displayName,
|
||||
presence: user.getStatus(),
|
||||
role: user.getRole()
|
||||
role: user.getRole(),
|
||||
isReplacing
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +122,9 @@ export function commonUserLeftHandling(
|
|||
if (user.isHidden()) {
|
||||
dispatch(hiddenParticipantLeft(id));
|
||||
} else {
|
||||
dispatch(participantLeft(id, conference));
|
||||
const isReplaced = user.isReplaced && user.isReplaced();
|
||||
|
||||
dispatch(participantLeft(id, conference, isReplaced));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,6 +152,7 @@ export default [
|
|||
'requireDisplayName',
|
||||
'remoteVideoMenu',
|
||||
'roomPasswordNumberOfDigits',
|
||||
'replaceParticipant',
|
||||
'resolution',
|
||||
'startAudioMuted',
|
||||
'startAudioOnly',
|
||||
|
|
|
@ -366,6 +366,7 @@ export function hiddenParticipantLeft(id) {
|
|||
* with the participant identified by the specified {@code id}. Only the local
|
||||
* participant is allowed to not specify an associated {@code JitsiConference}
|
||||
* instance.
|
||||
* @param {boolean} isReplaced - Whether the participant is to be replaced in the meeting.
|
||||
* @returns {{
|
||||
* type: PARTICIPANT_LEFT,
|
||||
* participant: {
|
||||
|
@ -374,12 +375,13 @@ export function hiddenParticipantLeft(id) {
|
|||
* }
|
||||
* }}
|
||||
*/
|
||||
export function participantLeft(id, conference) {
|
||||
export function participantLeft(id, conference, isReplaced) {
|
||||
return {
|
||||
type: PARTICIPANT_LEFT,
|
||||
participant: {
|
||||
conference,
|
||||
id
|
||||
id,
|
||||
isReplaced
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -490,9 +492,13 @@ export function participantKicked(kicker, kicked) {
|
|||
dispatch({
|
||||
type: PARTICIPANT_KICKED,
|
||||
kicked: kicked.getId(),
|
||||
kicker: kicker.getId()
|
||||
kicker: kicker?.getId()
|
||||
});
|
||||
|
||||
if (kicked.isReplaced && kicked.isReplaced()) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(showNotification({
|
||||
titleArguments: {
|
||||
kicked:
|
||||
|
|
|
@ -161,7 +161,7 @@ StateListenerRegistry.register(
|
|||
for (const p of getState()['features/base/participants']) {
|
||||
!p.local
|
||||
&& (!conference || p.conference !== conference)
|
||||
&& dispatch(participantLeft(p.id, p.conference));
|
||||
&& dispatch(participantLeft(p.id, p.conference, p.isReplaced));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -356,14 +356,16 @@ function _maybePlaySounds({ getState, dispatch }, action) {
|
|||
if (!action.participant.local
|
||||
&& (!startAudioMuted
|
||||
|| getParticipantCount(state) < startAudioMuted)) {
|
||||
const { isReplacing, isReplaced } = action.participant;
|
||||
|
||||
if (action.type === PARTICIPANT_JOINED) {
|
||||
const { presence } = action.participant;
|
||||
|
||||
// The sounds for the poltergeist are handled by features/invite.
|
||||
if (presence !== INVITED && presence !== CALLING) {
|
||||
if (presence !== INVITED && presence !== CALLING && !isReplacing) {
|
||||
dispatch(playSound(PARTICIPANT_JOINED_SOUND_ID));
|
||||
}
|
||||
} else if (action.type === PARTICIPANT_LEFT) {
|
||||
} else if (action.type === PARTICIPANT_LEFT && !isReplaced) {
|
||||
dispatch(playSound(PARTICIPANT_LEFT_SOUND_ID));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,6 +187,7 @@ function _participantJoined({ participant }) {
|
|||
dominantSpeaker,
|
||||
email,
|
||||
isFakeParticipant,
|
||||
isReplacing,
|
||||
isJigasi,
|
||||
loadableAvatarUrl,
|
||||
local,
|
||||
|
@ -218,6 +219,7 @@ function _participantJoined({ participant }) {
|
|||
email,
|
||||
id,
|
||||
isFakeParticipant,
|
||||
isReplacing,
|
||||
isJigasi,
|
||||
loadableAvatarUrl,
|
||||
local: local || false,
|
||||
|
|
|
@ -18,6 +18,12 @@ import { getParticipantDisplayName } from '../base/participants';
|
|||
*/
|
||||
export function notifyKickedOut(participant: Object, submit: ?Function) {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
if (!participant || (participant.isReplaced && participant.isReplaced())) {
|
||||
submit && submit();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(openDialog(AlertDialog, {
|
||||
contentKey: {
|
||||
key: 'dialog.kickTitle',
|
||||
|
|
|
@ -18,6 +18,10 @@ import {
|
|||
*/
|
||||
export function notifyKickedOut(participant: Object, _: ?Function) { // eslint-disable-line no-unused-vars
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
if (!participant || (participant.isReplaced && participant.isReplaced())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const args = {
|
||||
participantDisplayName:
|
||||
getParticipantDisplayName(getState, participant.getId())
|
||||
|
|
|
@ -113,7 +113,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
id: getLocalParticipant(store.getState()).id,
|
||||
local: true
|
||||
},
|
||||
{ id: action.participant.getId() }
|
||||
{ id: action.participant ? action.participant.getId() : undefined }
|
||||
);
|
||||
break;
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ export function mapStateToProps(state: Object): $Shape<Props> {
|
|||
|
||||
return {
|
||||
_participants: knockingParticipants,
|
||||
_visible: lobbyEnabled && isLocalParticipantModerator(state) && Boolean(knockingParticipants.length)
|
||||
_visible: lobbyEnabled && isLocalParticipantModerator(state)
|
||||
&& Boolean(knockingParticipants && knockingParticipants.length)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
const { participant: p } = action;
|
||||
const { dispatch, getState } = store;
|
||||
|
||||
if (!p.local && !joinLeaveNotificationsDisabled()) {
|
||||
if (!p.local && !joinLeaveNotificationsDisabled() && !p.isReplacing) {
|
||||
dispatch(showParticipantJoinedNotification(
|
||||
getParticipantDisplayName(getState, p.id)
|
||||
));
|
||||
|
@ -45,13 +45,15 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
// Do not show the notification for mobile and also when the focus indicator is disabled.
|
||||
const displayName = getParticipantDisplayName(getState, p.id);
|
||||
|
||||
dispatch(showNotification({
|
||||
descriptionArguments: { to: displayName || '$t(notify.somebody)' },
|
||||
descriptionKey: 'notify.grantedTo',
|
||||
titleKey: 'notify.somebody',
|
||||
title: displayName
|
||||
},
|
||||
NOTIFICATION_TIMEOUT));
|
||||
if (!p.isReplacing) {
|
||||
dispatch(showNotification({
|
||||
descriptionArguments: { to: displayName || '$t(notify.somebody)' },
|
||||
descriptionKey: 'notify.grantedTo',
|
||||
titleKey: 'notify.somebody',
|
||||
title: displayName
|
||||
},
|
||||
NOTIFICATION_TIMEOUT));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -65,7 +67,8 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
|
||||
if (typeof interfaceConfig === 'object'
|
||||
&& participant
|
||||
&& !participant.local) {
|
||||
&& !participant.local
|
||||
&& !action.participant.isReplaced) {
|
||||
store.dispatch(showNotification({
|
||||
descriptionKey: 'notify.disconnected',
|
||||
titleKey: 'notify.somebody',
|
||||
|
|
Loading…
Reference in New Issue