Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 48 additions & 21 deletions modules/xmpp/BreakoutRooms.js → modules/xmpp/BreakoutRooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { $msg, Strophe } from 'strophe.js';

import { XMPPEvents } from '../../service/xmpp/XMPPEvents';

import ChatRoom from './ChatRoom';

const FEATURE_KEY = 'features/breakout-rooms';
const BREAKOUT_ROOM_ACTIONS = {
ADD: `${FEATURE_KEY}/add`,
Expand All @@ -17,17 +19,42 @@ const BREAKOUT_ROOM_EVENTS = {

const logger = getLogger('xmpp:BreakoutRooms');

/**
* Types for breakout room participants and rooms.
*/
export interface IBreakoutRoomParticipant {
jid: string;
}

export interface IBreakoutRoom {
participants?: { [key: string]: IBreakoutRoomParticipant; };
}

export interface IBreakoutRoomsUpdatePayload {
event: string;
rooms: { [key: string]: IBreakoutRoom; };
}

export interface IBreakoutRoomsMoveToRoomPayload {
event: string;
roomJid: string;
}

/**
* Helper class for handling breakout rooms.
*/
export default class BreakoutRooms {
private room: ChatRoom;
private _rooms: { [key: string]: IBreakoutRoom; };
private _isBreakoutRoom?: boolean;
private _mainRoomJid?: string;

/**
* Constructs breakout room.
*
* @param {ChatRoom} room the room we are in.
*/
constructor(room) {
constructor(room: ChatRoom) {
this.room = room;

this._handleMessages = this._handleMessages.bind(this);
Expand All @@ -39,7 +66,7 @@ export default class BreakoutRooms {
/**
* Stops listening for events.
*/
dispose() {
dispose(): void {
this.room.xmpp.removeListener(XMPPEvents.BREAKOUT_ROOMS_EVENT, this._handleMessages);
}

Expand All @@ -48,7 +75,7 @@ export default class BreakoutRooms {
*
* @param {string} subject - A subject for the breakout room.
*/
createBreakoutRoom(subject) {
createBreakoutRoom(subject: string): void {
if (!this.isSupported() || !this.room.isModerator()) {
logger.error(`Cannot create breakout room - supported:${this.isSupported()},
moderator:${this.room.isModerator()}`);
Expand All @@ -69,7 +96,7 @@ export default class BreakoutRooms {
*
* @param {string} breakoutRoomJid - JID of the room to be removed.
*/
removeBreakoutRoom(breakoutRoomJid) {
removeBreakoutRoom(breakoutRoomJid: string): void {
if (!this.isSupported() || !this.room.isModerator()) {
logger.error(`Cannot remove breakout room - supported:${this.isSupported()},
moderator:${this.room.isModerator()}`);
Expand All @@ -91,7 +118,7 @@ export default class BreakoutRooms {
* @param {string} breakoutRoomJid - JID of the room to be removed.
* @param {string} subject - A new subject for the breakout room.
*/
renameBreakoutRoom(breakoutRoomJid, subject) {
renameBreakoutRoom(breakoutRoomJid: string, subject: string): void {
if (!this.isSupported() || !this.room.isModerator()) {
logger.error(`Cannot rename breakout room - supported:${this.isSupported()},
moderator:${this.room.isModerator()}`);
Expand All @@ -115,7 +142,7 @@ export default class BreakoutRooms {
* @param {string} participantJid - JID of the participant to be sent to a room.
* @param {string} roomJid - JID of the target room.
*/
sendParticipantToRoom(participantJid, roomJid) {
sendParticipantToRoom(participantJid: string, roomJid: string): void {
if (!this.isSupported() || !this.room.isModerator()) {
logger.error(`Cannot send participant to room - supported:${this.isSupported()},
moderator:${this.room.isModerator()}`);
Expand All @@ -138,14 +165,14 @@ export default class BreakoutRooms {
* @param {string} feature - Feature to check.
* @returns Wether the feature is supported.
*/
isFeatureSupported(feature) {
return Boolean((this.room.xmpp.breakoutRoomsFeatures || {})[feature]);
isFeatureSupported(feature: string): boolean {
return Boolean(this.room.xmpp.breakoutRoomsFeatures?.[feature]);
}

/**
* Whether Breakout Rooms support is enabled in the backend or not.
*/
isSupported() {
isSupported(): boolean {
return Boolean(this.getComponentAddress());
}

Expand All @@ -154,7 +181,7 @@ export default class BreakoutRooms {
*
* @returns The address of the component.
*/
getComponentAddress() {
getComponentAddress(): Optional<string> {
return this.room.xmpp.breakoutRoomsComponentAddress;
}

Expand All @@ -163,7 +190,7 @@ export default class BreakoutRooms {
*
* @param {boolean} isBreakoutRoom - Whether this room is a breakout room.
*/
_setIsBreakoutRoom(isBreakoutRoom) {
_setIsBreakoutRoom(isBreakoutRoom: boolean): void {
this._isBreakoutRoom = isBreakoutRoom;
}

Expand All @@ -172,7 +199,7 @@ export default class BreakoutRooms {
*
* @returns True if the room is a breakout room, false otherwise.
*/
isBreakoutRoom() {
isBreakoutRoom(): boolean {
if (typeof this._isBreakoutRoom !== 'undefined') {
return this._isBreakoutRoom;
}
Expand All @@ -187,7 +214,7 @@ export default class BreakoutRooms {
*
* @param {string} jid - The main room JID.
*/
_setMainRoomJid(jid) {
_setMainRoomJid(jid: string): void {
this._mainRoomJid = jid;
}

Expand All @@ -196,7 +223,7 @@ export default class BreakoutRooms {
*
* @returns The main room JID.
*/
getMainRoomJid() {
getMainRoomJid(): Optional<string> {
return this._mainRoomJid;
}

Expand All @@ -205,13 +232,13 @@ export default class BreakoutRooms {
*
* @param {object} payload - Arbitrary data.
*/
_handleMessages(payload) {
_handleMessages(payload: IBreakoutRoomsUpdatePayload | IBreakoutRoomsMoveToRoomPayload): void {
switch (payload.event) {
case BREAKOUT_ROOM_EVENTS.MOVE_TO_ROOM:
this.room.eventEmitter.emit(XMPPEvents.BREAKOUT_ROOMS_MOVE_TO_ROOM, payload.roomJid);
this.room.eventEmitter.emit(XMPPEvents.BREAKOUT_ROOMS_MOVE_TO_ROOM, (payload as IBreakoutRoomsMoveToRoomPayload).roomJid);
break;
case BREAKOUT_ROOM_EVENTS.UPDATE: {
const filteredPayload = this._filterUpdatePayload(payload);
const filteredPayload = this._filterUpdatePayload(payload as IBreakoutRoomsUpdatePayload);

this._rooms = filteredPayload.rooms;
this.room.eventEmitter.emit(XMPPEvents.BREAKOUT_ROOMS_UPDATED, filteredPayload);
Expand All @@ -226,14 +253,14 @@ export default class BreakoutRooms {
* @param {Object} payload - The payload of the update message.
* @return {Object} - The filtered payload.
*/
_filterUpdatePayload(payload) {
_filterUpdatePayload(payload: IBreakoutRoomsUpdatePayload): IBreakoutRoomsUpdatePayload {
const hiddenDomain = this.room.options.hiddenDomain;
const { rooms } = payload;
const filteredRooms = {};
const filteredRooms: { [key: string]: IBreakoutRoom; } = {};

Object.entries(rooms).forEach(([ key, room ]) => {
const { participants = {} } = room;
const filteredParticipants = {};
const filteredParticipants: { [key: string]: IBreakoutRoomParticipant; } = {};

Object.entries(participants).forEach(([ k, participant ]) => {
if (Strophe.getDomainFromJid(participant.jid) !== hiddenDomain) {
Expand All @@ -258,7 +285,7 @@ export default class BreakoutRooms {
*
* @param {Object} message - Command that needs to be sent.
*/
_sendMessage(message) {
_sendMessage(message: { [key: string]: unknown; }): void {
const msg = $msg({ to: this.getComponentAddress() });

msg.c('breakout_rooms', message).up();
Expand Down
5 changes: 4 additions & 1 deletion modules/xmpp/ChatRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,6 @@ export default class ChatRoom extends Listenable {
private _removeConnListeners: (() => void)[];
private inProgressEmitted: boolean;
private noBridgeAvailable: boolean;
private options: IChatRoomOptions;
private eventsForwarder: EventEmitterForwarder;
private lobby?: Lobby;
private avModeration: AVModeration;
Expand All @@ -246,6 +245,10 @@ export default class ChatRoom extends Listenable {
private subject?: string;
private _roomCreationRetries?: number;
private cachedShortTermCredentials?: Record<string, string>;
/**
* @internal
*/
options: IChatRoomOptions;
public xmpp: XMPP;
public connection: XmppConnection;
public roomjid: string;
Expand Down