123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- // @flow
- import type { Dispatch } from 'redux';
-
- import { getSourceNameSignalingFeatureFlag } from '../base/config';
- import {
- getLocalParticipant,
- getParticipantById,
- getRemoteParticipantCount,
- pinParticipant
- } from '../base/participants';
- import { shouldHideSelfView } from '../base/settings/functions.any';
- import { getMaxColumnCount } from '../video-layout';
-
- import {
- ADD_STAGE_PARTICIPANT,
- REMOVE_STAGE_PARTICIPANT,
- SET_STAGE_PARTICIPANTS,
- SET_FILMSTRIP_WIDTH,
- SET_HORIZONTAL_VIEW_DIMENSIONS,
- SET_STAGE_FILMSTRIP_DIMENSIONS,
- SET_TILE_VIEW_DIMENSIONS,
- SET_USER_FILMSTRIP_WIDTH,
- SET_USER_IS_RESIZING,
- SET_VERTICAL_VIEW_DIMENSIONS,
- SET_VOLUME,
- SET_MAX_STAGE_PARTICIPANTS,
- TOGGLE_PIN_STAGE_PARTICIPANT,
- CLEAR_STAGE_PARTICIPANTS
- } from './actionTypes';
- import {
- HORIZONTAL_FILMSTRIP_MARGIN,
- MAX_ACTIVE_PARTICIPANTS,
- SCROLL_SIZE,
- STAGE_VIEW_THUMBNAIL_VERTICAL_BORDER,
- TILE_HORIZONTAL_MARGIN,
- TILE_VERTICAL_CONTAINER_HORIZONTAL_MARGIN,
- TILE_VERTICAL_MARGIN,
- TILE_VIEW_DEFAULT_NUMBER_OF_VISIBLE_TILES,
- TILE_VIEW_GRID_HORIZONTAL_MARGIN,
- TILE_VIEW_GRID_VERTICAL_MARGIN,
- VERTICAL_FILMSTRIP_VERTICAL_MARGIN
- } from './constants';
- import {
- calculateNonResponsiveTileViewDimensions,
- calculateResponsiveTileViewDimensions,
- calculateThumbnailSizeForHorizontalView,
- calculateThumbnailSizeForVerticalView,
- getNumberOfPartipantsForTileView,
- getVerticalViewMaxWidth,
- isFilmstripResizable,
- showGridInVerticalView
- } from './functions';
-
- export * from './actions.any';
-
- /**
- * Sets the dimensions of the tile view grid.
- *
- * @returns {Function}
- */
- export function setTileViewDimensions() {
- return (dispatch: Dispatch<any>, getState: Function) => {
- const state = getState();
- const { clientHeight, clientWidth } = state['features/base/responsive-ui'];
- const {
- disableResponsiveTiles,
- disableTileEnlargement,
- tileView = {}
- } = state['features/base/config'];
- const { numberOfVisibleTiles = TILE_VIEW_DEFAULT_NUMBER_OF_VISIBLE_TILES } = tileView;
- const numberOfParticipants = getNumberOfPartipantsForTileView(state);
- const maxColumns = getMaxColumnCount(state);
-
- const {
- height,
- width,
- columns,
- rows
- } = disableResponsiveTiles
- ? calculateNonResponsiveTileViewDimensions(state)
- : calculateResponsiveTileViewDimensions({
- clientWidth,
- clientHeight,
- disableTileEnlargement,
- maxColumns,
- numberOfParticipants,
- desiredNumberOfVisibleTiles: numberOfVisibleTiles
- });
- const thumbnailsTotalHeight = rows * (TILE_VERTICAL_MARGIN + height);
- const availableHeight = clientHeight - TILE_VIEW_GRID_VERTICAL_MARGIN;
- const hasScroll = availableHeight < thumbnailsTotalHeight;
- const filmstripWidth
- = Math.min(clientWidth - TILE_VIEW_GRID_HORIZONTAL_MARGIN, columns * (TILE_HORIZONTAL_MARGIN + width))
- + (hasScroll ? SCROLL_SIZE : 0);
- const filmstripHeight = Math.min(availableHeight, thumbnailsTotalHeight);
-
- dispatch({
- type: SET_TILE_VIEW_DIMENSIONS,
- dimensions: {
- gridDimensions: {
- columns,
- rows
- },
- thumbnailSize: {
- height,
- width
- },
- filmstripHeight,
- filmstripWidth,
- hasScroll
- }
- });
- };
- }
-
- /**
- * Sets the dimensions of the thumbnails in vertical view.
- *
- * @returns {Function}
- */
- export function setVerticalViewDimensions() {
- return (dispatch: Dispatch<any>, getState: Function) => {
- const state = getState();
- const { clientHeight = 0, clientWidth = 0 } = state['features/base/responsive-ui'];
- const { width: filmstripWidth } = state['features/filmstrip'];
- const disableSelfView = shouldHideSelfView(state);
- const resizableFilmstrip = isFilmstripResizable(state);
- const _verticalViewGrid = showGridInVerticalView(state);
- const numberOfRemoteParticipants = getRemoteParticipantCount(state);
- const { localScreenShare } = state['features/base/participants'];
-
- let gridView = {};
- let thumbnails = {};
- let filmstripDimensions = {};
- let hasScroll = false;
- let remoteVideosContainerWidth;
- let remoteVideosContainerHeight;
-
- // grid view in the vertical filmstrip
- if (_verticalViewGrid) {
- const { tileView = {} } = state['features/base/config'];
- const { numberOfVisibleTiles = TILE_VIEW_DEFAULT_NUMBER_OF_VISIBLE_TILES } = tileView;
- const numberOfParticipants = getNumberOfPartipantsForTileView(state);
- const maxColumns = getMaxColumnCount(state, {
- width: filmstripWidth.current,
- disableResponsiveTiles: false,
- disableTileEnlargement: false
- });
- const {
- height,
- width,
- columns,
- rows
- } = calculateResponsiveTileViewDimensions({
- clientWidth: filmstripWidth.current,
- clientHeight,
- disableTileEnlargement: false,
- maxColumns,
- noHorizontalContainerMargin: true,
- numberOfParticipants,
- desiredNumberOfVisibleTiles: numberOfVisibleTiles
- });
- const thumbnailsTotalHeight = rows * (TILE_VERTICAL_MARGIN + height);
-
- hasScroll = clientHeight < thumbnailsTotalHeight;
- const widthOfFilmstrip = (columns * (TILE_HORIZONTAL_MARGIN + width)) + (hasScroll ? SCROLL_SIZE : 0);
- const filmstripHeight = Math.min(clientHeight - TILE_VIEW_GRID_VERTICAL_MARGIN, thumbnailsTotalHeight);
-
- gridView = {
- gridDimensions: {
- columns,
- rows
- },
- thumbnailSize: {
- height,
- width
- },
- hasScroll
- };
-
- filmstripDimensions = {
- height: filmstripHeight,
- width: widthOfFilmstrip
- };
- } else {
- thumbnails = calculateThumbnailSizeForVerticalView(clientWidth, filmstripWidth.current, resizableFilmstrip);
-
- remoteVideosContainerWidth
- = thumbnails?.local?.width + TILE_VERTICAL_CONTAINER_HORIZONTAL_MARGIN + SCROLL_SIZE;
- remoteVideosContainerHeight
- = clientHeight - (disableSelfView ? 0 : thumbnails?.local?.height) - VERTICAL_FILMSTRIP_VERTICAL_MARGIN;
-
- if (getSourceNameSignalingFeatureFlag(state)) {
- // Account for the height of the local screen share thumbnail when calculating the height of the remote
- // videos container.
- const localCameraThumbnailHeight = thumbnails?.local?.height;
- const localScreenShareThumbnailHeight
- = localScreenShare && !disableSelfView ? thumbnails?.local?.height : 0;
-
- remoteVideosContainerHeight = clientHeight
- - localCameraThumbnailHeight
- - localScreenShareThumbnailHeight
- - VERTICAL_FILMSTRIP_VERTICAL_MARGIN;
- }
-
- hasScroll
- = remoteVideosContainerHeight
- < (thumbnails?.remote.height + TILE_VERTICAL_MARGIN) * numberOfRemoteParticipants;
- }
-
- dispatch({
- type: SET_VERTICAL_VIEW_DIMENSIONS,
- dimensions: {
- ...thumbnails,
- remoteVideosContainer: _verticalViewGrid ? filmstripDimensions : {
- width: remoteVideosContainerWidth,
- height: remoteVideosContainerHeight
- },
- gridView,
- hasScroll
- }
- });
- };
- }
-
- /**
- * Sets the dimensions of the thumbnails in horizontal view.
- *
- * @returns {Function}
- */
- export function setHorizontalViewDimensions() {
- return (dispatch: Dispatch<any>, getState: Function) => {
- const state = getState();
- const { clientHeight = 0, clientWidth = 0 } = state['features/base/responsive-ui'];
- const disableSelfView = shouldHideSelfView(state);
- const thumbnails = calculateThumbnailSizeForHorizontalView(clientHeight);
- const remoteVideosContainerWidth
- = clientWidth - (disableSelfView ? 0 : thumbnails?.local?.width) - HORIZONTAL_FILMSTRIP_MARGIN;
- const remoteVideosContainerHeight
- = thumbnails?.local?.height + TILE_VERTICAL_MARGIN + STAGE_VIEW_THUMBNAIL_VERTICAL_BORDER + SCROLL_SIZE;
- const numberOfRemoteParticipants = getRemoteParticipantCount(state);
- const hasScroll
- = remoteVideosContainerHeight
- < (thumbnails?.remote.width + TILE_HORIZONTAL_MARGIN) * numberOfRemoteParticipants;
-
- dispatch({
- type: SET_HORIZONTAL_VIEW_DIMENSIONS,
- dimensions: {
- ...thumbnails,
- remoteVideosContainer: {
- width: remoteVideosContainerWidth,
- height: remoteVideosContainerHeight
- },
- hasScroll
- }
- });
- };
- }
-
- /**
- * Sets the dimensions of the stage filmstrip tile view grid.
- *
- * @returns {Function}
- */
- export function setStageFilmstripViewDimensions() {
- return (dispatch: Dispatch<any>, getState: Function) => {
- const state = getState();
- const { clientHeight, clientWidth } = state['features/base/responsive-ui'];
- const {
- tileView = {}
- } = state['features/base/config'];
- const { visible } = state['features/filmstrip'];
- const verticalWidth = visible ? getVerticalViewMaxWidth(state) : 0;
- const { numberOfVisibleTiles = MAX_ACTIVE_PARTICIPANTS } = tileView;
- const numberOfParticipants = state['features/filmstrip'].activeParticipants.length;
- const availableWidth = clientWidth - verticalWidth;
- const maxColumns = getMaxColumnCount(state, {
- width: availableWidth,
- disableResponsiveTiles: false,
- disableTileEnlargement: false
- });
-
- const {
- height,
- width,
- columns,
- rows
- } = calculateResponsiveTileViewDimensions({
- clientWidth: availableWidth,
- clientHeight,
- disableTileEnlargement: false,
- maxColumns,
- noHorizontalContainerMargin: verticalWidth > 0,
- numberOfParticipants,
- numberOfVisibleTiles
- });
- const thumbnailsTotalHeight = rows * (TILE_VERTICAL_MARGIN + height);
- const hasScroll = clientHeight < thumbnailsTotalHeight;
- const filmstripWidth
- = Math.min(clientWidth - TILE_VIEW_GRID_HORIZONTAL_MARGIN, columns * (TILE_HORIZONTAL_MARGIN + width))
- + (hasScroll ? SCROLL_SIZE : 0);
- const filmstripHeight = Math.min(clientHeight - TILE_VIEW_GRID_VERTICAL_MARGIN, thumbnailsTotalHeight);
-
- dispatch({
- type: SET_STAGE_FILMSTRIP_DIMENSIONS,
- dimensions: {
- gridDimensions: {
- columns,
- rows
- },
- thumbnailSize: {
- height,
- width
- },
- filmstripHeight,
- filmstripWidth,
- hasScroll
- }
- });
- };
- }
-
- /**
- * Emulates a click on the n-th video.
- *
- * @param {number} n - Number that identifies the video.
- * @returns {Function}
- */
- export function clickOnVideo(n: number) {
- return (dispatch: Function, getState: Function) => {
- const state = getState();
- const { id: localId } = getLocalParticipant(state);
-
- // Use the list that correctly represents the current order of the participants as visible in the UI.
- const { remoteParticipants } = state['features/filmstrip'];
- const participants = [ localId, ...remoteParticipants ];
- const { id, pinned } = getParticipantById(state, participants[n]);
-
- dispatch(pinParticipant(pinned ? null : id));
- };
- }
-
- /**
- * Sets the volume for a thumbnail's audio.
- *
- * @param {string} participantId - The participant ID asociated with the audio.
- * @param {string} volume - The volume level.
- * @returns {{
- * type: SET_VOLUME,
- * participantId: string,
- * volume: number
- * }}
- */
- export function setVolume(participantId: string, volume: number) {
- return {
- type: SET_VOLUME,
- participantId,
- volume
- };
- }
-
- /**
- * Sets the filmstrip's width.
- *
- * @param {number} width - The new width of the filmstrip.
- * @returns {{
- * type: SET_FILMSTRIP_WIDTH,
- * width: number
- * }}
- */
- export function setFilmstripWidth(width: number) {
- return {
- type: SET_FILMSTRIP_WIDTH,
- width
- };
- }
-
- /**
- * Sets the filmstrip's width and the user preferred width.
- *
- * @param {number} width - The new width of the filmstrip.
- * @returns {{
- * type: SET_USER_FILMSTRIP_WIDTH,
- * width: number
- * }}
- */
- export function setUserFilmstripWidth(width: number) {
- return {
- type: SET_USER_FILMSTRIP_WIDTH,
- width
- };
- }
-
- /**
- * Sets whether the user is resizing or not.
- *
- * @param {boolean} resizing - Whether the user is resizing or not.
- * @returns {Object}
- */
- export function setUserIsResizing(resizing: boolean) {
- return {
- type: SET_USER_IS_RESIZING,
- resizing
- };
- }
-
- /**
- * Add participant to the active participants list.
- *
- * @param {string} participantId - The Id of the participant to be added.
- * @param {boolean?} pinned - Whether the participant is pinned or not.
- * @returns {Object}
- */
- export function addStageParticipant(participantId, pinned = false) {
- return {
- type: ADD_STAGE_PARTICIPANT,
- participantId,
- pinned
- };
- }
-
- /**
- * Remove participant from the active participants list.
- *
- * @param {string} participantId - The Id of the participant to be removed.
- * @returns {Object}
- */
- export function removeStageParticipant(participantId) {
- return {
- type: REMOVE_STAGE_PARTICIPANT,
- participantId
- };
- }
-
- /**
- * Sets the active participants list.
- *
- * @param {Array<Object>} queue - The new list.
- * @returns {Object}
- */
- export function setStageParticipants(queue) {
- return {
- type: SET_STAGE_PARTICIPANTS,
- queue
- };
- }
-
- /**
- * Sets the max number of participants to be displayed on stage.
- *
- * @param {number} maxParticipants - Max number of participants.
- * @returns {Object}
- */
- export function setMaxStageParticipants(maxParticipants) {
- return {
- type: SET_MAX_STAGE_PARTICIPANTS,
- maxParticipants
- };
- }
-
- /**
- * Toggles the pin state of the given participant.
- *
- * @param {string} participantId - The id of the participant to be toggled.
- * @returns {Object}
- */
- export function togglePinStageParticipant(participantId) {
- return {
- type: TOGGLE_PIN_STAGE_PARTICIPANT,
- participantId
- };
- }
-
- /**
- * Clears the stage participants list.
- *
- * @returns {Object}
- */
- export function clearStageParticipants() {
- return {
- type: CLEAR_STAGE_PARTICIPANTS
- };
- }
|