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

635 lines
22 KiB
JavaScript
Raw Normal View History

2017-10-04 22:36:09 +00:00
// @flow
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
ACTION_PINNED,
ACTION_UNPINNED,
2019-06-17 10:35:47 +00:00
createOfferAnswerFailedEvent,
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
createPinnedEvent,
sendAnalytics
} from '../../analytics';
2020-05-20 10:57:03 +00:00
import { openDisplayNamePrompt } from '../../display-name';
import { showErrorNotification } from '../../notifications';
import { CONNECTION_ESTABLISHED, CONNECTION_FAILED, connectionDisconnected } from '../connection';
2019-06-17 10:35:47 +00:00
import { JitsiConferenceErrors } from '../lib-jitsi-meet';
2020-05-20 10:57:03 +00:00
import { MEDIA_TYPE } from '../media';
import {
getLocalParticipant,
getParticipantById,
getPinnedParticipant,
PARTICIPANT_ROLE,
2019-01-13 19:33:28 +00:00
PARTICIPANT_UPDATED,
PIN_PARTICIPANT
} from '../participants';
import { MiddlewareRegistry, StateListenerRegistry } from '../redux';
import { TRACK_ADDED, TRACK_REMOVED } from '../tracks';
import {
CONFERENCE_FAILED,
CONFERENCE_JOINED,
2019-03-12 17:45:53 +00:00
CONFERENCE_SUBJECT_CHANGED,
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,
SEND_TONES,
SET_PENDING_SUBJECT_CHANGE,
SET_ROOM
} from './actionTypes';
2020-05-20 10:57:03 +00:00
import {
conferenceFailed,
conferenceWillLeave,
createConference,
setSubject
} from './actions';
import {
_addLocalTracksToConference,
_removeLocalTracksFromConference,
fix(base/participants): ensure default local id outside of conference Makes sure that whenever a conference is left or switched, the local participant's id will be equal to the default value. The problem fixed by this commit is a situation where the local participant may end up sharing the same ID with it's "ghost" when rejoining a disconnected conference. The most important and easiest to hit case is when the conference is left after the CONFERENCE_FAILED event. Another rare and harder to encounter in the real world issue is where CONFERENCE_LEFT may come with the delay due to it's asynchronous nature. The step by step scenario is as follows: trying to leave a conference, but the network is not doing well, so it takes time, requests are timing out. After getting back to the welcome page the the CONFERENCE_LEFT has not arrived yet. The same conference is joined again and the load config may timeout, but it will be read from the cache. Now the network gets better and conference is joining which results in our ghost participant added to the redux state. At this point there's the root issue: two participants with the same id, because the local one was neither cleared nor set to the new one yet (PARTICIPANT_JOINED come, before CONFERENCE_JOINED where we adjust the id). Then comes CONFERENCE_JOINED and we try to update our local id. We're updating the ID of both ghost and local participant. It could be also that the delayed CONFERENCE_LEFT comes for the old conference, but it's too late and it would update the id for both participants. The approach here reasons that the ID of the local participant may be reset as soon as the local participant and, respectively, her ID is no longer involved in a recoverable JitsiConference of interest to the user and, consequently, the app. Co-authored-by: Pawel Domas <pawel.domas@jitsi.org> Co-authored-by: Lyubo Marinov <lmarinov@atlassian.com>
2018-05-16 20:08:34 +00:00
forEachConference,
getCurrentConference
} from './functions';
import logger from './logger';
2017-10-04 22:36:09 +00:00
declare var APP: Object;
/**
* Handler for before unload event.
*/
let beforeUnloadHandler;
/**
* Implements the middleware of the feature base/conference.
*
* @param {Store} store - The redux store.
* @returns {Function}
*/
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case CONFERENCE_FAILED:
return _conferenceFailed(store, next, action);
case CONFERENCE_JOINED:
return _conferenceJoined(store, next, action);
case CONNECTION_ESTABLISHED:
return _connectionEstablished(store, next, action);
case CONNECTION_FAILED:
return _connectionFailed(store, next, action);
2019-03-12 17:45:53 +00:00
case CONFERENCE_SUBJECT_CHANGED:
return _conferenceSubjectChanged(store, next, action);
case CONFERENCE_WILL_LEAVE:
_conferenceWillLeave();
break;
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
case DATA_CHANNEL_OPENED:
return _syncReceiveVideoQuality(store, next, action);
2019-01-13 19:33:28 +00:00
case PARTICIPANT_UPDATED:
return _updateLocalParticipantInConference(store, next, action);
case PIN_PARTICIPANT:
return _pinParticipant(store, next, action);
case SEND_TONES:
return _sendTones(store, next, action);
case SET_ROOM:
return _setRoom(store, next, action);
case TRACK_ADDED:
case TRACK_REMOVED:
return _trackAddedOrRemoved(store, next, action);
}
return next(action);
});
/**
* Registers a change handler for state['features/base/conference'] to update
* the preferred video quality levels based on user preferred and internal
* settings.
*/
StateListenerRegistry.register(
/* selector */ state => state['features/base/conference'],
/* listener */ (currentState, store, previousState = {}) => {
const {
conference,
maxReceiverVideoQuality,
preferredVideoQuality
} = currentState;
const changedConference = conference !== previousState.conference;
const changedPreferredVideoQuality
= preferredVideoQuality !== previousState.preferredVideoQuality;
const changedMaxVideoQuality = maxReceiverVideoQuality !== previousState.maxReceiverVideoQuality;
if (changedConference || changedPreferredVideoQuality || changedMaxVideoQuality) {
_setReceiverVideoConstraint(conference, preferredVideoQuality, maxReceiverVideoQuality);
}
if (changedConference || changedPreferredVideoQuality) {
_setSenderVideoConstraint(conference, preferredVideoQuality);
}
});
/**
* Makes sure to leave a failed conference in order to release any allocated
* resources like peer connections, emit participant left events, etc.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code CONFERENCE_FAILED} which is
* being dispatched in the specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _conferenceFailed({ dispatch, getState }, next, action) {
const result = next(action);
2019-06-17 10:35:47 +00:00
const { conference, error } = action;
// Handle specific failure reasons.
switch (error.name) {
case JitsiConferenceErrors.CONFERENCE_DESTROYED: {
const [ reason ] = error.params;
dispatch(showErrorNotification({
description: reason,
titleKey: 'dialog.sessTerminated'
}));
if (typeof APP !== 'undefined') {
APP.UI.hideStats();
}
break;
}
case JitsiConferenceErrors.CONNECTION_ERROR: {
const [ msg ] = error.params;
2020-05-20 08:25:31 +00:00
dispatch(connectionDisconnected(getState()['features/base/connection'].connection));
dispatch(showErrorNotification({
descriptionArguments: { msg },
descriptionKey: msg ? 'dialog.connectErrorWithMsg' : 'dialog.connectError',
titleKey: 'connection.CONNFAIL'
}));
break;
}
2020-05-20 08:25:31 +00:00
case JitsiConferenceErrors.OFFER_ANSWER_FAILED:
sendAnalytics(createOfferAnswerFailedEvent());
break;
}
// FIXME: Workaround for the web version. Currently, the creation of the
// conference is handled by /conference.js and appropriate failure handlers
// are set there.
if (typeof APP !== 'undefined') {
if (typeof beforeUnloadHandler !== 'undefined') {
window.removeEventListener('beforeunload', beforeUnloadHandler);
beforeUnloadHandler = undefined;
}
return result;
}
// XXX After next(action), it is clear whether the error is recoverable.
!error.recoverable
&& conference
&& conference.leave().catch(reason => {
// Even though we don't care too much about the failure, it may be
// good to know that it happen, so log it (on the info level).
logger.info('JitsiConference.leave() rejected with:', reason);
});
return result;
}
/**
* Does extra sync up on properties that may need to be updated after the
* conference was joined.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code CONFERENCE_JOINED} which is
* being dispatched in the specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _conferenceJoined({ dispatch, getState }, next, action) {
const result = next(action);
const { conference } = action;
const { pendingSubjectChange } = getState()['features/base/conference'];
const { requireDisplayName } = getState()['features/base/config'];
pendingSubjectChange && dispatch(setSubject(pendingSubjectChange));
// FIXME: Very dirty solution. This will work on web only.
// When the user closes the window or quits the browser, lib-jitsi-meet
// handles the process of leaving the conference. This is temporary solution
// that should cover the described use case as part of the effort to
// implement the conferenceWillLeave action for web.
beforeUnloadHandler = () => {
dispatch(conferenceWillLeave(conference));
};
window.addEventListener('beforeunload', beforeUnloadHandler);
if (requireDisplayName
&& !getLocalParticipant(getState)?.name
&& !conference.isHidden()) {
dispatch(openDisplayNamePrompt(undefined));
}
return result;
}
/**
* Notifies the feature base/conference that the action
* {@code CONNECTION_ESTABLISHED} is being dispatched within a specific redux
* store.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code CONNECTION_ESTABLISHED}
* which is being dispatched in the specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _connectionEstablished({ dispatch }, next, action) {
const result = next(action);
// FIXME: Workaround for the web version. Currently, the creation of the
// conference is handled by /conference.js.
typeof APP === 'undefined' && dispatch(createConference());
return result;
}
/**
* Notifies the feature base/conference that the action
* {@code CONNECTION_FAILED} is being dispatched within a specific redux
* store.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code CONNECTION_FAILED} which is
* being dispatched in the specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _connectionFailed({ dispatch, getState }, next, action) {
const result = next(action);
if (typeof beforeUnloadHandler !== 'undefined') {
window.removeEventListener('beforeunload', beforeUnloadHandler);
beforeUnloadHandler = undefined;
}
// FIXME: Workaround for the web version. Currently, the creation of the
// conference is handled by /conference.js and appropriate failure handlers
// are set there.
if (typeof APP === 'undefined') {
const { connection } = action;
const { error } = action;
forEachConference(getState, conference => {
// It feels that it would make things easier if JitsiConference
// in lib-jitsi-meet would monitor it's connection and emit
// CONFERENCE_FAILED when it's dropped. It has more knowledge on
// whether it can recover or not. But because the reload screen
// and the retry logic is implemented in the app maybe it can be
// left this way for now.
if (conference.getConnection() === connection) {
// XXX Note that on mobile the error type passed to
// connectionFailed is always an object with .name property.
// This fact needs to be checked prior to enabling this logic on
// web.
const conferenceAction
= conferenceFailed(conference, error.name);
// Copy the recoverable flag if set on the CONNECTION_FAILED
// action to not emit recoverable action caused by
// a non-recoverable one.
if (typeof error.recoverable !== 'undefined') {
conferenceAction.error.recoverable = error.recoverable;
}
dispatch(conferenceAction);
}
return true;
});
}
return result;
}
2019-03-12 17:45:53 +00:00
/**
* Notifies the feature base/conference that the action
* {@code CONFERENCE_SUBJECT_CHANGED} is being dispatched within a specific
* redux store.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code CONFERENCE_SUBJECT_CHANGED}
* which is being dispatched in the specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _conferenceSubjectChanged({ dispatch, getState }, next, action) {
2019-03-12 17:45:53 +00:00
const result = next(action);
const { subject } = getState()['features/base/conference'];
if (subject) {
dispatch({
type: SET_PENDING_SUBJECT_CHANGE,
subject: undefined
});
}
2019-03-12 17:45:53 +00:00
typeof APP === 'object' && APP.API.notifySubjectChanged(subject);
return result;
}
/**
* Notifies the feature base/conference that the action
* {@code CONFERENCE_WILL_LEAVE} is being dispatched within a specific redux
* store.
*
* @private
* @returns {void}
*/
function _conferenceWillLeave() {
if (typeof beforeUnloadHandler !== 'undefined') {
window.removeEventListener('beforeunload', beforeUnloadHandler);
beforeUnloadHandler = undefined;
}
}
/**
* Notifies the feature base/conference that the action {@code PIN_PARTICIPANT}
* is being dispatched within a specific redux store. Pins the specified remote
* participant in the associated conference, ignores the local participant.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code PIN_PARTICIPANT} which is
* being dispatched in the specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _pinParticipant({ getState }, next, action) {
const state = getState();
const { conference } = state['features/base/conference'];
if (!conference) {
return next(action);
}
const participants = state['features/base/participants'];
const id = action.participant.id;
const participantById = getParticipantById(participants, id);
const pinnedParticipant = getPinnedParticipant(participants);
const actionName = id ? ACTION_PINNED : ACTION_UNPINNED;
const local
= (participantById && participantById.local)
|| (!id && pinnedParticipant && pinnedParticipant.local);
let participantIdForEvent;
if (local) {
participantIdForEvent = local;
} else {
participantIdForEvent
= actionName === ACTION_PINNED ? id : pinnedParticipant && pinnedParticipant.id;
}
sendAnalytics(createPinnedEvent(
actionName,
participantIdForEvent,
{
local,
'participant_count': conference.getParticipantCount()
}));
return next(action);
}
/**
* Requests the specified tones to be played.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code SEND_TONES} which is
* being dispatched in the specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _sendTones({ getState }, next, action) {
const state = getState();
const { conference } = state['features/base/conference'];
if (conference) {
const { duration, tones, pause } = action;
conference.sendTones(tones, duration, pause);
}
return next(action);
}
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
/**
* Helper function for updating the preferred receiver video constraint, based
* on the user preference and the internal maximum.
*
* @param {JitsiConference} conference - The JitsiConference instance for the
* current call.
* @param {number} preferred - The user preferred max frame height.
* @param {number} max - The maximum frame height the application should
* receive.
* @returns {void}
*/
function _setReceiverVideoConstraint(conference, preferred, max) {
if (conference) {
const value = Math.min(preferred, max);
conference.setReceiverVideoConstraint(value);
logger.info(`setReceiverVideoConstraint: ${value}`);
}
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
}
/**
* Helper function for updating the preferred sender video constraint, based
* on the user preference.
*
* @param {JitsiConference} conference - The JitsiConference instance for the
* current call.
* @param {number} preferred - The user preferred max frame height.
* @returns {void}
*/
function _setSenderVideoConstraint(conference, preferred) {
if (conference) {
conference.setSenderVideoConstraint(preferred)
.catch(err => {
logger.error(`Changing sender resolution to ${preferred} failed - ${err} `);
});
}
}
/**
* Notifies the feature base/conference that the action
* {@code SET_ROOM} is being dispatched within a specific
* redux store.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code SET_ROOM}
* which is being dispatched in the specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _setRoom({ dispatch, getState }, next, action) {
const state = getState();
const { subject } = state['features/base/config'];
const { room } = action;
if (room) {
// Set the stored subject.
dispatch(setSubject(subject));
}
return next(action);
}
2016-12-12 00:29:13 +00:00
/**
* Synchronizes local tracks from state with local tracks in JitsiConference
* instance.
*
* @param {Store} store - The redux store.
2016-12-12 00:29:13 +00:00
* @param {Object} action - Action object.
* @private
* @returns {Promise}
*/
2017-10-04 22:36:09 +00:00
function _syncConferenceLocalTracksWithState({ getState }, action) {
const conference = getCurrentConference(getState);
2016-12-12 00:29:13 +00:00
let promise;
if (conference) {
2016-12-12 00:29:13 +00:00
const track = action.track.jitsiTrack;
if (action.type === TRACK_ADDED) {
promise = _addLocalTracksToConference(conference, [ track ]);
} else {
promise = _removeLocalTracksFromConference(conference, [ track ]);
}
}
return promise || Promise.resolve();
}
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 the maximum receive video quality.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code DATA_CHANNEL_STATUS_CHANGED}
* which is being dispatched in the specified {@code store}.
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
* @private
* @returns {Object} The value returned by {@code next(action)}.
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
*/
2017-10-04 22:36:09 +00:00
function _syncReceiveVideoQuality({ getState }, next, action) {
const {
conference,
maxReceiverVideoQuality,
preferredVideoQuality
} = getState()['features/base/conference'];
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
_setReceiverVideoConstraint(
conference,
preferredVideoQuality,
maxReceiverVideoQuality);
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
return next(action);
}
/**
* Notifies the feature base/conference that the action {@code TRACK_ADDED}
* or {@code TRACK_REMOVED} is being dispatched within a specific redux store.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code TRACK_ADDED} or
* {@code TRACK_REMOVED} which is being dispatched in the specified
* {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _trackAddedOrRemoved(store, next, action) {
const track = action.track;
// TODO All track swapping should happen here instead of conference.js.
// Since we swap the tracks for the web client in conference.js, ignore
// presenter tracks here and do not add/remove them to/from the conference.
if (track && track.local && track.mediaType !== MEDIA_TYPE.PRESENTER) {
return (
_syncConferenceLocalTracksWithState(store, action)
.then(() => next(action)));
}
return next(action);
}
2019-01-13 19:33:28 +00:00
/**
* Updates the conference object when the local participant is updated.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action which is being dispatched in the
* specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _updateLocalParticipantInConference({ dispatch, getState }, next, action) {
2019-01-13 19:33:28 +00:00
const { conference } = getState()['features/base/conference'];
const { participant } = action;
const result = next(action);
const localParticipant = getLocalParticipant(getState);
if (conference && participant.id === localParticipant.id) {
if ('name' in participant) {
conference.setDisplayName(participant.name);
}
if ('role' in participant && participant.role === PARTICIPANT_ROLE.MODERATOR) {
const { pendingSubjectChange, subject } = getState()['features/base/conference'];
// When the local user role is updated to moderator and we have a pending subject change
// which was not reflected we need to set it (the first time we tried was before becoming moderator).
if (typeof pendingSubjectChange !== 'undefined' && pendingSubjectChange !== subject) {
dispatch(setSubject(pendingSubjectChange));
}
}
2019-01-13 19:33:28 +00:00
}
return result;
}