diff --git a/JitsiConference.js b/JitsiConference.js index 2efc83a1d3..0c6f0f8119 100644 --- a/JitsiConference.js +++ b/JitsiConference.js @@ -3890,6 +3890,15 @@ JitsiConference.prototype.isMembersOnly = function() { return Boolean(this.room && this.room.membersOnlyEnabled); }; +/** + * Returns true if the room supports visitors feature. + * + * @returns {boolean} whether conference room has visitors support. + */ +JitsiConference.prototype.isVisitorsSupported = function() { + return Boolean(this.room && this.room.visitorsSupported); +}; + /** * Enables lobby by moderators * diff --git a/JitsiConferenceEventManager.js b/JitsiConferenceEventManager.js index af9cf92290..07b15e1e40 100644 --- a/JitsiConferenceEventManager.js +++ b/JitsiConferenceEventManager.js @@ -318,6 +318,8 @@ JitsiConferenceEventManager.prototype.setupChatRoomListeners = function() { this.chatRoomForwarder.forward(XMPPEvents.MUC_MEMBERS_ONLY_CHANGED, JitsiConferenceEvents.MEMBERS_ONLY_CHANGED); + this.chatRoomForwarder.forward(XMPPEvents.MUC_VISITORS_SUPPORTED_CHANGED, + JitsiConferenceEvents.VISITORS_SUPPORTED_CHANGED); chatRoom.addListener(XMPPEvents.MUC_MEMBER_JOINED, conference.onMemberJoined.bind(conference)); diff --git a/JitsiConferenceEvents.spec.ts b/JitsiConferenceEvents.spec.ts index 505269628c..00b400d9ce 100644 --- a/JitsiConferenceEvents.spec.ts +++ b/JitsiConferenceEvents.spec.ts @@ -1,5 +1,4 @@ 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 @@ -71,6 +70,7 @@ describe( "/JitsiConferenceEvents members", () => { VIDEO_UNMUTE_PERMISSIONS_CHANGED, VISITORS_MESSAGE, VISITORS_REJECTION, + VISITORS_SUPPORTED_CHANGED, BOT_TYPE_CHANGED, LOBBY_USER_JOINED, LOBBY_USER_UPDATED, @@ -133,6 +133,7 @@ describe( "/JitsiConferenceEvents members", () => { expect( RECORDER_STATE_CHANGED ).toBe( 'conference.recorderStateChanged' ); expect( VIDEO_SIP_GW_AVAILABILITY_CHANGED ).toBe( 'conference.videoSIPGWAvailabilityChanged' ); expect( VIDEO_SIP_GW_SESSION_STATE_CHANGED ).toBe( 'conference.videoSIPGWSessionStateChanged' ); + expect( VISITORS_SUPPORTED_CHANGED ).toBe( 'conference.visitorsSupported' ); expect( START_MUTED_POLICY_CHANGED ).toBe( 'conference.start_muted_policy_changed' ); expect( STARTED_MUTED ).toBe( 'conference.started_muted' ); expect( SUBJECT_CHANGED ).toBe( 'conference.subjectChanged' ); @@ -226,6 +227,7 @@ describe( "/JitsiConferenceEvents members", () => { expect( JitsiConferenceEvents.USER_ROLE_CHANGED ).toBe( 'conference.roleChanged' ); expect( JitsiConferenceEvents.USER_STATUS_CHANGED ).toBe( 'conference.statusChanged' ); expect( JitsiConferenceEvents.VIDEO_UNMUTE_PERMISSIONS_CHANGED ).toBe( 'conference.video_unmute_permissions_changed' ); + expect( JitsiConferenceEvents.VISITORS_SUPPORTED_CHANGED ).toBe( 'conference.visitorsSupported' ); expect( JitsiConferenceEvents.BOT_TYPE_CHANGED ).toBe( 'conference.bot_type_changed' ); expect( JitsiConferenceEvents.LOBBY_USER_JOINED ).toBe( 'conference.lobby.userJoined' ); expect( JitsiConferenceEvents.LOBBY_USER_UPDATED ).toBe( 'conference.lobby.userUpdated' ); diff --git a/JitsiConferenceEvents.ts b/JitsiConferenceEvents.ts index 8dd8fe5bce..d4314aa611 100644 --- a/JitsiConferenceEvents.ts +++ b/JitsiConferenceEvents.ts @@ -463,6 +463,11 @@ export enum JitsiConferenceEvents { */ VIDEO_UNMUTE_PERMISSIONS_CHANGED = 'conference.video_unmute_permissions_changed', + /** + * Indicates that the conference has support for visitors. + */ + VISITORS_SUPPORTED_CHANGED = 'conference.visitorsSupported', + /** * Event indicating we have received a message from the visitors component. */ @@ -551,5 +556,6 @@ export const USER_STATUS_CHANGED = JitsiConferenceEvents.USER_STATUS_CHANGED; export const VIDEO_SIP_GW_AVAILABILITY_CHANGED = JitsiConferenceEvents.VIDEO_SIP_GW_AVAILABILITY_CHANGED; export const VIDEO_SIP_GW_SESSION_STATE_CHANGED = JitsiConferenceEvents.VIDEO_SIP_GW_SESSION_STATE_CHANGED; export const VIDEO_UNMUTE_PERMISSIONS_CHANGED = JitsiConferenceEvents.VIDEO_UNMUTE_PERMISSIONS_CHANGED; +export const VISITORS_SUPPORTED_CHANGED = JitsiConferenceEvents.VISITORS_SUPPORTED_CHANGED; export const VISITORS_MESSAGE = JitsiConferenceEvents.VISITORS_MESSAGE; export const VISITORS_REJECTION = JitsiConferenceEvents.VISITORS_REJECTION; diff --git a/modules/xmpp/ChatRoom.js b/modules/xmpp/ChatRoom.js index 43c1ebe078..55fceb25f4 100644 --- a/modules/xmpp/ChatRoom.js +++ b/modules/xmpp/ChatRoom.js @@ -408,6 +408,14 @@ export default class ChatRoom extends Listenable { this.eventEmitter.emit(XMPPEvents.MUC_MEMBERS_ONLY_CHANGED, membersOnly); } + const visitorsSupported = $(result) + .find('>query>x[type="result"]>field[var="muc#roominfo_visitorsEnabled"]>value').text() === '1'; + + if (visitorsSupported !== this.visitorsSupported) { + this.visitorsSupported = visitorsSupported; + this.eventEmitter.emit(XMPPEvents.MUC_VISITORS_SUPPORTED_CHANGED, visitorsSupported); + } + const roomMetadataEl = $(result).find('>query>x[type="result"]>field[var="muc#roominfo_jitsimetadata"]>value'); const roomMetadataText = roomMetadataEl?.text(); diff --git a/service/xmpp/XMPPEvents.spec.ts b/service/xmpp/XMPPEvents.spec.ts index 462c793214..3e5d93df9d 100644 --- a/service/xmpp/XMPPEvents.spec.ts +++ b/service/xmpp/XMPPEvents.spec.ts @@ -58,6 +58,7 @@ describe( "/service/xmpp/XMPPEvents members", () => { expect( XMPPEvents.MUC_ROLE_CHANGED ).toBe( 'xmpp.muc_role_changed' ); expect( XMPPEvents.MUC_LOCK_CHANGED ).toBe( 'xmpp.muc_lock_changed' ); expect( XMPPEvents.MUC_MEMBERS_ONLY_CHANGED ).toBe( 'xmpp.muc_members_only_changed' ); + expect( XMPPEvents.MUC_VISITORS_SUPPORTED_CHANGED ).toBe( 'xmpp.muc_visitors_supported_changed' ); expect( XMPPEvents.PARTICIPANT_AUDIO_MUTED ).toBe( 'xmpp.audio_muted' ); expect( XMPPEvents.PARTICIPANT_VIDEO_MUTED ).toBe( 'xmpp.video_muted' ); expect( XMPPEvents.PARTICIPANT_VIDEO_TYPE_CHANGED ).toBe( 'xmpp.video_type' ); @@ -114,4 +115,4 @@ describe( "/service/xmpp/XMPPEvents members", () => { const keys = Object.keys( others ); expect( keys ).withContext( `Extra members: ${ keys.join( ", " ) }` ).toEqual( [] ); } ); -} ); \ No newline at end of file +} ); diff --git a/service/xmpp/XMPPEvents.ts b/service/xmpp/XMPPEvents.ts index 4ec1a5e830..5d1acb12e6 100644 --- a/service/xmpp/XMPPEvents.ts +++ b/service/xmpp/XMPPEvents.ts @@ -173,6 +173,9 @@ export enum XMPPEvents { // Designates an event indicating that the MUC members only config has changed. MUC_MEMBERS_ONLY_CHANGED = 'xmpp.muc_members_only_changed', + // Designates an event indicating that the MUC visitors support has changed. + MUC_VISITORS_SUPPORTED_CHANGED = 'xmpp.muc_visitors_supported_changed', + // Designates an event indicating that a participant in the XMPP MUC has // advertised that they have audio muted (or unmuted). PARTICIPANT_AUDIO_MUTED = 'xmpp.audio_muted',