diff --git a/JitsiConferenceEventManager.js b/JitsiConferenceEventManager.js index 144e3cc1bb..279141665b 100644 --- a/JitsiConferenceEventManager.js +++ b/JitsiConferenceEventManager.js @@ -696,6 +696,11 @@ JitsiConferenceEventManager.prototype.setupXMPPListeners = function() { value => { conference.eventEmitter.emit(JitsiConferenceEvents.AV_MODERATION_REJECTED, { mediaType: value }); }); + + this._addConferenceXMPPListener(XMPPEvents.VISITORS_MESSAGE, + value => conference.eventEmitter.emit(JitsiConferenceEvents.VISITORS_MESSAGE, value)); + this._addConferenceXMPPListener(XMPPEvents.VISITORS_REJECTION, + () => conference.eventEmitter.emit(JitsiConferenceEvents.VISITORS_REJECTION)); }; /** diff --git a/JitsiConferenceEvents.spec.ts b/JitsiConferenceEvents.spec.ts index 3980b49236..505269628c 100644 --- a/JitsiConferenceEvents.spec.ts +++ b/JitsiConferenceEvents.spec.ts @@ -1,4 +1,5 @@ import * as exported from "./JitsiConferenceEvents"; +import {VISITORS_MESSAGE, VISITORS_REJECTION} from "./JitsiConferenceEvents"; // this test is brittle on purpose because it's designed to ensure that the TypeScript conversion maintains backward compatibility @@ -68,6 +69,8 @@ describe( "/JitsiConferenceEvents members", () => { USER_ROLE_CHANGED, USER_STATUS_CHANGED, VIDEO_UNMUTE_PERMISSIONS_CHANGED, + VISITORS_MESSAGE, + VISITORS_REJECTION, BOT_TYPE_CHANGED, LOBBY_USER_JOINED, LOBBY_USER_UPDATED, @@ -146,6 +149,8 @@ describe( "/JitsiConferenceEvents members", () => { expect( USER_ROLE_CHANGED ).toBe( 'conference.roleChanged' ); expect( USER_STATUS_CHANGED ).toBe( 'conference.statusChanged' ); expect( VIDEO_UNMUTE_PERMISSIONS_CHANGED ).toBe( 'conference.video_unmute_permissions_changed' ); + expect( VISITORS_MESSAGE ).toBe( 'conference.visitors_message' ); + expect( VISITORS_REJECTION ).toBe( 'conference.visitors_rejection' ); expect( BOT_TYPE_CHANGED ).toBe( 'conference.bot_type_changed' ); expect( LOBBY_USER_JOINED ).toBe( 'conference.lobby.userJoined' ); expect( LOBBY_USER_UPDATED ).toBe( 'conference.lobby.userUpdated' ); diff --git a/JitsiConferenceEvents.ts b/JitsiConferenceEvents.ts index b02b29d3ca..799435a6f1 100644 --- a/JitsiConferenceEvents.ts +++ b/JitsiConferenceEvents.ts @@ -235,7 +235,7 @@ export enum JitsiConferenceEvents { PARTCIPANT_FEATURES_CHANGED = 'conference.partcipant_features_changed', /** - * Indicates that a the value of a specific property of a specific participant + * Indicates that a value of a specific property of a specific participant * has changed. */ PARTICIPANT_PROPERTY_CHANGED = 'conference.participant_property_changed', @@ -280,7 +280,7 @@ export enum JitsiConferenceEvents { * {string} address, * {VideoSIPGWConstants} oldState, * {VideoSIPGWConstants} newState, - * {string} displayName} + * {string} displayName * }. */ VIDEO_SIP_GW_SESSION_STATE_CHANGED = 'conference.videoSIPGWSessionStateChanged', @@ -378,6 +378,16 @@ export enum JitsiConferenceEvents { */ VIDEO_UNMUTE_PERMISSIONS_CHANGED = 'conference.video_unmute_permissions_changed', + /** + * Event indicating we have received a message from the visitors component. + */ + VISITORS_MESSAGE = 'conference.visitors_message', + + /** + * Event indicating that our request for promotion was rejected. + */ + VISITORS_REJECTION = 'conference.visitors_rejection', + /** * Event indicates that the bot participant type changed. */ @@ -464,7 +474,7 @@ export enum JitsiConferenceEvents { E2EE_VERIFICATION_READY = 'conference.e2ee.verification.ready', E2EE_VERIFICATION_COMPLETED = 'conference.e2ee.verification.completed' -}; +} // exported for backward compatibility export const AUDIO_INPUT_STATE_CHANGE = JitsiConferenceEvents.AUDIO_INPUT_STATE_CHANGE; @@ -531,6 +541,8 @@ export const USER_LEFT = JitsiConferenceEvents.USER_LEFT; export const USER_ROLE_CHANGED = JitsiConferenceEvents.USER_ROLE_CHANGED; export const USER_STATUS_CHANGED = JitsiConferenceEvents.USER_STATUS_CHANGED; export const VIDEO_UNMUTE_PERMISSIONS_CHANGED = JitsiConferenceEvents.VIDEO_UNMUTE_PERMISSIONS_CHANGED; +export const VISITORS_MESSAGE = JitsiConferenceEvents.VISITORS_MESSAGE; +export const VISITORS_REJECTION = JitsiConferenceEvents.VISITORS_REJECTION; export const BOT_TYPE_CHANGED = JitsiConferenceEvents.BOT_TYPE_CHANGED; export const LOBBY_USER_JOINED = JitsiConferenceEvents.LOBBY_USER_JOINED; export const LOBBY_USER_UPDATED = JitsiConferenceEvents.LOBBY_USER_UPDATED; diff --git a/modules/xmpp/strophe.emuc.js b/modules/xmpp/strophe.emuc.js index 43b4ab147a..14c720d0a3 100644 --- a/modules/xmpp/strophe.emuc.js +++ b/modules/xmpp/strophe.emuc.js @@ -224,12 +224,15 @@ export default class MucConnectionPlugin extends ConnectionPluginListenable { const visitors = $(iq).find('>visitors[xmlns="jitsi:visitors"]'); const response = $(iq).find('promotion-response'); - if (visitors.length && response.length - && String(response.attr('allow')).toLowerCase() === 'true') { - logger.warn('Redirected back to main room.'); - - this.xmpp.eventEmitter.emit( - CONNECTION_REDIRECTED, undefined, visitors.attr('focusjid'), response.attr('username')); + if (visitors.length && response.length) { + if (String(response.attr('allow')).toLowerCase() === 'true') { + logger.info('Promotion request accepted. Redirected to main room.'); + this.xmpp.eventEmitter.emit( + CONNECTION_REDIRECTED, undefined, visitors.attr('focusjid'), response.attr('username')); + } else { + logger.info('Promotion request rejected.'); + this.xmpp.eventEmitter.emit(XMPPEvents.VISITORS_REJECTION); + } } return true; diff --git a/modules/xmpp/xmpp.js b/modules/xmpp/xmpp.js index e6d9a6af76..60b7073e35 100644 --- a/modules/xmpp/xmpp.js +++ b/modules/xmpp/xmpp.js @@ -525,6 +525,10 @@ export default class XMPP extends Listenable { this.roomMetadataComponentAddress = identity.name; this._components.push(this.roomMetadataComponentAddress); } + + if (identity.type === 'visitors') { + this._components.push(identity.name); + } }); this._maybeSendDeploymentInfoStat(true); @@ -1080,6 +1084,8 @@ export default class XMPP extends Listenable { this.eventEmitter.emit(XMPPEvents.BREAKOUT_ROOMS_EVENT, parsedJson); } else if (parsedJson[JITSI_MEET_MUC_TYPE] === 'room_metadata') { this.eventEmitter.emit(XMPPEvents.ROOM_METADATA_EVENT, parsedJson); + } else if (parsedJson[JITSI_MEET_MUC_TYPE] === 'visitors') { + this.eventEmitter.emit(XMPPEvents.VISITORS_MESSAGE, parsedJson); } return true; diff --git a/service/xmpp/XMPPEvents.ts b/service/xmpp/XMPPEvents.ts index 1117ba4102..82197faecc 100644 --- a/service/xmpp/XMPPEvents.ts +++ b/service/xmpp/XMPPEvents.ts @@ -385,6 +385,16 @@ export enum XMPPEvents { */ VIDEO_SIP_GW_SESSION_STATE_CHANGED = 'xmpp.videoSIPGWSessionStateChanged', + /** + * Event indicating we have received a message from the visitors component. + */ + VISITORS_MESSAGE = 'xmpp.visitors_message', + + /** + * Event indicating that our request for promotion was rejected. + */ + VISITORS_REJECTION = 'xmpp.visitors_rejection', + // Designates an event indicating that the local ICE connection state has // changed. ICE_CONNECTION_STATE_CHANGED = 'xmpp.ice_connection_state_changed',