jiti-meet/react/features/large-video/actions.js

165 lines
5.3 KiB
JavaScript
Raw Normal View History

2017-10-04 22:36:09 +00:00
// @flow
2019-03-19 15:42:25 +00:00
import type { Dispatch } from 'redux';
import {
createSelectParticipantFailedEvent,
sendAnalytics
} from '../analytics';
import { _handleParticipantError } from '../base/conference';
import { MEDIA_TYPE } from '../base/media';
import { getParticipants } from '../base/participants';
import { reportError } from '../base/util';
import { shouldDisplayTileView } from '../video-layout';
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
import {
SELECT_LARGE_VIDEO_PARTICIPANT,
UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION
} from './actionTypes';
declare var APP: Object;
/**
* Signals conference to select a participant.
*
* @returns {Function}
*/
export function selectParticipant() {
2019-03-19 15:42:25 +00:00
return (dispatch: Dispatch<any>, getState: Function) => {
const state = getState();
2017-10-04 22:36:09 +00:00
const { conference } = state['features/base/conference'];
if (conference) {
const ids = shouldDisplayTileView(state)
? getParticipants(state).map(participant => participant.id)
: [ state['features/large-video'].participantId ];
try {
conference.selectParticipants(ids);
} catch (err) {
_handleParticipantError(err);
sendAnalytics(createSelectParticipantFailedEvent(err));
reportError(
err, `Failed to select participants ${ids.toString()}`);
}
}
};
}
/**
* Action to select the participant to be displayed in LargeVideo based on a
* variety of factors: If there is a dominant or pinned speaker, or if there are
2017-01-17 14:32:20 +00:00
* remote tracks, etc.
*
* @returns {Function}
*/
export function selectParticipantInLargeVideo() {
2019-03-19 15:42:25 +00:00
return (dispatch: Dispatch<any>, getState: Function) => {
const state = getState();
const participantId = _electParticipantInLargeVideo(state);
2017-01-17 14:44:50 +00:00
const largeVideo = state['features/large-video'];
if (participantId !== largeVideo.participantId) {
dispatch({
type: SELECT_LARGE_VIDEO_PARTICIPANT,
participantId
});
dispatch(selectParticipant());
}
};
}
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
/**
* Updates the currently seen resolution of the video displayed on large video.
*
* @param {number} resolution - The current resolution (height) of the video.
* @returns {{
* type: UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION,
* resolution: number
* }}
*/
2017-10-04 22:36:09 +00:00
export function updateKnownLargeVideoResolution(resolution: number) {
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 {
type: UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION,
resolution
};
}
/**
* Returns the most recent existing remote video track.
*
* @param {Track[]} tracks - All current tracks.
* @private
* @returns {(Track|undefined)}
*/
function _electLastVisibleRemoteVideo(tracks) {
// First we try to get most recent remote video track.
for (let i = tracks.length - 1; i >= 0; --i) {
const track = tracks[i];
if (!track.local && track.mediaType === MEDIA_TYPE.VIDEO) {
return track;
}
}
}
/**
* Returns the identifier of the participant who is to be on the stage and
* should be displayed in {@code LargeVideo}.
*
* @param {Object} state - The Redux state from which the participant to be
* displayed in {@code LargeVideo} is to be elected.
* @private
* @returns {(string|undefined)}
*/
function _electParticipantInLargeVideo(state) {
2017-10-09 15:03:02 +00:00
// 1. If a participant is pinned, they will be shown in the LargeVideo (
// regardless of whether they are local or remote).
const participants = state['features/base/participants'];
let participant = participants.find(p => p.pinned);
let id = participant && participant.id;
if (!id) {
2017-10-09 15:03:02 +00:00
// 2. No participant is pinned so get the dominant speaker. But the
// local participant won't be displayed in LargeVideo even if she is
// the dominant speaker.
participant = participants.find(p => p.dominantSpeaker && !p.local);
id = participant && participant.id;
if (!id) {
2017-10-09 15:03:02 +00:00
// 3. There is no dominant speaker so select the remote participant
// who last had visible video.
const tracks = state['features/base/tracks'];
const videoTrack = _electLastVisibleRemoteVideo(tracks);
id = videoTrack && videoTrack.participantId;
if (!id) {
2017-10-09 15:03:02 +00:00
// 4. It's possible there is no participant with visible video.
// This can happen for a number of reasons:
// - there is only one participant (i.e. the local user),
// - other participants joined with video muted.
// As a last resort, pick the last participant who joined the
// conference (regardless of whether they are local or
// remote).
//
// HOWEVER: We don't want to show poltergeist or other bot type participants on stage
// automatically, because it's misleading (users may think they are already
// joined and maybe speaking).
for (let i = participants.length; i > 0 && !participant; i--) {
const p = participants[i - 1];
!p.botType && (participant = p);
}
id = participant && participant.id;
}
}
}
return id;
}