123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- import { IStore } from '../app/types';
- import { conferenceWillJoin, setPassword } from '../base/conference/actions';
- import { getCurrentConference, sendLocalParticipant } from '../base/conference/functions';
- import { getLocalParticipant } from '../base/participants/functions';
- import { IParticipant } from '../base/participants/types';
- import { onLobbyChatInitialized, removeLobbyChatParticipant, sendMessage } from '../chat/actions.any';
- import { LOBBY_CHAT_MESSAGE } from '../chat/constants';
- import { handleLobbyMessageReceived } from '../chat/middleware';
- import { hideNotification, showNotification } from '../notifications/actions';
- import { LOBBY_NOTIFICATION_ID } from '../notifications/constants';
-
- import {
- KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED,
- KNOCKING_PARTICIPANT_LEFT,
- REMOVE_LOBBY_CHAT_WITH_MODERATOR,
- SET_KNOCKING_STATE,
- SET_LOBBY_MODE_ENABLED,
- SET_LOBBY_PARTICIPANT_CHAT_STATE,
- SET_LOBBY_VISIBILITY,
- SET_PASSWORD_JOIN_FAILED
- } from './actionTypes';
- import { LOBBY_CHAT_INITIALIZED, MODERATOR_IN_CHAT_WITH_LEFT } from './constants';
- import { getKnockingParticipants, getLobbyEnabled } from './functions';
- import { IKnockingParticipant } from './types';
-
- /**
- * Tries to join with a preset password.
- *
- * @param {string} password - The password to join with.
- * @returns {Function}
- */
- export function joinWithPassword(password: string) {
- return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const conference = getCurrentConference(getState);
-
- dispatch(setPassword(conference, conference.join, password));
- };
- }
-
- /**
- * Action to be dispatched when a knocking poarticipant leaves before any response.
- *
- * @param {string} id - The ID of the participant.
- * @returns {{
- * id: string,
- * type: KNOCKING_PARTICIPANT_LEFT
- * }}
- */
- export function knockingParticipantLeft(id: string) {
- return {
- id,
- type: KNOCKING_PARTICIPANT_LEFT
- };
- }
-
- /**
- * Action to be executed when a participant starts knocking or an already knocking participant gets updated.
- *
- * @param {Object} participant - The knocking participant.
- * @returns {{
- * participant: Object,
- * type: KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED
- * }}
- */
- export function participantIsKnockingOrUpdated(participant: IKnockingParticipant | Object) {
- return {
- participant,
- type: KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED
- };
- }
-
- /**
- * Handles a knocking participant and dismisses the notification.
- *
- * @param {string} id - The id of the knocking participant.
- * @param {boolean} approved - True if the participant is approved, false otherwise.
- * @returns {Function}
- */
- export function answerKnockingParticipant(id: string, approved: boolean) {
- return async (dispatch: IStore['dispatch']) => {
- dispatch(setKnockingParticipantApproval(id, approved));
- dispatch(hideNotification(LOBBY_NOTIFICATION_ID));
- };
- }
-
- /**
- * Approves (lets in) or rejects a knocking participant.
- *
- * @param {string} id - The id of the knocking participant.
- * @param {boolean} approved - True if the participant is approved, false otherwise.
- * @returns {Function}
- */
- export function setKnockingParticipantApproval(id: string, approved: boolean) {
- return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const conference = getCurrentConference(getState);
-
- if (conference) {
- if (approved) {
- conference.lobbyApproveAccess(id);
- } else {
- conference.lobbyDenyAccess(id);
- }
- }
- };
- }
-
- /**
- * Action used to admit multiple participants in the conference.
- *
- * @param {Array<Object>} participants - A list of knocking participants.
- * @returns {void}
- */
- export function admitMultiple(participants: Array<IKnockingParticipant>) {
- return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const conference = getCurrentConference(getState);
-
- participants.forEach(p => {
- conference.lobbyApproveAccess(p.id);
- });
- };
- }
-
- /**
- * Approves the request of a knocking participant to join the meeting.
- *
- * @param {string} id - The id of the knocking participant.
- * @returns {Function}
- */
- export function approveKnockingParticipant(id: string) {
- return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const conference = getCurrentConference(getState);
-
- conference?.lobbyApproveAccess(id);
- };
- }
-
- /**
- * Denies the request of a knocking participant to join the meeting.
- *
- * @param {string} id - The id of the knocking participant.
- * @returns {Function}
- */
- export function rejectKnockingParticipant(id: string) {
- return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const conference = getCurrentConference(getState);
-
- conference?.lobbyDenyAccess(id);
- };
- }
-
- /**
- * Action to set the knocking state of the participant.
- *
- * @param {boolean} knocking - The new state.
- * @returns {{
- * state: boolean,
- * type: SET_KNOCKING_STATE
- * }}
- */
- export function setKnockingState(knocking: boolean) {
- return {
- knocking,
- type: SET_KNOCKING_STATE
- };
- }
-
- /**
- * Action to set the new state of the lobby mode.
- *
- * @param {boolean} enabled - The new state to set.
- * @returns {{
- * enabled: boolean,
- * type: SET_LOBBY_MODE_ENABLED
- * }}
- */
- export function setLobbyModeEnabled(enabled: boolean) {
- return {
- enabled,
- type: SET_LOBBY_MODE_ENABLED
- };
- }
-
- /**
- * Action to be dispatched when we failed to join with a password.
- *
- * @param {boolean} failed - True of recent password join failed.
- * @returns {{
- * failed: boolean,
- * type: SET_PASSWORD_JOIN_FAILED
- * }}
- */
- export function setPasswordJoinFailed(failed: boolean) {
- return {
- failed,
- type: SET_PASSWORD_JOIN_FAILED
- };
- }
-
- /**
- * Starts knocking and waiting for approval.
- *
- * @returns {Function}
- */
- export function startKnocking() {
- return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const state = getState();
- const { membersOnly } = state['features/base/conference'];
- const localParticipant = getLocalParticipant(state);
-
- // @ts-ignore
- dispatch(conferenceWillJoin(membersOnly));
-
- // We need to update the conference object with the current display name, if approved
- // we want to send that display name, it was not updated in case when pre-join is disabled
- // @ts-ignore
- sendLocalParticipant(state, membersOnly);
-
- membersOnly?.joinLobby(localParticipant?.name, localParticipant?.email);
- dispatch(setLobbyMessageListener());
- dispatch(setKnockingState(true));
- };
- }
-
- /**
- * Action to toggle lobby mode on or off.
- *
- * @param {boolean} enabled - The desired (new) state of the lobby mode.
- * @returns {Function}
- */
- export function toggleLobbyMode(enabled: boolean) {
- return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const conference = getCurrentConference(getState);
-
- if (enabled) {
- conference.enableLobby();
- } else {
- conference.disableLobby();
- }
- };
- }
-
- /**
- * Action to open the lobby screen.
- *
- * @returns {openDialog}
- */
- export function openLobbyScreen() {
- return {
- type: SET_LOBBY_VISIBILITY,
- visible: true
- };
- }
-
- /**
- * Action to hide the lobby screen.
- *
- * @returns {hideDialog}
- */
- export function hideLobbyScreen() {
- return {
- type: SET_LOBBY_VISIBILITY,
- visible: false
- };
- }
-
- /**
- * Action to handle chat initialized in the lobby room.
- *
- * @param {Object} payload - The payload received,
- * contains the information about the two participants
- * that will chat with each other in the lobby room.
- *
- * @returns {Promise<void>}
- */
- export function handleLobbyChatInitialized(payload: { attendee: IParticipant; moderator: IParticipant; }) {
- return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const state = getState();
- const conference = getCurrentConference(state);
-
- const id = conference.myLobbyUserId();
-
- dispatch({
- type: SET_LOBBY_PARTICIPANT_CHAT_STATE,
- participant: payload.attendee,
- moderator: payload.moderator
- });
-
- dispatch(onLobbyChatInitialized(payload));
-
- const attendeeIsKnocking = getKnockingParticipants(state).some(p => p.id === payload.attendee.id);
-
- if (attendeeIsKnocking && conference.getRole() === 'moderator' && payload.moderator.id !== id) {
- dispatch(showNotification({
- titleKey: 'lobby.lobbyChatStartedNotification',
- titleArguments: {
- moderator: payload.moderator.name ?? '',
- attendee: payload.attendee.name ?? ''
- }
- }));
- }
- };
- }
-
- /**
- * Action to send message to the moderator.
- *
- * @param {string} message - The message to be sent.
- *
- * @returns {Promise<void>}
- */
- export function onSendMessage(message: string) {
- return async (dispatch: IStore['dispatch']) => {
- dispatch(sendMessage(message));
- };
- }
-
- /**
- * Action to send lobby message to every participant. Only allowed for moderators.
- *
- * @param {Object} message - The message to be sent.
- *
- * @returns {Promise<void>}
- */
- export function sendLobbyChatMessage(message: Object) {
- return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const conference = getCurrentConference(getState);
-
- conference.sendLobbyMessage(message);
- };
- }
-
- /**
- * Sets lobby listeners if lobby has been enabled.
- *
- * @returns {Function}
- */
- export function maybeSetLobbyChatMessageListener() {
- return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const state = getState();
- const lobbyEnabled = getLobbyEnabled(state);
-
- if (lobbyEnabled) {
- dispatch(setLobbyMessageListener());
- }
- };
- }
-
- /**
- * Action to handle the event when a moderator leaves during lobby chat.
- *
- * @param {string} participantId - The participant id of the moderator who left.
- * @returns {Function}
- */
- export function updateLobbyParticipantOnLeave(participantId: string) {
- return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const state = getState();
- const { knocking, knockingParticipants } = state['features/lobby'];
- const { lobbyMessageRecipient } = state['features/chat'];
- const { conference } = state['features/base/conference'];
-
- if (knocking && lobbyMessageRecipient && lobbyMessageRecipient.id === participantId) {
- return dispatch(removeLobbyChatParticipant(true));
- }
-
- if (!knocking) {
- // inform knocking participant when their moderator leaves
- const participantToNotify = knockingParticipants.find(p => p.chattingWithModerator === participantId);
-
- if (participantToNotify) {
- conference?.sendLobbyMessage({
- type: MODERATOR_IN_CHAT_WITH_LEFT,
- moderatorId: participantToNotify.chattingWithModerator
- }, participantToNotify.id);
- }
- dispatch({
- type: REMOVE_LOBBY_CHAT_WITH_MODERATOR,
- moderatorId: participantId
- });
- }
- };
- }
-
- /**
- * Handles all messages received in the lobby room.
- *
- * @returns {Function}
- */
- export function setLobbyMessageListener() {
- return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
- const state = getState();
- const conference = getCurrentConference(state);
- const { enableLobbyChat = true } = state['features/base/config'];
-
- if (!enableLobbyChat) {
- return;
- }
-
- conference.addLobbyMessageListener((message: any, participantId: string) => {
- if (message.type === LOBBY_CHAT_MESSAGE) {
- return dispatch(handleLobbyMessageReceived(message.message, participantId));
- }
- if (message.type === LOBBY_CHAT_INITIALIZED) {
- return dispatch(handleLobbyChatInitialized(message));
- }
- if (message.type === MODERATOR_IN_CHAT_WITH_LEFT) {
- return dispatch(updateLobbyParticipantOnLeave(message.moderatorId));
- }
- });
- };
- }
|