2022-10-17 11:28:01 +00:00
|
|
|
/* eslint-disable lines-around-comment */
|
|
|
|
import { createStartMutedConfigurationEvent } from '../../analytics/AnalyticsEvents';
|
|
|
|
import { sendAnalytics } from '../../analytics/functions';
|
2022-08-26 18:25:04 +00:00
|
|
|
import { appNavigate } from '../../app/actions';
|
2022-10-20 09:11:27 +00:00
|
|
|
import { IReduxState, IStore } from '../../app/types';
|
2022-10-17 11:28:01 +00:00
|
|
|
import { endpointMessageReceived } from '../../subtitles/actions.any';
|
2021-06-16 11:08:18 +00:00
|
|
|
import { getReplaceParticipant } from '../config/functions';
|
2022-10-17 11:28:01 +00:00
|
|
|
import { disconnect } from '../connection/actions';
|
|
|
|
import { JITSI_CONNECTION_CONFERENCE_KEY } from '../connection/constants';
|
2022-04-01 12:50:52 +00:00
|
|
|
import { JitsiConferenceEvents, JitsiE2ePingEvents } from '../lib-jitsi-meet';
|
2022-10-17 11:28:01 +00:00
|
|
|
import { setAudioMuted, setAudioUnmutePermissions, setVideoMuted, setVideoUnmutePermissions } from '../media/actions';
|
|
|
|
import { MEDIA_TYPE } from '../media/constants';
|
2016-10-05 14:36:59 +00:00
|
|
|
import {
|
|
|
|
dominantSpeakerChanged,
|
2017-04-05 09:01:57 +00:00
|
|
|
participantConnectionStatusChanged,
|
2019-06-17 14:00:09 +00:00
|
|
|
participantKicked,
|
|
|
|
participantMutedUs,
|
2018-06-20 13:45:22 +00:00
|
|
|
participantPresenceChanged,
|
2017-03-23 18:01:33 +00:00
|
|
|
participantRoleChanged,
|
|
|
|
participantUpdated
|
2022-10-17 11:28:01 +00:00
|
|
|
} from '../participants/actions';
|
|
|
|
import { getNormalizedDisplayName } from '../participants/functions';
|
|
|
|
import { toState } from '../redux/functions';
|
2021-12-09 13:48:55 +00:00
|
|
|
import {
|
|
|
|
destroyLocalTracks,
|
|
|
|
replaceLocalTrack,
|
|
|
|
trackAdded,
|
|
|
|
trackRemoved
|
2022-10-17 11:28:01 +00:00
|
|
|
} from '../tracks/actions.any';
|
|
|
|
import { getLocalTracks } from '../tracks/functions';
|
|
|
|
import { getBackendSafeRoomName } from '../util/uri';
|
2016-10-05 14:36:59 +00:00
|
|
|
|
|
|
|
import {
|
2018-06-20 20:19:53 +00:00
|
|
|
AUTH_STATUS_CHANGED,
|
2016-12-12 01:02:50 +00:00
|
|
|
CONFERENCE_FAILED,
|
2016-10-05 14:36:59 +00:00
|
|
|
CONFERENCE_JOINED,
|
2022-09-27 07:10:28 +00:00
|
|
|
CONFERENCE_JOIN_IN_PROGRESS,
|
2016-10-05 14:36:59 +00:00
|
|
|
CONFERENCE_LEFT,
|
2021-12-17 07:38:15 +00:00
|
|
|
CONFERENCE_LOCAL_SUBJECT_CHANGED,
|
2019-03-12 17:45:53 +00:00
|
|
|
CONFERENCE_SUBJECT_CHANGED,
|
2020-01-13 17:12:25 +00:00
|
|
|
CONFERENCE_TIMESTAMP_CHANGED,
|
2021-02-03 10:28:39 +00:00
|
|
|
CONFERENCE_UNIQUE_ID_SET,
|
2017-01-18 19:28:52 +00:00
|
|
|
CONFERENCE_WILL_JOIN,
|
2016-10-05 14:36:59 +00:00
|
|
|
CONFERENCE_WILL_LEAVE,
|
2017-08-09 19:40:03 +00:00
|
|
|
DATA_CHANNEL_OPENED,
|
2022-04-01 12:50:52 +00:00
|
|
|
E2E_RTT_CHANGED,
|
2018-03-20 18:07:51 +00:00
|
|
|
KICKED_OUT,
|
2016-12-12 19:49:23 +00:00
|
|
|
LOCK_STATE_CHANGED,
|
2021-09-14 15:31:30 +00:00
|
|
|
NON_PARTICIPANT_MESSAGE_RECEIVED,
|
2017-08-09 19:40:03 +00:00
|
|
|
P2P_STATUS_CHANGED,
|
2019-08-30 21:17:22 +00:00
|
|
|
SEND_TONES,
|
2017-11-21 02:21:35 +00:00
|
|
|
SET_FOLLOW_ME,
|
2022-06-21 06:53:07 +00:00
|
|
|
SET_OBFUSCATED_ROOM,
|
2016-12-12 01:02:50 +00:00
|
|
|
SET_PASSWORD,
|
2017-04-13 00:23:43 +00:00
|
|
|
SET_PASSWORD_FAILED,
|
2019-03-12 17:45:53 +00:00
|
|
|
SET_PENDING_SUBJECT_CHANGE,
|
2022-09-27 07:10:28 +00:00
|
|
|
SET_ROOM,
|
2021-11-10 11:19:40 +00:00
|
|
|
SET_START_MUTED_POLICY,
|
|
|
|
SET_START_REACTIONS_MUTED
|
2016-10-05 14:36:59 +00:00
|
|
|
} from './actionTypes';
|
2017-02-28 23:12:02 +00:00
|
|
|
import {
|
|
|
|
AVATAR_URL_COMMAND,
|
2017-08-01 00:40:55 +00:00
|
|
|
EMAIL_COMMAND,
|
|
|
|
JITSI_CONFERENCE_URL_KEY
|
2017-02-28 23:12:02 +00:00
|
|
|
} from './constants';
|
2017-10-06 17:52:23 +00:00
|
|
|
import {
|
|
|
|
_addLocalTracksToConference,
|
2018-08-16 15:11:06 +00:00
|
|
|
commonUserJoinedHandling,
|
|
|
|
commonUserLeftHandling,
|
2021-08-04 10:56:07 +00:00
|
|
|
getConferenceOptions,
|
2022-08-26 18:25:04 +00:00
|
|
|
getConferenceState,
|
2022-09-27 07:10:28 +00:00
|
|
|
getCurrentConference,
|
2017-10-13 19:31:05 +00:00
|
|
|
sendLocalParticipant
|
2017-10-06 17:52:23 +00:00
|
|
|
} from './functions';
|
2019-08-21 14:50:00 +00:00
|
|
|
import logger from './logger';
|
2022-10-17 11:28:01 +00:00
|
|
|
import { IJitsiConference } from './reducer';
|
2017-11-21 02:21:35 +00:00
|
|
|
|
2016-10-05 14:36:59 +00:00
|
|
|
/**
|
2016-12-12 00:29:13 +00:00
|
|
|
* Adds conference (event) listeners.
|
2016-10-05 14:36:59 +00:00
|
|
|
*
|
2016-12-12 00:29:13 +00:00
|
|
|
* @param {JitsiConference} conference - The JitsiConference instance.
|
|
|
|
* @param {Dispatch} dispatch - The Redux dispatch function.
|
2021-03-05 15:18:34 +00:00
|
|
|
* @param {Object} state - The Redux state.
|
2016-12-12 00:29:13 +00:00
|
|
|
* @private
|
|
|
|
* @returns {void}
|
2016-10-05 14:36:59 +00:00
|
|
|
*/
|
2022-10-20 09:11:27 +00:00
|
|
|
function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore['dispatch'], state: IReduxState) {
|
2019-10-09 08:34:01 +00:00
|
|
|
// A simple logger for conference errors received through
|
|
|
|
// the listener. These errors are not handled now, but logged.
|
|
|
|
conference.on(JitsiConferenceEvents.CONFERENCE_ERROR,
|
2022-10-17 11:28:01 +00:00
|
|
|
(error: Error) => logger.error('Conference error.', error));
|
2019-10-09 08:34:01 +00:00
|
|
|
|
2017-04-05 09:01:57 +00:00
|
|
|
// Dispatches into features/base/conference follow:
|
|
|
|
|
2022-01-20 09:16:22 +00:00
|
|
|
conference.on(
|
|
|
|
JitsiConferenceEvents.AUTH_STATUS_CHANGED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(authEnabled: boolean, authLogin: string) => dispatch(authStatusChanged(authEnabled, authLogin)));
|
2016-12-12 01:02:50 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.CONFERENCE_FAILED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(conferenceFailed(conference, ...args)));
|
2016-12-12 00:29:13 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.CONFERENCE_JOINED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(conferenceJoined(conference, ...args)));
|
2022-09-06 07:42:59 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.CONFERENCE_UNIQUE_ID_SET, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(conferenceUniqueIdSet(conference, ...args)));
|
2022-04-06 02:13:39 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.CONFERENCE_JOIN_IN_PROGRESS, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(conferenceJoinInProgress(conference, ...args)));
|
2016-12-12 00:29:13 +00:00
|
|
|
conference.on(
|
2017-06-15 00:40:51 +00:00
|
|
|
JitsiConferenceEvents.CONFERENCE_LEFT,
|
2022-10-17 11:28:01 +00:00
|
|
|
(...args: any[]) => {
|
2020-01-13 17:12:25 +00:00
|
|
|
dispatch(conferenceTimestampChanged(0));
|
2022-10-17 11:28:01 +00:00
|
|
|
// @ts-ignore
|
2020-01-13 17:12:25 +00:00
|
|
|
dispatch(conferenceLeft(conference, ...args));
|
|
|
|
});
|
2022-10-17 11:28:01 +00:00
|
|
|
conference.on(JitsiConferenceEvents.SUBJECT_CHANGED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(conferenceSubjectChanged(...args)));
|
2016-10-05 14:36:59 +00:00
|
|
|
|
2022-10-17 11:28:01 +00:00
|
|
|
conference.on(JitsiConferenceEvents.CONFERENCE_CREATED_TIMESTAMP, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(conferenceTimestampChanged(...args)));
|
2020-01-13 17:12:25 +00:00
|
|
|
|
2018-03-20 18:07:51 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.KICKED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(kickedOut(conference, ...args)));
|
2019-06-17 14:00:09 +00:00
|
|
|
|
|
|
|
conference.on(
|
|
|
|
JitsiConferenceEvents.PARTICIPANT_KICKED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(kicker: any, kicked: any) => dispatch(participantKicked(kicker, kicked)));
|
2018-03-20 18:07:51 +00:00
|
|
|
|
2016-12-12 19:49:23 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.LOCK_STATE_CHANGED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(lockStateChanged(conference, ...args)));
|
2016-12-12 19:49:23 +00:00
|
|
|
|
2017-08-02 15:00:51 +00:00
|
|
|
// Dispatches into features/base/media follow:
|
|
|
|
|
|
|
|
conference.on(
|
|
|
|
JitsiConferenceEvents.STARTED_MUTED,
|
|
|
|
() => {
|
2021-03-05 15:18:34 +00:00
|
|
|
const audioMuted = Boolean(conference.isStartAudioMuted());
|
|
|
|
const videoMuted = Boolean(conference.isStartVideoMuted());
|
|
|
|
const localTracks = getLocalTracks(state['features/base/tracks']);
|
2017-10-09 21:40:38 +00:00
|
|
|
|
2021-03-05 15:18:34 +00:00
|
|
|
sendAnalytics(createStartMutedConfigurationEvent('remote', audioMuted, videoMuted));
|
|
|
|
logger.log(`Start muted: ${audioMuted ? 'audio, ' : ''}${videoMuted ? 'video' : ''}`);
|
2017-10-09 21:40:38 +00:00
|
|
|
|
2017-08-04 21:06:42 +00:00
|
|
|
// XXX Jicofo tells lib-jitsi-meet to start with audio and/or video
|
|
|
|
// muted i.e. Jicofo expresses an intent. Lib-jitsi-meet has turned
|
|
|
|
// Jicofo's intent into reality by actually muting the respective
|
|
|
|
// tracks. The reality is expressed in base/tracks already so what
|
|
|
|
// is left is to express Jicofo's intent in base/media.
|
|
|
|
// TODO Maybe the app needs to learn about Jicofo's intent and
|
|
|
|
// transfer that intent to lib-jitsi-meet instead of lib-jitsi-meet
|
|
|
|
// acting on Jicofo's intent without the app's knowledge.
|
2017-10-09 21:40:38 +00:00
|
|
|
dispatch(setAudioMuted(audioMuted));
|
|
|
|
dispatch(setVideoMuted(videoMuted));
|
2021-03-05 15:18:34 +00:00
|
|
|
|
|
|
|
// Remove the tracks from peerconnection as well.
|
|
|
|
for (const track of localTracks) {
|
2021-10-01 12:04:34 +00:00
|
|
|
const trackType = track.jitsiTrack.getType();
|
|
|
|
|
|
|
|
// Do not remove the audio track on RN. Starting with iOS 15 it will fail to unmute otherwise.
|
|
|
|
if ((audioMuted && trackType === MEDIA_TYPE.AUDIO && navigator.product !== 'ReactNative')
|
|
|
|
|| (videoMuted && trackType === MEDIA_TYPE.VIDEO)) {
|
2021-03-18 19:03:28 +00:00
|
|
|
dispatch(replaceLocalTrack(track.jitsiTrack, null, conference));
|
2021-03-05 15:18:34 +00:00
|
|
|
}
|
|
|
|
}
|
2017-08-02 15:00:51 +00:00
|
|
|
});
|
|
|
|
|
2021-11-30 20:08:25 +00:00
|
|
|
conference.on(
|
|
|
|
JitsiConferenceEvents.AUDIO_UNMUTE_PERMISSIONS_CHANGED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(disableAudioMuteChange: boolean) => {
|
2021-12-07 21:48:12 +00:00
|
|
|
dispatch(setAudioUnmutePermissions(disableAudioMuteChange));
|
2021-11-30 20:08:25 +00:00
|
|
|
});
|
|
|
|
conference.on(
|
|
|
|
JitsiConferenceEvents.VIDEO_UNMUTE_PERMISSIONS_CHANGED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(disableVideoMuteChange: boolean) => {
|
2021-12-07 21:48:12 +00:00
|
|
|
dispatch(setVideoUnmutePermissions(disableVideoMuteChange));
|
2021-11-30 20:08:25 +00:00
|
|
|
});
|
|
|
|
|
2017-04-05 09:01:57 +00:00
|
|
|
// Dispatches into features/base/tracks follow:
|
|
|
|
|
2016-12-12 00:29:13 +00:00
|
|
|
conference.on(
|
2017-06-15 00:40:51 +00:00
|
|
|
JitsiConferenceEvents.TRACK_ADDED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(t: any) => t && !t.isLocal() && dispatch(trackAdded(t)));
|
2016-12-12 00:29:13 +00:00
|
|
|
conference.on(
|
2017-06-15 00:40:51 +00:00
|
|
|
JitsiConferenceEvents.TRACK_REMOVED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(t: any) => t && !t.isLocal() && dispatch(trackRemoved(t)));
|
2016-10-05 14:36:59 +00:00
|
|
|
|
2019-06-17 14:00:09 +00:00
|
|
|
conference.on(
|
|
|
|
JitsiConferenceEvents.TRACK_MUTE_CHANGED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(track: any, participantThatMutedUs: any) => {
|
2019-06-17 14:00:09 +00:00
|
|
|
if (participantThatMutedUs) {
|
2021-02-24 21:45:07 +00:00
|
|
|
dispatch(participantMutedUs(participantThatMutedUs, track));
|
2019-06-17 14:00:09 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-10-17 11:28:01 +00:00
|
|
|
conference.on(JitsiConferenceEvents.TRACK_UNMUTE_REJECTED, (track: any) => dispatch(destroyLocalTracks(track)));
|
2021-12-09 13:48:55 +00:00
|
|
|
|
2017-04-05 09:01:57 +00:00
|
|
|
// Dispatches into features/base/participants follow:
|
2017-12-19 01:47:51 +00:00
|
|
|
conference.on(
|
|
|
|
JitsiConferenceEvents.DISPLAY_NAME_CHANGED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(id: string, displayName: string) => dispatch(participantUpdated({
|
Associate remote participant w/ JitsiConference (_UPDATED)
The commit message of "Associate remote participant w/ JitsiConference
(_JOINED)" explains the motivation for this commit.
Practically, _JOINED and _LEFT combined with "Remove remote participants
who are no longer of interest" should alleviate the problem with
multiplying remote participants to an acceptable level of annoyance.
Technically though, a remote participant cannot be identified by an ID
only. The ID is (somewhat) "unique" in the context of a single
JitsiConference instance. So in order to not have to scratch our heads
over an obscure corner, racing case, it's better to always identify
remote participants by the pair id-conference. Unfortunately, that's a
bit of a high order given the existing source code. So I've implemented
the cases which are the easiest so that new source code written with
participantUpdated is more likely to identify a remote participant with
the pair id-conference.
Additionally, the commit "Reduce direct read access to the
features/base/participants redux state" brings more control back to the
functions of the feature base/participants so that one day we can (if we
choose to) do something like, for example:
If getParticipants is called with a conference, it returns the
participants from features/base/participants who are associated with the
specified conference. If no conference is specified in the function
call, then default to the conference which is the primary focus of the
app at the time of the function call. Added to the above, this should
allow us to further reduce the cases in which we're identifying remote
participants by id only and get us even closer to a more "predictable"
behavior in corner, racing cases.
2018-05-22 21:47:43 +00:00
|
|
|
conference,
|
2017-12-19 01:47:51 +00:00
|
|
|
id,
|
2019-01-15 11:28:07 +00:00
|
|
|
name: getNormalizedDisplayName(displayName)
|
2017-12-19 01:47:51 +00:00
|
|
|
})));
|
2017-04-05 09:01:57 +00:00
|
|
|
|
|
|
|
conference.on(
|
2017-06-15 00:40:51 +00:00
|
|
|
JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(dominant: string, previous: string[], silence: boolean | string) => {
|
2022-09-08 21:14:00 +00:00
|
|
|
dispatch(dominantSpeakerChanged(dominant, previous, Boolean(silence), conference));
|
|
|
|
});
|
2017-04-05 09:01:57 +00:00
|
|
|
|
2018-08-23 19:57:12 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(endpointMessageReceived(...args)));
|
2018-08-23 19:57:12 +00:00
|
|
|
|
2021-09-14 15:31:30 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.NON_PARTICIPANT_MESSAGE_RECEIVED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(nonParticipantMessageReceived(...args)));
|
2021-09-14 15:31:30 +00:00
|
|
|
|
2017-04-05 09:01:57 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(participantConnectionStatusChanged(...args)));
|
2017-04-05 09:01:57 +00:00
|
|
|
|
2016-12-12 00:29:13 +00:00
|
|
|
conference.on(
|
2017-06-15 00:40:51 +00:00
|
|
|
JitsiConferenceEvents.USER_JOINED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(_id: string, user: any) => commonUserJoinedHandling({ dispatch }, conference, user));
|
2016-12-12 00:29:13 +00:00
|
|
|
conference.on(
|
2017-06-15 00:40:51 +00:00
|
|
|
JitsiConferenceEvents.USER_LEFT,
|
2022-10-17 11:28:01 +00:00
|
|
|
(_id: string, user: any) => commonUserLeftHandling({ dispatch }, conference, user));
|
2016-12-12 00:29:13 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.USER_ROLE_CHANGED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(participantRoleChanged(...args)));
|
2018-06-20 13:45:22 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiConferenceEvents.USER_STATUS_CHANGED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(participantPresenceChanged(...args)));
|
2016-10-05 14:36:59 +00:00
|
|
|
|
2022-04-01 12:50:52 +00:00
|
|
|
conference.on(
|
2022-10-17 11:28:01 +00:00
|
|
|
JitsiE2ePingEvents.E2E_RTT_CHANGED, // @ts-ignore
|
|
|
|
(...args: any[]) => dispatch(e2eRttChanged(...args)));
|
2022-04-01 12:50:52 +00:00
|
|
|
|
2018-06-26 22:56:22 +00:00
|
|
|
conference.on(
|
|
|
|
JitsiConferenceEvents.BOT_TYPE_CHANGED,
|
2022-10-17 11:28:01 +00:00
|
|
|
(id: string, botType: string) => dispatch(participantUpdated({
|
2018-06-26 22:56:22 +00:00
|
|
|
conference,
|
|
|
|
id,
|
|
|
|
botType
|
|
|
|
})));
|
|
|
|
|
2017-02-28 23:12:02 +00:00
|
|
|
conference.addCommandListener(
|
2017-06-15 00:40:51 +00:00
|
|
|
AVATAR_URL_COMMAND,
|
2022-10-17 11:28:01 +00:00
|
|
|
(data: { value: string; }, id: string) => dispatch(participantUpdated({
|
Associate remote participant w/ JitsiConference (_UPDATED)
The commit message of "Associate remote participant w/ JitsiConference
(_JOINED)" explains the motivation for this commit.
Practically, _JOINED and _LEFT combined with "Remove remote participants
who are no longer of interest" should alleviate the problem with
multiplying remote participants to an acceptable level of annoyance.
Technically though, a remote participant cannot be identified by an ID
only. The ID is (somewhat) "unique" in the context of a single
JitsiConference instance. So in order to not have to scratch our heads
over an obscure corner, racing case, it's better to always identify
remote participants by the pair id-conference. Unfortunately, that's a
bit of a high order given the existing source code. So I've implemented
the cases which are the easiest so that new source code written with
participantUpdated is more likely to identify a remote participant with
the pair id-conference.
Additionally, the commit "Reduce direct read access to the
features/base/participants redux state" brings more control back to the
functions of the feature base/participants so that one day we can (if we
choose to) do something like, for example:
If getParticipants is called with a conference, it returns the
participants from features/base/participants who are associated with the
specified conference. If no conference is specified in the function
call, then default to the conference which is the primary focus of the
app at the time of the function call. Added to the above, this should
allow us to further reduce the cases in which we're identifying remote
participants by id only and get us even closer to a more "predictable"
behavior in corner, racing cases.
2018-05-22 21:47:43 +00:00
|
|
|
conference,
|
2017-06-15 00:40:51 +00:00
|
|
|
id,
|
|
|
|
avatarURL: data.value
|
|
|
|
})));
|
2016-12-12 00:29:13 +00:00
|
|
|
conference.addCommandListener(
|
2017-06-15 00:40:51 +00:00
|
|
|
EMAIL_COMMAND,
|
2022-10-17 11:28:01 +00:00
|
|
|
(data: { value: string; }, id: string) => dispatch(participantUpdated({
|
Associate remote participant w/ JitsiConference (_UPDATED)
The commit message of "Associate remote participant w/ JitsiConference
(_JOINED)" explains the motivation for this commit.
Practically, _JOINED and _LEFT combined with "Remove remote participants
who are no longer of interest" should alleviate the problem with
multiplying remote participants to an acceptable level of annoyance.
Technically though, a remote participant cannot be identified by an ID
only. The ID is (somewhat) "unique" in the context of a single
JitsiConference instance. So in order to not have to scratch our heads
over an obscure corner, racing case, it's better to always identify
remote participants by the pair id-conference. Unfortunately, that's a
bit of a high order given the existing source code. So I've implemented
the cases which are the easiest so that new source code written with
participantUpdated is more likely to identify a remote participant with
the pair id-conference.
Additionally, the commit "Reduce direct read access to the
features/base/participants redux state" brings more control back to the
functions of the feature base/participants so that one day we can (if we
choose to) do something like, for example:
If getParticipants is called with a conference, it returns the
participants from features/base/participants who are associated with the
specified conference. If no conference is specified in the function
call, then default to the conference which is the primary focus of the
app at the time of the function call. Added to the above, this should
allow us to further reduce the cases in which we're identifying remote
participants by id only and get us even closer to a more "predictable"
behavior in corner, racing cases.
2018-05-22 21:47:43 +00:00
|
|
|
conference,
|
2017-06-15 00:40:51 +00:00
|
|
|
id,
|
|
|
|
email: data.value
|
|
|
|
})));
|
2016-10-05 14:36:59 +00:00
|
|
|
}
|
|
|
|
|
2022-04-01 12:50:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create an action for when the end-to-end RTT against a specific remote participant has changed.
|
|
|
|
*
|
|
|
|
* @param {Object} participant - The participant against which the rtt is measured.
|
|
|
|
* @param {number} rtt - The rtt.
|
|
|
|
* @returns {{
|
|
|
|
* type: E2E_RTT_CHANGED,
|
|
|
|
* e2eRtt: {
|
|
|
|
* participant: Object,
|
|
|
|
* rtt: number
|
|
|
|
* }
|
|
|
|
* }}
|
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function e2eRttChanged(participant: Object, rtt: number) {
|
2022-04-01 12:50:52 +00:00
|
|
|
return {
|
|
|
|
type: E2E_RTT_CHANGED,
|
|
|
|
e2eRtt: {
|
|
|
|
rtt,
|
|
|
|
participant
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-06-20 20:19:53 +00:00
|
|
|
/**
|
|
|
|
* Updates the current known state of server-side authentication.
|
|
|
|
*
|
|
|
|
* @param {boolean} authEnabled - Whether or not server authentication is
|
|
|
|
* enabled.
|
|
|
|
* @param {string} authLogin - The current name of the logged in user, if any.
|
|
|
|
* @returns {{
|
|
|
|
* type: AUTH_STATUS_CHANGED,
|
|
|
|
* authEnabled: boolean,
|
|
|
|
* authLogin: string
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
export function authStatusChanged(authEnabled: boolean, authLogin: string) {
|
|
|
|
return {
|
|
|
|
type: AUTH_STATUS_CHANGED,
|
|
|
|
authEnabled,
|
|
|
|
authLogin
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-12-12 01:02:50 +00:00
|
|
|
/**
|
|
|
|
* Signals that a specific conference has failed.
|
|
|
|
*
|
|
|
|
* @param {JitsiConference} conference - The JitsiConference that has failed.
|
|
|
|
* @param {string} error - The error describing/detailing the cause of the
|
|
|
|
* failure.
|
2020-05-20 08:25:31 +00:00
|
|
|
* @param {any} params - Rest of the params that we receive together with the event.
|
2016-12-12 01:02:50 +00:00
|
|
|
* @returns {{
|
|
|
|
* type: CONFERENCE_FAILED,
|
|
|
|
* conference: JitsiConference,
|
2017-10-05 12:41:35 +00:00
|
|
|
* error: Error
|
2016-12-12 01:02:50 +00:00
|
|
|
* }}
|
2017-01-31 20:58:48 +00:00
|
|
|
* @public
|
2016-12-12 01:02:50 +00:00
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function conferenceFailed(conference: IJitsiConference, error: string, ...params: any) {
|
2016-12-12 01:02:50 +00:00
|
|
|
return {
|
|
|
|
type: CONFERENCE_FAILED,
|
|
|
|
conference,
|
2017-10-05 12:41:35 +00:00
|
|
|
|
|
|
|
// Make the error resemble an Error instance (to the extent that
|
|
|
|
// jitsi-meet needs it).
|
|
|
|
error: {
|
2018-06-07 13:05:00 +00:00
|
|
|
name: error,
|
2020-04-15 13:13:43 +00:00
|
|
|
params,
|
2018-06-07 13:05:00 +00:00
|
|
|
recoverable: undefined
|
2017-10-05 12:41:35 +00:00
|
|
|
}
|
2016-12-12 01:02:50 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-10-05 14:36:59 +00:00
|
|
|
/**
|
2017-08-08 14:27:44 +00:00
|
|
|
* Signals that a specific conference has been joined.
|
2016-10-05 14:36:59 +00:00
|
|
|
*
|
|
|
|
* @param {JitsiConference} conference - The JitsiConference instance which was
|
|
|
|
* joined by the local participant.
|
2017-08-08 14:27:44 +00:00
|
|
|
* @returns {{
|
|
|
|
* type: CONFERENCE_JOINED,
|
|
|
|
* conference: JitsiConference
|
|
|
|
* }}
|
2016-10-05 14:36:59 +00:00
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function conferenceJoined(conference: IJitsiConference) {
|
2017-08-08 14:27:44 +00:00
|
|
|
return {
|
|
|
|
type: CONFERENCE_JOINED,
|
|
|
|
conference
|
2016-10-05 14:36:59 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-04-06 02:13:39 +00:00
|
|
|
/**
|
|
|
|
* Signals that a specific conference join is in progress.
|
|
|
|
*
|
|
|
|
* @param {JitsiConference} conference - The JitsiConference instance for which join by the local participant
|
|
|
|
* is in progress.
|
|
|
|
* @returns {{
|
|
|
|
* type: CONFERENCE_JOIN_IN_PROGRESS,
|
|
|
|
* conference: JitsiConference
|
|
|
|
* }}
|
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function conferenceJoinInProgress(conference: IJitsiConference) {
|
2022-04-06 02:13:39 +00:00
|
|
|
return {
|
|
|
|
type: CONFERENCE_JOIN_IN_PROGRESS,
|
|
|
|
conference
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-01-18 19:28:52 +00:00
|
|
|
/**
|
2017-01-20 18:11:11 +00:00
|
|
|
* Signals that a specific conference has been left.
|
2017-01-18 19:28:52 +00:00
|
|
|
*
|
2017-01-20 18:11:11 +00:00
|
|
|
* @param {JitsiConference} conference - The JitsiConference instance which was
|
|
|
|
* left by the local participant.
|
2017-01-18 19:28:52 +00:00
|
|
|
* @returns {{
|
2017-04-19 14:52:27 +00:00
|
|
|
* type: CONFERENCE_LEFT,
|
|
|
|
* conference: JitsiConference
|
|
|
|
* }}
|
2017-01-18 19:28:52 +00:00
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function conferenceLeft(conference: IJitsiConference) {
|
2017-01-18 19:28:52 +00:00
|
|
|
return {
|
2017-01-20 18:11:11 +00:00
|
|
|
type: CONFERENCE_LEFT,
|
|
|
|
conference
|
2017-01-18 19:28:52 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-03-12 17:45:53 +00:00
|
|
|
/**
|
|
|
|
* Signals that the conference subject has been changed.
|
|
|
|
*
|
|
|
|
* @param {string} subject - The new subject.
|
|
|
|
* @returns {{
|
|
|
|
* type: CONFERENCE_SUBJECT_CHANGED,
|
|
|
|
* subject: string
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
export function conferenceSubjectChanged(subject: string) {
|
|
|
|
return {
|
|
|
|
type: CONFERENCE_SUBJECT_CHANGED,
|
|
|
|
subject
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-01-13 17:12:25 +00:00
|
|
|
/**
|
|
|
|
* Signals that the conference timestamp has been changed.
|
|
|
|
*
|
|
|
|
* @param {number} conferenceTimestamp - The UTC timestamp.
|
|
|
|
* @returns {{
|
|
|
|
* type: CONFERENCE_TIMESTAMP_CHANGED,
|
|
|
|
* conferenceTimestamp
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
export function conferenceTimestampChanged(conferenceTimestamp: number) {
|
|
|
|
return {
|
|
|
|
type: CONFERENCE_TIMESTAMP_CHANGED,
|
|
|
|
conferenceTimestamp
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-02-04 17:33:18 +00:00
|
|
|
/**
|
|
|
|
* Signals that the unique identifier for conference has been set.
|
|
|
|
*
|
|
|
|
* @param {JitsiConference} conference - The JitsiConference instance, where the uuid has been set.
|
|
|
|
* @returns {{
|
|
|
|
* type: CONFERENCE_UNIQUE_ID_SET,
|
|
|
|
* conference: JitsiConference,
|
|
|
|
* }}
|
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function conferenceUniqueIdSet(conference: IJitsiConference) {
|
2021-02-04 17:33:18 +00:00
|
|
|
return {
|
|
|
|
type: CONFERENCE_UNIQUE_ID_SET,
|
|
|
|
conference
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-10-05 14:36:59 +00:00
|
|
|
/**
|
2017-11-13 22:10:54 +00:00
|
|
|
* Adds any existing local tracks to a specific conference before the conference
|
|
|
|
* is joined. Then signals the intention of the application to have the local
|
|
|
|
* participant join the specified conference.
|
2016-10-05 14:36:59 +00:00
|
|
|
*
|
2017-11-13 22:10:54 +00:00
|
|
|
* @param {JitsiConference} conference - The {@code JitsiConference} instance
|
|
|
|
* the local participant will (try to) join.
|
2017-08-08 14:27:44 +00:00
|
|
|
* @returns {Function}
|
2016-10-05 14:36:59 +00:00
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function _conferenceWillJoin(conference: IJitsiConference) {
|
|
|
|
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
2017-08-08 14:27:44 +00:00
|
|
|
const localTracks
|
2017-11-09 21:59:31 +00:00
|
|
|
= getLocalTracks(getState()['features/base/tracks'])
|
2017-08-08 14:27:44 +00:00
|
|
|
.map(t => t.jitsiTrack);
|
|
|
|
|
|
|
|
if (localTracks.length) {
|
|
|
|
_addLocalTracksToConference(conference, localTracks);
|
|
|
|
}
|
|
|
|
|
2017-11-21 22:45:14 +00:00
|
|
|
dispatch(conferenceWillJoin(conference));
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Signals the intention of the application to have the local participant
|
|
|
|
* join the specified conference.
|
|
|
|
*
|
|
|
|
* @param {JitsiConference} conference - The {@code JitsiConference} instance
|
|
|
|
* the local participant will (try to) join.
|
|
|
|
* @returns {{
|
|
|
|
* type: CONFERENCE_WILL_JOIN,
|
|
|
|
* conference: JitsiConference
|
|
|
|
* }}
|
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function conferenceWillJoin(conference: IJitsiConference) {
|
2017-11-21 22:45:14 +00:00
|
|
|
return {
|
|
|
|
type: CONFERENCE_WILL_JOIN,
|
|
|
|
conference
|
2016-10-05 14:36:59 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-12-12 00:29:13 +00:00
|
|
|
* Signals the intention of the application to have the local participant leave
|
|
|
|
* a specific conference. Similar in fashion to CONFERENCE_LEFT. Contrary to it
|
2016-10-05 14:36:59 +00:00
|
|
|
* though, it's not guaranteed because CONFERENCE_LEFT may be triggered by
|
|
|
|
* lib-jitsi-meet and not the application.
|
|
|
|
*
|
|
|
|
* @param {JitsiConference} conference - The JitsiConference instance which will
|
|
|
|
* be left by the local participant.
|
|
|
|
* @returns {{
|
2017-04-19 14:52:27 +00:00
|
|
|
* type: CONFERENCE_LEFT,
|
|
|
|
* conference: JitsiConference
|
|
|
|
* }}
|
2016-10-05 14:36:59 +00:00
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function conferenceWillLeave(conference: IJitsiConference) {
|
2016-10-05 14:36:59 +00:00
|
|
|
return {
|
|
|
|
type: CONFERENCE_WILL_LEAVE,
|
2016-12-12 00:29:13 +00:00
|
|
|
conference
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initializes a new conference.
|
|
|
|
*
|
2021-09-14 15:31:30 +00:00
|
|
|
* @param {string} overrideRoom - Override the room to join, instead of taking it
|
|
|
|
* from Redux.
|
2016-12-12 00:29:13 +00:00
|
|
|
* @returns {Function}
|
|
|
|
*/
|
2021-09-14 15:31:30 +00:00
|
|
|
export function createConference(overrideRoom?: string) {
|
2022-10-17 11:28:01 +00:00
|
|
|
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
2016-12-12 00:29:13 +00:00
|
|
|
const state = getState();
|
2017-08-01 00:40:55 +00:00
|
|
|
const { connection, locationURL } = state['features/base/connection'];
|
2016-12-12 00:29:13 +00:00
|
|
|
|
|
|
|
if (!connection) {
|
2017-07-07 17:21:08 +00:00
|
|
|
throw new Error('Cannot create a conference without a connection!');
|
2016-10-05 14:36:59 +00:00
|
|
|
}
|
2016-12-12 00:29:13 +00:00
|
|
|
|
2016-12-12 01:02:50 +00:00
|
|
|
const { password, room } = state['features/base/conference'];
|
2016-12-12 00:29:13 +00:00
|
|
|
|
2017-07-07 17:21:08 +00:00
|
|
|
if (!room) {
|
|
|
|
throw new Error('Cannot join a conference without a room name!');
|
2016-12-12 00:29:13 +00:00
|
|
|
}
|
|
|
|
|
2021-09-14 15:31:30 +00:00
|
|
|
// XXX: revisit this.
|
|
|
|
// Hide the custom domain in the room name.
|
2022-10-17 11:28:01 +00:00
|
|
|
const tmp: any = overrideRoom || room;
|
|
|
|
let _room: any = getBackendSafeRoomName(tmp);
|
2021-09-14 15:31:30 +00:00
|
|
|
|
|
|
|
if (tmp.domain) {
|
|
|
|
// eslint-disable-next-line no-new-wrappers
|
|
|
|
_room = new String(tmp);
|
|
|
|
|
|
|
|
// $FlowExpectedError
|
|
|
|
_room.domain = tmp.domain;
|
|
|
|
}
|
|
|
|
|
|
|
|
const conference = connection.initJitsiConference(_room, getConferenceOptions(state));
|
2016-12-12 00:29:13 +00:00
|
|
|
|
2022-10-17 11:28:01 +00:00
|
|
|
// @ts-ignore
|
2019-04-25 08:14:23 +00:00
|
|
|
connection[JITSI_CONNECTION_CONFERENCE_KEY] = conference;
|
|
|
|
|
2017-08-01 00:40:55 +00:00
|
|
|
conference[JITSI_CONFERENCE_URL_KEY] = locationURL;
|
2019-04-25 08:14:23 +00:00
|
|
|
|
2017-07-07 17:21:08 +00:00
|
|
|
dispatch(_conferenceWillJoin(conference));
|
2017-07-06 11:51:35 +00:00
|
|
|
|
2021-03-05 15:18:34 +00:00
|
|
|
_addConferenceListeners(conference, dispatch, state);
|
2016-12-12 00:29:13 +00:00
|
|
|
|
2017-10-13 19:31:05 +00:00
|
|
|
sendLocalParticipant(state, conference);
|
2017-02-28 23:12:02 +00:00
|
|
|
|
2021-06-16 11:08:18 +00:00
|
|
|
const replaceParticipant = getReplaceParticipant(state);
|
|
|
|
|
|
|
|
conference.join(password, replaceParticipant);
|
2016-12-12 01:02:50 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-09-08 13:36:42 +00:00
|
|
|
/**
|
|
|
|
* Will try to join the conference again in case it failed earlier with
|
|
|
|
* {@link JitsiConferenceErrors.AUTHENTICATION_REQUIRED}. It means that Jicofo
|
|
|
|
* did not allow to create new room from anonymous domain, but it can be tried
|
|
|
|
* again later in case authenticated user created it in the meantime.
|
|
|
|
*
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function checkIfCanJoin() {
|
2022-10-17 11:28:01 +00:00
|
|
|
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
2017-09-18 07:09:43 +00:00
|
|
|
const { authRequired, password }
|
2017-09-08 13:36:42 +00:00
|
|
|
= getState()['features/base/conference'];
|
|
|
|
|
2021-12-08 21:25:18 +00:00
|
|
|
const replaceParticipant = getReplaceParticipant(getState());
|
2021-06-11 08:58:45 +00:00
|
|
|
|
2022-10-17 11:28:01 +00:00
|
|
|
// @ts-ignore
|
2019-01-19 23:53:05 +00:00
|
|
|
authRequired && dispatch(_conferenceWillJoin(authRequired));
|
2022-10-17 11:28:01 +00:00
|
|
|
authRequired?.join(password, replaceParticipant);
|
2017-09-08 13:36:42 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-08-09 19:40:03 +00:00
|
|
|
/**
|
|
|
|
* Signals the data channel with the bridge has successfully opened.
|
|
|
|
*
|
|
|
|
* @returns {{
|
|
|
|
* type: DATA_CHANNEL_OPENED
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
export function dataChannelOpened() {
|
|
|
|
return {
|
|
|
|
type: DATA_CHANNEL_OPENED
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-08-26 18:25:04 +00:00
|
|
|
/**
|
|
|
|
* Action to end a conference for all participants.
|
|
|
|
*
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function endConference() {
|
2022-10-17 11:28:01 +00:00
|
|
|
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
2022-08-26 18:25:04 +00:00
|
|
|
const { conference } = getConferenceState(toState(getState));
|
|
|
|
|
|
|
|
conference?.end();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-03-20 18:07:51 +00:00
|
|
|
/**
|
|
|
|
* Signals that we've been kicked out of the conference.
|
|
|
|
*
|
|
|
|
* @param {JitsiConference} conference - The {@link JitsiConference} instance
|
|
|
|
* for which the event is being signaled.
|
2019-06-17 14:00:09 +00:00
|
|
|
* @param {JitsiParticipant} participant - The {@link JitsiParticipant}
|
|
|
|
* instance which initiated the kick event.
|
2018-03-20 18:07:51 +00:00
|
|
|
* @returns {{
|
|
|
|
* type: KICKED_OUT,
|
2019-06-17 14:00:09 +00:00
|
|
|
* conference: JitsiConference,
|
|
|
|
* participant: JitsiParticipant
|
2018-03-20 18:07:51 +00:00
|
|
|
* }}
|
|
|
|
*/
|
2019-06-17 14:00:09 +00:00
|
|
|
export function kickedOut(conference: Object, participant: Object) {
|
2018-03-20 18:07:51 +00:00
|
|
|
return {
|
|
|
|
type: KICKED_OUT,
|
2019-06-17 14:00:09 +00:00
|
|
|
conference,
|
|
|
|
participant
|
2018-03-20 18:07:51 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-08-26 18:25:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Action to leave a conference.
|
|
|
|
*
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function leaveConference() {
|
2022-10-17 11:28:01 +00:00
|
|
|
return async (dispatch: IStore['dispatch']) => {
|
2022-08-26 18:25:04 +00:00
|
|
|
|
|
|
|
// FIXME: these should be unified.
|
|
|
|
if (navigator.product === 'ReactNative') {
|
|
|
|
dispatch(appNavigate(undefined));
|
|
|
|
} else {
|
|
|
|
dispatch(disconnect(true));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-12 19:49:23 +00:00
|
|
|
/**
|
|
|
|
* Signals that the lock state of a specific JitsiConference changed.
|
|
|
|
*
|
|
|
|
* @param {JitsiConference} conference - The JitsiConference which had its lock
|
|
|
|
* state changed.
|
|
|
|
* @param {boolean} locked - If the specified conference became locked, true;
|
|
|
|
* otherwise, false.
|
|
|
|
* @returns {{
|
|
|
|
* type: LOCK_STATE_CHANGED,
|
|
|
|
* conference: JitsiConference,
|
|
|
|
* locked: boolean
|
|
|
|
* }}
|
|
|
|
*/
|
2017-10-03 19:24:00 +00:00
|
|
|
export function lockStateChanged(conference: Object, locked: boolean) {
|
2016-12-12 19:49:23 +00:00
|
|
|
return {
|
|
|
|
type: LOCK_STATE_CHANGED,
|
|
|
|
conference,
|
|
|
|
locked
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-09-14 15:31:30 +00:00
|
|
|
/**
|
|
|
|
* Signals that a non participant endpoint message has been received.
|
|
|
|
*
|
|
|
|
* @param {string} id - The resource id of the sender.
|
|
|
|
* @param {Object} json - The json carried by the endpoint message.
|
|
|
|
* @returns {{
|
|
|
|
* type: NON_PARTICIPANT_MESSAGE_RECEIVED,
|
|
|
|
* id: Object,
|
|
|
|
* json: Object
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
export function nonParticipantMessageReceived(id: String, json: Object) {
|
|
|
|
return {
|
|
|
|
type: NON_PARTICIPANT_MESSAGE_RECEIVED,
|
|
|
|
id,
|
|
|
|
json
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-11-21 02:21:35 +00:00
|
|
|
/**
|
|
|
|
* Updates the known state of start muted policies.
|
|
|
|
*
|
|
|
|
* @param {boolean} audioMuted - Whether or not members will join the conference
|
|
|
|
* as audio muted.
|
|
|
|
* @param {boolean} videoMuted - Whether or not members will join the conference
|
|
|
|
* as video muted.
|
|
|
|
* @returns {{
|
|
|
|
* type: SET_START_MUTED_POLICY,
|
|
|
|
* startAudioMutedPolicy: boolean,
|
|
|
|
* startVideoMutedPolicy: boolean
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
export function onStartMutedPolicyChanged(
|
|
|
|
audioMuted: boolean, videoMuted: boolean) {
|
|
|
|
return {
|
|
|
|
type: SET_START_MUTED_POLICY,
|
|
|
|
startAudioMutedPolicy: audioMuted,
|
|
|
|
startVideoMutedPolicy: videoMuted
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-03-29 12:07:05 +00:00
|
|
|
/**
|
2017-08-09 19:40:03 +00:00
|
|
|
* Sets whether or not peer2peer is currently enabled.
|
2017-03-29 12:07:05 +00:00
|
|
|
*
|
2017-08-09 19:40:03 +00:00
|
|
|
* @param {boolean} p2p - Whether or not peer2peer is currently active.
|
2017-03-29 12:07:05 +00:00
|
|
|
* @returns {{
|
2017-08-09 19:40:03 +00:00
|
|
|
* type: P2P_STATUS_CHANGED,
|
|
|
|
* p2p: boolean
|
2017-03-29 12:07:05 +00:00
|
|
|
* }}
|
|
|
|
*/
|
2017-10-03 19:24:00 +00:00
|
|
|
export function p2pStatusChanged(p2p: boolean) {
|
2017-03-29 12:07:05 +00:00
|
|
|
return {
|
2017-08-09 19:40:03 +00:00
|
|
|
type: P2P_STATUS_CHANGED,
|
|
|
|
p2p
|
2017-03-29 12:07:05 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-08-30 21:17:22 +00:00
|
|
|
/**
|
|
|
|
* Signals to play touch tones.
|
|
|
|
*
|
|
|
|
* @param {string} tones - The tones to play.
|
|
|
|
* @param {number} [duration] - How long to play each tone.
|
|
|
|
* @param {number} [pause] - How long to pause between each tone.
|
|
|
|
* @returns {{
|
|
|
|
* type: SEND_TONES,
|
|
|
|
* tones: string,
|
|
|
|
* duration: number,
|
|
|
|
* pause: number
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
export function sendTones(tones: string, duration: number, pause: number) {
|
|
|
|
return {
|
|
|
|
type: SEND_TONES,
|
|
|
|
tones,
|
|
|
|
duration,
|
|
|
|
pause
|
|
|
|
};
|
2018-03-07 00:28:19 +00:00
|
|
|
}
|
|
|
|
|
2017-11-21 02:21:35 +00:00
|
|
|
/**
|
|
|
|
* Enables or disables the Follow Me feature.
|
|
|
|
*
|
|
|
|
* @param {boolean} enabled - Whether or not Follow Me should be enabled.
|
|
|
|
* @returns {{
|
|
|
|
* type: SET_FOLLOW_ME,
|
|
|
|
* enabled: boolean
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
export function setFollowMe(enabled: boolean) {
|
|
|
|
return {
|
|
|
|
type: SET_FOLLOW_ME,
|
|
|
|
enabled
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-11-10 11:19:40 +00:00
|
|
|
/**
|
|
|
|
* Enables or disables the Mute reaction sounds feature.
|
|
|
|
*
|
|
|
|
* @param {boolean} muted - Whether or not reaction sounds should be muted for all participants.
|
2021-12-13 19:46:05 +00:00
|
|
|
* @param {boolean} updateBackend - Whether or not the moderator should notify all participants for the new setting.
|
2021-11-10 11:19:40 +00:00
|
|
|
* @returns {{
|
|
|
|
* type: SET_START_REACTIONS_MUTED,
|
|
|
|
* muted: boolean
|
|
|
|
* }}
|
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function setStartReactionsMuted(muted: boolean, updateBackend = false) {
|
2021-11-10 11:19:40 +00:00
|
|
|
return {
|
|
|
|
type: SET_START_REACTIONS_MUTED,
|
2021-12-13 19:46:05 +00:00
|
|
|
muted,
|
|
|
|
updateBackend
|
2021-11-10 11:19:40 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-12-12 01:02:50 +00:00
|
|
|
/**
|
|
|
|
* Sets the password to join or lock a specific JitsiConference.
|
|
|
|
*
|
|
|
|
* @param {JitsiConference} conference - The JitsiConference which requires a
|
|
|
|
* password to join or is to be locked with the specified password.
|
|
|
|
* @param {Function} method - The JitsiConference method of password protection
|
|
|
|
* such as join or lock.
|
|
|
|
* @param {string} password - The password with which the specified conference
|
|
|
|
* is to be joined or locked.
|
2016-12-13 09:14:04 +00:00
|
|
|
* @returns {Function}
|
2016-12-12 01:02:50 +00:00
|
|
|
*/
|
2017-10-03 19:24:00 +00:00
|
|
|
export function setPassword(
|
2022-10-17 11:28:01 +00:00
|
|
|
conference: IJitsiConference,
|
2017-10-03 19:24:00 +00:00
|
|
|
method: Function,
|
|
|
|
password: string) {
|
2022-10-17 11:28:01 +00:00
|
|
|
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
2016-12-13 09:14:04 +00:00
|
|
|
switch (method) {
|
|
|
|
case conference.join: {
|
|
|
|
let state = getState()['features/base/conference'];
|
|
|
|
|
2020-05-20 08:25:31 +00:00
|
|
|
dispatch({
|
|
|
|
type: SET_PASSWORD,
|
|
|
|
conference,
|
|
|
|
method,
|
|
|
|
password
|
|
|
|
});
|
2016-12-13 09:14:04 +00:00
|
|
|
|
2020-05-20 08:25:31 +00:00
|
|
|
// Join the conference with the newly-set password.
|
2016-12-13 09:14:04 +00:00
|
|
|
|
2020-05-20 08:25:31 +00:00
|
|
|
// Make sure that the action did set the password.
|
|
|
|
state = getState()['features/base/conference'];
|
|
|
|
if (state.password === password
|
2016-12-13 09:14:04 +00:00
|
|
|
|
2020-05-20 08:25:31 +00:00
|
|
|
// Make sure that the application still wants the
|
|
|
|
// conference joined.
|
|
|
|
&& !state.conference) {
|
|
|
|
method.call(conference, password);
|
2016-12-13 09:14:04 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case conference.lock: {
|
|
|
|
const state = getState()['features/base/conference'];
|
|
|
|
|
|
|
|
if (state.conference === conference) {
|
|
|
|
return (
|
|
|
|
method.call(conference, password)
|
|
|
|
.then(() => dispatch({
|
|
|
|
type: SET_PASSWORD,
|
|
|
|
conference,
|
|
|
|
method,
|
|
|
|
password
|
2017-04-13 00:23:43 +00:00
|
|
|
}))
|
2022-10-17 11:28:01 +00:00
|
|
|
.catch((error: Error) => dispatch({
|
2017-04-13 00:23:43 +00:00
|
|
|
type: SET_PASSWORD_FAILED,
|
|
|
|
error
|
|
|
|
}))
|
|
|
|
);
|
2016-12-13 09:14:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Promise.reject();
|
|
|
|
}
|
|
|
|
}
|
2016-10-05 14:36:59 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-06-21 06:53:07 +00:00
|
|
|
/**
|
|
|
|
* Sets the obfuscated room name of the conference to be joined.
|
|
|
|
*
|
|
|
|
* @param {(string)} obfuscatedRoom - Obfuscated room name.
|
|
|
|
* @param {(string)} obfuscatedRoomSource - The room name that was obfuscated.
|
|
|
|
* @returns {{
|
|
|
|
* type: SET_OBFUSCATED_ROOM,
|
|
|
|
* room: string
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
export function setObfuscatedRoom(obfuscatedRoom: string, obfuscatedRoomSource: string) {
|
|
|
|
return {
|
|
|
|
type: SET_OBFUSCATED_ROOM,
|
|
|
|
obfuscatedRoom,
|
|
|
|
obfuscatedRoomSource
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-10-05 14:36:59 +00:00
|
|
|
/**
|
|
|
|
* Sets (the name of) the room of the conference to be joined.
|
|
|
|
*
|
|
|
|
* @param {(string|undefined)} room - The name of the room of the conference to
|
|
|
|
* be joined.
|
|
|
|
* @returns {{
|
2017-04-06 16:45:36 +00:00
|
|
|
* type: SET_ROOM,
|
|
|
|
* room: string
|
|
|
|
* }}
|
2016-10-05 14:36:59 +00:00
|
|
|
*/
|
2022-10-17 11:28:01 +00:00
|
|
|
export function setRoom(room?: string) {
|
2016-10-05 14:36:59 +00:00
|
|
|
return {
|
|
|
|
type: SET_ROOM,
|
|
|
|
room
|
|
|
|
};
|
|
|
|
}
|
2017-03-29 12:07:05 +00:00
|
|
|
|
2017-11-21 02:21:35 +00:00
|
|
|
/**
|
|
|
|
* Sets whether or not members should join audio and/or video muted.
|
|
|
|
*
|
|
|
|
* @param {boolean} startAudioMuted - Whether or not members will join the
|
|
|
|
* conference as audio muted.
|
|
|
|
* @param {boolean} startVideoMuted - Whether or not members will join the
|
|
|
|
* conference as video muted.
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function setStartMutedPolicy(
|
|
|
|
startAudioMuted: boolean, startVideoMuted: boolean) {
|
2022-10-17 11:28:01 +00:00
|
|
|
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
2018-05-24 20:15:32 +00:00
|
|
|
const conference = getCurrentConference(getState());
|
2017-11-21 02:21:35 +00:00
|
|
|
|
2022-10-17 11:28:01 +00:00
|
|
|
conference?.setStartMutedPolicy({
|
2017-11-21 02:21:35 +00:00
|
|
|
audio: startAudioMuted,
|
|
|
|
video: startVideoMuted
|
|
|
|
});
|
|
|
|
|
|
|
|
return dispatch(
|
|
|
|
onStartMutedPolicyChanged(startAudioMuted, startVideoMuted));
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-02-17 14:40:24 +00:00
|
|
|
/**
|
2021-12-17 07:38:15 +00:00
|
|
|
* Sets the conference subject.
|
2019-02-17 14:40:24 +00:00
|
|
|
*
|
|
|
|
* @param {string} subject - The new subject.
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2020-06-18 07:56:42 +00:00
|
|
|
export function setSubject(subject: string) {
|
2022-10-17 11:28:01 +00:00
|
|
|
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
2019-03-12 17:45:53 +00:00
|
|
|
const { conference } = getState()['features/base/conference'];
|
|
|
|
|
|
|
|
if (conference) {
|
2020-06-18 07:56:42 +00:00
|
|
|
conference.setSubject(subject || '');
|
2019-03-12 17:45:53 +00:00
|
|
|
} else {
|
|
|
|
dispatch({
|
|
|
|
type: SET_PENDING_SUBJECT_CHANGE,
|
|
|
|
subject
|
|
|
|
});
|
|
|
|
}
|
2019-02-17 14:40:24 +00:00
|
|
|
};
|
|
|
|
}
|
2021-12-17 07:38:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the conference local subject.
|
|
|
|
*
|
|
|
|
* @param {string} localSubject - The new local subject.
|
|
|
|
* @returns {{
|
|
|
|
* type: CONFERENCE_LOCAL_SUBJECT_CHANGED,
|
|
|
|
* localSubject: string
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
export function setLocalSubject(localSubject: string) {
|
|
|
|
return {
|
|
|
|
type: CONFERENCE_LOCAL_SUBJECT_CHANGED,
|
|
|
|
localSubject
|
|
|
|
};
|
|
|
|
}
|