jiti-meet/react/features/base/conference/actions.js

743 lines
21 KiB
JavaScript
Raw Normal View History

// @flow
import type { Dispatch } from 'redux';
import {
Restructures the analytics events (#2333) * ref: Restructures the pinned/unpinned events. * ref: Refactors the "audio only disabled" event. * ref: Refactors the "stream switch delay" event. * ref: Refactors the "select participant failed" event. * ref: Refactors the "initially muted" events. * ref: Refactors the screen sharing started/stopped events. * ref: Restructures the "device list changed" events. * ref: Restructures the "shared video" events. * ref: Restructures the "start muted" events. * ref: Restructures the "start audio only" event. * ref: Restructures the "sync track state" event. * ref: Restructures the "callkit" events. * ref: Restructures the "replace track". * ref: Restructures keyboard shortcuts events. * ref: Restructures most of the toolbar events. * ref: Refactors the API events. * ref: Restructures the video quality, profile button and invite dialog events. * ref: Refactors the "device changed" events. * ref: Refactors the page reload event. * ref: Removes an unused function. * ref: Removes a method which is needlessly exposed under a different name. * ref: Refactors the events from the remote video menu. * ref: Refactors the events from the profile pane. * ref: Restructures the recording-related events. Removes events fired when recording with something other than jibri (which isn't currently supported anyway). * ref: Cleans up AnalyticsEvents.js. * ref: Removes an unused function and adds documentation. * feat: Adds events for all API calls. * fix: Addresses feedback. * fix: Brings back mistakenly removed code. * fix: Simplifies code and fixes a bug in toggleFilmstrip when the 'visible' parameter is defined. * feat: Removes the resolution change application log. * ref: Uses consistent naming for events' attributes. Uses "_" as a separator instead of camel case or ".". * ref: Don't add the user agent and conference name as permanent properties. The library does this on its own now. * ref: Adapts the GA handler to changes in lib-jitsi-meet. * ref: Removes unused fields from the analytics handler initializaiton. * ref: Renames the google analytics file and add docs. * fix: Fixes the push-to-talk events and logs. * npm: Updates lib-jitsi-meet to 515374c8d383cb17df8ed76427e6f0fb5ea6ff1e. * fix: Fixes a recently introduced bug in the google analytics handler. * ref: Uses "value" instead of "delay" since this is friendlier to GA.
2018-01-03 21:24:07 +00:00
createStartMutedConfigurationEvent,
sendAnalytics
} from '../../analytics';
import { getName } from '../../app/functions';
import { endpointMessageReceived } from '../../subtitles';
import { JITSI_CONNECTION_CONFERENCE_KEY } from '../connection';
2017-02-28 03:21:50 +00:00
import { JitsiConferenceEvents } from '../lib-jitsi-meet';
import { setAudioMuted, setVideoMuted } from '../media';
import {
dominantSpeakerChanged,
getLocalParticipant,
2019-01-15 11:28:07 +00:00
getNormalizedDisplayName,
2017-04-05 09:01:57 +00:00
participantConnectionStatusChanged,
participantKicked,
participantMutedUs,
participantPresenceChanged,
participantRoleChanged,
participantUpdated
} from '../participants';
import { getLocalTracks, trackAdded, trackRemoved } from '../tracks';
2019-10-04 07:31:22 +00:00
import {
getBackendSafePath,
2019-10-04 07:31:22 +00:00
getBackendSafeRoomName,
getJitsiMeetGlobalNS
} from '../util';
import {
AUTH_STATUS_CHANGED,
2016-12-12 01:02:50 +00:00
CONFERENCE_FAILED,
CONFERENCE_JOINED,
CONFERENCE_LEFT,
2019-03-12 17:45:53 +00:00
CONFERENCE_SUBJECT_CHANGED,
2020-01-13 17:12:25 +00:00
CONFERENCE_TIMESTAMP_CHANGED,
CONFERENCE_WILL_JOIN,
CONFERENCE_WILL_LEAVE,
feat(quality-slider): initial implementation (#1817) * feat(quality-slider): initial implementation - Add new menu button with an Inline Dialog slider for selecting received video quality. - Place P2P status in redux store for the Inline Dialog to display a warning about not respecting video quality selection. - Respond to data channel open events by setting receive video quality. This is for lonely call cases where a setting is set before the data channel is open. - Remove dropdown menu from video status label and clean up related js and css. * first pass at addressing feedback - Move VideoStatusLabel to video-quality directory. - Rename VideoStatusLabel to VideoQualityLabel. - Open VideoQualitydialog from VideoQualityLabel. - New CSS for making VideoQualityLabel display properly. - Do not render VideoQualityLabel in filmstrip only instead of hiding with css. - Remove tooltip from VideoQualityLabel. - Show LD, SD, HD labels in VideoQualityLabel. - Remove action SET_LARGE_VIDEO_HD_STATUS from conference. - Create new action UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION in large-video. - Move VideoQualityButton into video-quality directory. - General renaming (medium -> standard, menu -> dialog). - Render P2P message between title and slider. - Add padding to slider for displacement caused by P2P message's new placement. - Fix display issue with VideoQualityButton displaying out of line in the primary toolbar. * second pass at addressing feedback - Fix p2p inline message color - Force labels to break on words - Resolve rebase issues, including only dispatching quality update on change. Before there was double calling of dispatch produced by an IE11 workaround. This breaks now when setting audio only mode to true twice. - Rename some instances of quality to definition * rename to data channel opened * do not show p2p in audio only * stop toggle audio only icon automatically * remove fixme about toolbar button * find closest resolution for label * toggle dialog on button click * redo last commit for both button and label
2017-08-09 19:40:03 +00:00
DATA_CHANNEL_OPENED,
KICKED_OUT,
2016-12-12 19:49:23 +00:00
LOCK_STATE_CHANGED,
feat(quality-slider): initial implementation (#1817) * feat(quality-slider): initial implementation - Add new menu button with an Inline Dialog slider for selecting received video quality. - Place P2P status in redux store for the Inline Dialog to display a warning about not respecting video quality selection. - Respond to data channel open events by setting receive video quality. This is for lonely call cases where a setting is set before the data channel is open. - Remove dropdown menu from video status label and clean up related js and css. * first pass at addressing feedback - Move VideoStatusLabel to video-quality directory. - Rename VideoStatusLabel to VideoQualityLabel. - Open VideoQualitydialog from VideoQualityLabel. - New CSS for making VideoQualityLabel display properly. - Do not render VideoQualityLabel in filmstrip only instead of hiding with css. - Remove tooltip from VideoQualityLabel. - Show LD, SD, HD labels in VideoQualityLabel. - Remove action SET_LARGE_VIDEO_HD_STATUS from conference. - Create new action UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION in large-video. - Move VideoQualityButton into video-quality directory. - General renaming (medium -> standard, menu -> dialog). - Render P2P message between title and slider. - Add padding to slider for displacement caused by P2P message's new placement. - Fix display issue with VideoQualityButton displaying out of line in the primary toolbar. * second pass at addressing feedback - Fix p2p inline message color - Force labels to break on words - Resolve rebase issues, including only dispatching quality update on change. Before there was double calling of dispatch produced by an IE11 workaround. This breaks now when setting audio only mode to true twice. - Rename some instances of quality to definition * rename to data channel opened * do not show p2p in audio only * stop toggle audio only icon automatically * remove fixme about toolbar button * find closest resolution for label * toggle dialog on button click * redo last commit for both button and label
2017-08-09 19:40:03 +00:00
P2P_STATUS_CHANGED,
SEND_TONES,
SET_DESKTOP_SHARING_ENABLED,
SET_FOLLOW_ME,
2016-12-12 01:02:50 +00:00
SET_PASSWORD,
SET_PASSWORD_FAILED,
SET_ROOM,
2019-03-12 17:45:53 +00:00
SET_PENDING_SUBJECT_CHANGE,
SET_START_MUTED_POLICY
} from './actionTypes';
import {
AVATAR_ID_COMMAND,
AVATAR_URL_COMMAND,
EMAIL_COMMAND,
JITSI_CONFERENCE_URL_KEY
} from './constants';
import {
_addLocalTracksToConference,
commonUserJoinedHandling,
commonUserLeftHandling,
getCurrentConference,
2017-10-13 19:31:05 +00:00
sendLocalParticipant
} from './functions';
import logger from './logger';
declare var APP: Object;
/**
2016-12-12 00:29:13 +00:00
* Adds conference (event) listeners.
*
2016-12-12 00:29:13 +00:00
* @param {JitsiConference} conference - The JitsiConference instance.
* @param {Dispatch} dispatch - The Redux dispatch function.
* @private
* @returns {void}
*/
2016-12-12 00:29:13 +00:00
function _addConferenceListeners(conference, dispatch) {
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,
error => logger.error('Conference error.', error));
2017-04-05 09:01:57 +00:00
// Dispatches into features/base/conference follow:
2016-12-12 01:02:50 +00:00
conference.on(
2017-06-15 00:40:51 +00:00
JitsiConferenceEvents.CONFERENCE_FAILED,
(...args) => dispatch(conferenceFailed(conference, ...args)));
2016-12-12 00:29:13 +00:00
conference.on(
2017-06-15 00:40:51 +00:00
JitsiConferenceEvents.CONFERENCE_JOINED,
(...args) => dispatch(conferenceJoined(conference, ...args)));
2016-12-12 00:29:13 +00:00
conference.on(
2017-06-15 00:40:51 +00:00
JitsiConferenceEvents.CONFERENCE_LEFT,
2020-01-13 17:12:25 +00:00
(...args) => {
dispatch(conferenceTimestampChanged(0));
dispatch(conferenceLeft(conference, ...args));
});
2019-05-29 07:53:12 +00:00
conference.on(JitsiConferenceEvents.SUBJECT_CHANGED,
(...args) => dispatch(conferenceSubjectChanged(...args)));
2020-01-13 17:12:25 +00:00
conference.on(JitsiConferenceEvents.CONFERENCE_CREATED_TIMESTAMP,
(...args) => dispatch(conferenceTimestampChanged(...args)));
conference.on(
JitsiConferenceEvents.KICKED,
(...args) => dispatch(kickedOut(conference, ...args)));
conference.on(
JitsiConferenceEvents.PARTICIPANT_KICKED,
(kicker, kicked) => dispatch(participantKicked(kicker, kicked)));
2016-12-12 19:49:23 +00:00
conference.on(
2017-06-15 00:40:51 +00:00
JitsiConferenceEvents.LOCK_STATE_CHANGED,
(...args) => dispatch(lockStateChanged(conference, ...args)));
2016-12-12 19:49:23 +00:00
// Dispatches into features/base/media follow:
conference.on(
JitsiConferenceEvents.STARTED_MUTED,
() => {
const audioMuted = Boolean(conference.startAudioMuted);
const videoMuted = Boolean(conference.startVideoMuted);
Restructures the analytics events (#2333) * ref: Restructures the pinned/unpinned events. * ref: Refactors the "audio only disabled" event. * ref: Refactors the "stream switch delay" event. * ref: Refactors the "select participant failed" event. * ref: Refactors the "initially muted" events. * ref: Refactors the screen sharing started/stopped events. * ref: Restructures the "device list changed" events. * ref: Restructures the "shared video" events. * ref: Restructures the "start muted" events. * ref: Restructures the "start audio only" event. * ref: Restructures the "sync track state" event. * ref: Restructures the "callkit" events. * ref: Restructures the "replace track". * ref: Restructures keyboard shortcuts events. * ref: Restructures most of the toolbar events. * ref: Refactors the API events. * ref: Restructures the video quality, profile button and invite dialog events. * ref: Refactors the "device changed" events. * ref: Refactors the page reload event. * ref: Removes an unused function. * ref: Removes a method which is needlessly exposed under a different name. * ref: Refactors the events from the remote video menu. * ref: Refactors the events from the profile pane. * ref: Restructures the recording-related events. Removes events fired when recording with something other than jibri (which isn't currently supported anyway). * ref: Cleans up AnalyticsEvents.js. * ref: Removes an unused function and adds documentation. * feat: Adds events for all API calls. * fix: Addresses feedback. * fix: Brings back mistakenly removed code. * fix: Simplifies code and fixes a bug in toggleFilmstrip when the 'visible' parameter is defined. * feat: Removes the resolution change application log. * ref: Uses consistent naming for events' attributes. Uses "_" as a separator instead of camel case or ".". * ref: Don't add the user agent and conference name as permanent properties. The library does this on its own now. * ref: Adapts the GA handler to changes in lib-jitsi-meet. * ref: Removes unused fields from the analytics handler initializaiton. * ref: Renames the google analytics file and add docs. * fix: Fixes the push-to-talk events and logs. * npm: Updates lib-jitsi-meet to 515374c8d383cb17df8ed76427e6f0fb5ea6ff1e. * fix: Fixes a recently introduced bug in the google analytics handler. * ref: Uses "value" instead of "delay" since this is friendlier to GA.
2018-01-03 21:24:07 +00:00
sendAnalytics(createStartMutedConfigurationEvent(
'remote', audioMuted, videoMuted));
logger.log(`Start muted: ${audioMuted ? 'audio, ' : ''}${
videoMuted ? 'video' : ''}`);
// 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.
dispatch(setAudioMuted(audioMuted));
dispatch(setVideoMuted(videoMuted));
});
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,
t => 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,
t => t && !t.isLocal() && dispatch(trackRemoved(t)));
conference.on(
JitsiConferenceEvents.TRACK_MUTE_CHANGED,
(_, participantThatMutedUs) => {
if (participantThatMutedUs) {
dispatch(participantMutedUs(participantThatMutedUs));
}
});
2017-04-05 09:01:57 +00:00
// Dispatches into features/base/participants follow:
conference.on(
JitsiConferenceEvents.DISPLAY_NAME_CHANGED,
(id, displayName) => 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,
id,
2019-01-15 11:28:07 +00:00
name: getNormalizedDisplayName(displayName)
})));
2017-04-05 09:01:57 +00:00
conference.on(
2017-06-15 00:40:51 +00:00
JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED,
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
id => dispatch(dominantSpeakerChanged(id, conference)));
2017-04-05 09:01:57 +00:00
conference.on(
JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
(...args) => dispatch(endpointMessageReceived(...args)));
2017-04-05 09:01:57 +00:00
conference.on(
2017-06-15 00:40:51 +00:00
JitsiConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED,
(...args) => 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,
(id, user) => 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,
(id, user) => commonUserLeftHandling({ dispatch }, conference, user));
2016-12-12 00:29:13 +00:00
conference.on(
2017-06-15 00:40:51 +00:00
JitsiConferenceEvents.USER_ROLE_CHANGED,
(...args) => dispatch(participantRoleChanged(...args)));
conference.on(
JitsiConferenceEvents.USER_STATUS_CHANGED,
(...args) => dispatch(participantPresenceChanged(...args)));
2018-06-26 22:56:22 +00:00
conference.on(
JitsiConferenceEvents.BOT_TYPE_CHANGED,
(id, botType) => dispatch(participantUpdated({
conference,
id,
botType
})));
conference.addCommandListener(
2017-06-15 00:40:51 +00:00
AVATAR_ID_COMMAND,
(data, id) => 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,
avatarID: data.value
})));
conference.addCommandListener(
2017-06-15 00:40:51 +00:00
AVATAR_URL_COMMAND,
(data, id) => 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,
(data, id) => 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
})));
}
/**
* 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
* }}
* @public
2016-12-12 01:02:50 +00:00
*/
export function conferenceFailed(conference: Object, 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: {
name: error,
params,
recoverable: undefined
2017-10-05 12:41:35 +00:00
}
2016-12-12 01:02:50 +00:00
};
}
/**
* Signals that a specific conference has been joined.
*
* @param {JitsiConference} conference - The JitsiConference instance which was
* joined by the local participant.
* @returns {{
* type: CONFERENCE_JOINED,
* conference: JitsiConference
* }}
*/
export function conferenceJoined(conference: Object) {
return {
type: CONFERENCE_JOINED,
conference
};
}
/**
* Signals that a specific conference has been left.
*
* @param {JitsiConference} conference - The JitsiConference instance which was
* left by the local participant.
* @returns {{
2017-04-19 14:52:27 +00:00
* type: CONFERENCE_LEFT,
* conference: JitsiConference
* }}
*/
export function conferenceLeft(conference: Object) {
return {
type: CONFERENCE_LEFT,
conference
};
}
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
};
}
/**
* 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.
*
* @param {JitsiConference} conference - The {@code JitsiConference} instance
* the local participant will (try to) join.
* @returns {Function}
*/
function _conferenceWillJoin(conference: Object) {
2019-03-19 15:42:25 +00:00
return (dispatch: Dispatch<any>, getState: Function) => {
const localTracks
= getLocalTracks(getState()['features/base/tracks'])
.map(t => t.jitsiTrack);
if (localTracks.length) {
_addLocalTracksToConference(conference, localTracks);
}
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
* }}
*/
export function conferenceWillJoin(conference: Object) {
return {
type: CONFERENCE_WILL_JOIN,
conference
};
}
/**
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
* 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
* }}
*/
export function conferenceWillLeave(conference: Object) {
return {
type: CONFERENCE_WILL_LEAVE,
2016-12-12 00:29:13 +00:00
conference
};
}
/**
* Initializes a new conference.
*
* @returns {Function}
*/
export function createConference() {
return (dispatch: Function, getState: Function) => {
2016-12-12 00:29:13 +00:00
const state = getState();
const { connection, locationURL } = state['features/base/connection'];
2016-12-12 00:29:13 +00:00
if (!connection) {
throw new Error('Cannot create a conference without a connection!');
}
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
if (!room) {
throw new Error('Cannot join a conference without a room name!');
2016-12-12 00:29:13 +00:00
}
const config = state['features/base/config'];
const { tenant } = state['features/base/jwt'];
const { email, name: nick } = getLocalParticipant(state);
2016-12-12 00:29:13 +00:00
const conference
2017-01-15 19:05:17 +00:00
= connection.initJitsiConference(
2019-10-04 07:31:22 +00:00
getBackendSafeRoomName(room), {
...config,
applicationName: getName(),
getWiFiStatsMethod: getJitsiMeetGlobalNS().getWiFiStats,
confID: `${locationURL.host}${getBackendSafePath(locationURL.pathname)}`,
siteID: tenant,
statisticsDisplayName: config.enableDisplayNameInStats ? nick : undefined,
statisticsId: config.enableEmailInStats ? email : undefined
});
2016-12-12 00:29:13 +00:00
connection[JITSI_CONNECTION_CONFERENCE_KEY] = conference;
conference[JITSI_CONFERENCE_URL_KEY] = locationURL;
dispatch(_conferenceWillJoin(conference));
2016-12-12 00:29:13 +00:00
_addConferenceListeners(conference, dispatch);
2017-10-13 19:31:05 +00:00
sendLocalParticipant(state, conference);
2016-12-12 01:02:50 +00:00
conference.join(password);
};
}
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() {
return (dispatch: Function, getState: Function) => {
2017-09-18 07:09:43 +00:00
const { authRequired, password }
2017-09-08 13:36:42 +00:00
= getState()['features/base/conference'];
authRequired && dispatch(_conferenceWillJoin(authRequired));
2017-09-18 07:09:43 +00:00
authRequired && authRequired.join(password);
2017-09-08 13:36:42 +00:00
};
}
feat(quality-slider): initial implementation (#1817) * feat(quality-slider): initial implementation - Add new menu button with an Inline Dialog slider for selecting received video quality. - Place P2P status in redux store for the Inline Dialog to display a warning about not respecting video quality selection. - Respond to data channel open events by setting receive video quality. This is for lonely call cases where a setting is set before the data channel is open. - Remove dropdown menu from video status label and clean up related js and css. * first pass at addressing feedback - Move VideoStatusLabel to video-quality directory. - Rename VideoStatusLabel to VideoQualityLabel. - Open VideoQualitydialog from VideoQualityLabel. - New CSS for making VideoQualityLabel display properly. - Do not render VideoQualityLabel in filmstrip only instead of hiding with css. - Remove tooltip from VideoQualityLabel. - Show LD, SD, HD labels in VideoQualityLabel. - Remove action SET_LARGE_VIDEO_HD_STATUS from conference. - Create new action UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION in large-video. - Move VideoQualityButton into video-quality directory. - General renaming (medium -> standard, menu -> dialog). - Render P2P message between title and slider. - Add padding to slider for displacement caused by P2P message's new placement. - Fix display issue with VideoQualityButton displaying out of line in the primary toolbar. * second pass at addressing feedback - Fix p2p inline message color - Force labels to break on words - Resolve rebase issues, including only dispatching quality update on change. Before there was double calling of dispatch produced by an IE11 workaround. This breaks now when setting audio only mode to true twice. - Rename some instances of quality to definition * rename to data channel opened * do not show p2p in audio only * stop toggle audio only icon automatically * remove fixme about toolbar button * find closest resolution for label * toggle dialog on button click * redo last commit for both button and label
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
};
}
/**
* Signals that we've been kicked out of the conference.
*
* @param {JitsiConference} conference - The {@link JitsiConference} instance
* for which the event is being signaled.
* @param {JitsiParticipant} participant - The {@link JitsiParticipant}
* instance which initiated the kick event.
* @returns {{
* type: KICKED_OUT,
* conference: JitsiConference,
* participant: JitsiParticipant
* }}
*/
export function kickedOut(conference: Object, participant: Object) {
return {
type: KICKED_OUT,
conference,
participant
};
}
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
* }}
*/
export function lockStateChanged(conference: Object, locked: boolean) {
2016-12-12 19:49:23 +00:00
return {
type: LOCK_STATE_CHANGED,
conference,
locked
};
}
/**
* 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
};
}
/**
feat(quality-slider): initial implementation (#1817) * feat(quality-slider): initial implementation - Add new menu button with an Inline Dialog slider for selecting received video quality. - Place P2P status in redux store for the Inline Dialog to display a warning about not respecting video quality selection. - Respond to data channel open events by setting receive video quality. This is for lonely call cases where a setting is set before the data channel is open. - Remove dropdown menu from video status label and clean up related js and css. * first pass at addressing feedback - Move VideoStatusLabel to video-quality directory. - Rename VideoStatusLabel to VideoQualityLabel. - Open VideoQualitydialog from VideoQualityLabel. - New CSS for making VideoQualityLabel display properly. - Do not render VideoQualityLabel in filmstrip only instead of hiding with css. - Remove tooltip from VideoQualityLabel. - Show LD, SD, HD labels in VideoQualityLabel. - Remove action SET_LARGE_VIDEO_HD_STATUS from conference. - Create new action UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION in large-video. - Move VideoQualityButton into video-quality directory. - General renaming (medium -> standard, menu -> dialog). - Render P2P message between title and slider. - Add padding to slider for displacement caused by P2P message's new placement. - Fix display issue with VideoQualityButton displaying out of line in the primary toolbar. * second pass at addressing feedback - Fix p2p inline message color - Force labels to break on words - Resolve rebase issues, including only dispatching quality update on change. Before there was double calling of dispatch produced by an IE11 workaround. This breaks now when setting audio only mode to true twice. - Rename some instances of quality to definition * rename to data channel opened * do not show p2p in audio only * stop toggle audio only icon automatically * remove fixme about toolbar button * find closest resolution for label * toggle dialog on button click * redo last commit for both button and label
2017-08-09 19:40:03 +00:00
* Sets whether or not peer2peer is currently enabled.
*
feat(quality-slider): initial implementation (#1817) * feat(quality-slider): initial implementation - Add new menu button with an Inline Dialog slider for selecting received video quality. - Place P2P status in redux store for the Inline Dialog to display a warning about not respecting video quality selection. - Respond to data channel open events by setting receive video quality. This is for lonely call cases where a setting is set before the data channel is open. - Remove dropdown menu from video status label and clean up related js and css. * first pass at addressing feedback - Move VideoStatusLabel to video-quality directory. - Rename VideoStatusLabel to VideoQualityLabel. - Open VideoQualitydialog from VideoQualityLabel. - New CSS for making VideoQualityLabel display properly. - Do not render VideoQualityLabel in filmstrip only instead of hiding with css. - Remove tooltip from VideoQualityLabel. - Show LD, SD, HD labels in VideoQualityLabel. - Remove action SET_LARGE_VIDEO_HD_STATUS from conference. - Create new action UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION in large-video. - Move VideoQualityButton into video-quality directory. - General renaming (medium -> standard, menu -> dialog). - Render P2P message between title and slider. - Add padding to slider for displacement caused by P2P message's new placement. - Fix display issue with VideoQualityButton displaying out of line in the primary toolbar. * second pass at addressing feedback - Fix p2p inline message color - Force labels to break on words - Resolve rebase issues, including only dispatching quality update on change. Before there was double calling of dispatch produced by an IE11 workaround. This breaks now when setting audio only mode to true twice. - Rename some instances of quality to definition * rename to data channel opened * do not show p2p in audio only * stop toggle audio only icon automatically * remove fixme about toolbar button * find closest resolution for label * toggle dialog on button click * redo last commit for both button and label
2017-08-09 19:40:03 +00:00
* @param {boolean} p2p - Whether or not peer2peer is currently active.
* @returns {{
feat(quality-slider): initial implementation (#1817) * feat(quality-slider): initial implementation - Add new menu button with an Inline Dialog slider for selecting received video quality. - Place P2P status in redux store for the Inline Dialog to display a warning about not respecting video quality selection. - Respond to data channel open events by setting receive video quality. This is for lonely call cases where a setting is set before the data channel is open. - Remove dropdown menu from video status label and clean up related js and css. * first pass at addressing feedback - Move VideoStatusLabel to video-quality directory. - Rename VideoStatusLabel to VideoQualityLabel. - Open VideoQualitydialog from VideoQualityLabel. - New CSS for making VideoQualityLabel display properly. - Do not render VideoQualityLabel in filmstrip only instead of hiding with css. - Remove tooltip from VideoQualityLabel. - Show LD, SD, HD labels in VideoQualityLabel. - Remove action SET_LARGE_VIDEO_HD_STATUS from conference. - Create new action UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION in large-video. - Move VideoQualityButton into video-quality directory. - General renaming (medium -> standard, menu -> dialog). - Render P2P message between title and slider. - Add padding to slider for displacement caused by P2P message's new placement. - Fix display issue with VideoQualityButton displaying out of line in the primary toolbar. * second pass at addressing feedback - Fix p2p inline message color - Force labels to break on words - Resolve rebase issues, including only dispatching quality update on change. Before there was double calling of dispatch produced by an IE11 workaround. This breaks now when setting audio only mode to true twice. - Rename some instances of quality to definition * rename to data channel opened * do not show p2p in audio only * stop toggle audio only icon automatically * remove fixme about toolbar button * find closest resolution for label * toggle dialog on button click * redo last commit for both button and label
2017-08-09 19:40:03 +00:00
* type: P2P_STATUS_CHANGED,
* p2p: boolean
* }}
*/
export function p2pStatusChanged(p2p: boolean) {
return {
feat(quality-slider): initial implementation (#1817) * feat(quality-slider): initial implementation - Add new menu button with an Inline Dialog slider for selecting received video quality. - Place P2P status in redux store for the Inline Dialog to display a warning about not respecting video quality selection. - Respond to data channel open events by setting receive video quality. This is for lonely call cases where a setting is set before the data channel is open. - Remove dropdown menu from video status label and clean up related js and css. * first pass at addressing feedback - Move VideoStatusLabel to video-quality directory. - Rename VideoStatusLabel to VideoQualityLabel. - Open VideoQualitydialog from VideoQualityLabel. - New CSS for making VideoQualityLabel display properly. - Do not render VideoQualityLabel in filmstrip only instead of hiding with css. - Remove tooltip from VideoQualityLabel. - Show LD, SD, HD labels in VideoQualityLabel. - Remove action SET_LARGE_VIDEO_HD_STATUS from conference. - Create new action UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION in large-video. - Move VideoQualityButton into video-quality directory. - General renaming (medium -> standard, menu -> dialog). - Render P2P message between title and slider. - Add padding to slider for displacement caused by P2P message's new placement. - Fix display issue with VideoQualityButton displaying out of line in the primary toolbar. * second pass at addressing feedback - Fix p2p inline message color - Force labels to break on words - Resolve rebase issues, including only dispatching quality update on change. Before there was double calling of dispatch produced by an IE11 workaround. This breaks now when setting audio only mode to true twice. - Rename some instances of quality to definition * rename to data channel opened * do not show p2p in audio only * stop toggle audio only icon automatically * remove fixme about toolbar button * find closest resolution for label * toggle dialog on button click * redo last commit for both button and label
2017-08-09 19:40:03 +00:00
type: P2P_STATUS_CHANGED,
p2p
};
}
/**
* 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
};
}
/**
* Sets the flag for indicating if desktop sharing is enabled.
*
* @param {boolean} desktopSharingEnabled - True if desktop sharing is enabled.
* @returns {{
* type: SET_DESKTOP_SHARING_ENABLED,
* desktopSharingEnabled: boolean
* }}
*/
export function setDesktopSharingEnabled(desktopSharingEnabled: boolean) {
return {
type: SET_DESKTOP_SHARING_ENABLED,
desktopSharingEnabled
};
}
/**
* 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
};
}
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
*/
export function setPassword(
conference: Object,
method: Function,
password: string) {
2019-03-19 15:42:25 +00:00
return (dispatch: Dispatch<any>, getState: Function): ?Promise<void> => {
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
}))
.catch(error => dispatch({
type: SET_PASSWORD_FAILED,
error
}))
);
2016-12-13 09:14:04 +00:00
}
return Promise.reject();
}
}
};
}
/**
* 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
* }}
*/
export function setRoom(room: ?string) {
return {
type: SET_ROOM,
room
};
}
/**
* 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) {
2019-03-19 15:42:25 +00:00
return (dispatch: Dispatch<any>, getState: Function) => {
const conference = getCurrentConference(getState());
conference && conference.setStartMutedPolicy({
audio: startAudioMuted,
video: startVideoMuted
});
return dispatch(
onStartMutedPolicyChanged(startAudioMuted, startVideoMuted));
};
}
/**
* Changing conference subject.
*
* @param {string} subject - The new subject.
* @returns {void}
*/
export function setSubject(subject: string) {
2019-03-19 15:42:25 +00:00
return (dispatch: Dispatch<any>, getState: Function) => {
2019-03-12 17:45:53 +00:00
const { conference } = getState()['features/base/conference'];
if (conference) {
conference.setSubject(subject || '');
2019-03-12 17:45:53 +00:00
} else {
dispatch({
type: SET_PENDING_SUBJECT_CHANGE,
subject
});
}
};
}