This commit is contained in:
27
react/features/screen-share/actionTypes.ts
Normal file
27
react/features/screen-share/actionTypes.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Type of action which sets the current state of screen audio sharing.
|
||||
*
|
||||
* {
|
||||
* type: SET_SCREEN_AUDIO_SHARE_STATE,
|
||||
* isSharingAudio: boolean
|
||||
* }
|
||||
*/
|
||||
export const SET_SCREEN_AUDIO_SHARE_STATE = 'SET_SCREEN_AUDIO_SHARE_STATE';
|
||||
|
||||
/**
|
||||
* Type of action which sets the capture frame rate for screenshare.
|
||||
* {
|
||||
* type: SET_SCREENSHARE_CAPTURE_FRAME_RATE,
|
||||
* captureFrameRate: number
|
||||
* }
|
||||
*/
|
||||
export const SET_SCREENSHARE_CAPTURE_FRAME_RATE = 'SET_SCREENSHARE_CAPTURE_FRAME_RATE';
|
||||
|
||||
/**
|
||||
* Type of action which sets the current audio track captured from the screenshare.
|
||||
* {
|
||||
* type: SET_SCREENSHARE_TRACKS,
|
||||
* desktopAudioTrack: JitsiTrack
|
||||
* }
|
||||
*/
|
||||
export const SET_SCREENSHARE_TRACKS = 'SET_SCREENSHARE_TRACKS';
|
||||
19
react/features/screen-share/actions.any.ts
Normal file
19
react/features/screen-share/actions.any.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import {
|
||||
SET_SCREENSHARE_CAPTURE_FRAME_RATE
|
||||
} from './actionTypes';
|
||||
|
||||
/**
|
||||
* Updates the capture frame rate for screenshare in redux.
|
||||
*
|
||||
* @param {number} captureFrameRate - The frame rate to be used for screenshare.
|
||||
* @returns {{
|
||||
* type: SET_SCREENSHARE_CAPTURE_FRAME_RATE,
|
||||
* captureFrameRate: number
|
||||
* }}
|
||||
*/
|
||||
export function setScreenshareFramerate(captureFrameRate: number) {
|
||||
return {
|
||||
type: SET_SCREENSHARE_CAPTURE_FRAME_RATE,
|
||||
captureFrameRate
|
||||
};
|
||||
}
|
||||
104
react/features/screen-share/actions.web.ts
Normal file
104
react/features/screen-share/actions.web.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { IStore } from '../app/types';
|
||||
import { openDialog } from '../base/dialog/actions';
|
||||
import { browser } from '../base/lib-jitsi-meet';
|
||||
import { shouldHideShareAudioHelper } from '../base/settings/functions.web';
|
||||
import { toggleScreensharing } from '../base/tracks/actions.web';
|
||||
|
||||
import {
|
||||
SET_SCREENSHARE_TRACKS,
|
||||
SET_SCREEN_AUDIO_SHARE_STATE
|
||||
} from './actionTypes';
|
||||
import ShareAudioDialog from './components/web/ShareAudioDialog';
|
||||
import ShareMediaWarningDialog from './components/web/ShareScreenWarningDialog';
|
||||
import { isAudioOnlySharing, isScreenVideoShared } from './functions';
|
||||
|
||||
export * from './actions.any';
|
||||
|
||||
/**
|
||||
* Updates the current known status of the shared video.
|
||||
*
|
||||
* @param {boolean} isSharingAudio - Is audio currently being shared or not.
|
||||
* @returns {{
|
||||
* type: SET_SCREEN_AUDIO_SHARE_STATE,
|
||||
* isSharingAudio: boolean
|
||||
* }}
|
||||
*/
|
||||
export function setScreenAudioShareState(isSharingAudio: boolean) {
|
||||
return {
|
||||
type: SET_SCREEN_AUDIO_SHARE_STATE,
|
||||
isSharingAudio
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the audio track associated with the screenshare.
|
||||
*
|
||||
* @param {JitsiLocalTrack} desktopAudioTrack - The audio track captured from the screenshare.
|
||||
* @returns {{
|
||||
* type: SET_SCREENSHARE_TRACKS,
|
||||
* desktopAudioTrack: JitsiTrack
|
||||
* }}
|
||||
*/
|
||||
export function setScreenshareAudioTrack(desktopAudioTrack: any) {
|
||||
return {
|
||||
type: SET_SCREENSHARE_TRACKS,
|
||||
desktopAudioTrack
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the audio only screen sharing flow. Function will switch between off and on states depending on the context.
|
||||
*
|
||||
* @param {Object} state - The state of the application.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function startAudioScreenShareFlow() {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const state = getState();
|
||||
const audioOnlySharing = isAudioOnlySharing(state);
|
||||
|
||||
// If we're already in a normal screen sharing session, warn the user.
|
||||
if (isScreenVideoShared(state)) {
|
||||
dispatch(openDialog(ShareMediaWarningDialog, { _isAudioScreenShareWarning: true }));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If users opted out of the helper dialog toggle directly.
|
||||
// If we're in an electron environment the helper dialog is not needed as there's only one option
|
||||
// available for audio screen sharing, namely full window audio.
|
||||
// If we're already sharing audio, toggle off.
|
||||
if (shouldHideShareAudioHelper(state) || browser.isElectron() || audioOnlySharing) {
|
||||
// We don't want to explicitly set the screens share state, by passing undefined we let the
|
||||
// underlying logic decide if it's on or off.
|
||||
dispatch(toggleScreensharing(undefined, true));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(openDialog(ShareAudioDialog));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Start normal screen sharing flow.Function will switch between off and on states depending on the context, and if
|
||||
* not explicitly told otherwise.
|
||||
*
|
||||
* @param {boolean} enabled - Explicitly set the screen sharing state.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function startScreenShareFlow(enabled: boolean) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const state = getState();
|
||||
const audioOnlySharing = isAudioOnlySharing(state);
|
||||
|
||||
// If we're in an audio screen sharing session, warn the user.
|
||||
if (audioOnlySharing) {
|
||||
dispatch(openDialog(ShareMediaWarningDialog, { _isAudioScreenShareWarning: false }));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(toggleScreensharing(enabled));
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { IReduxState } from '../../../app/types';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import { IconVolumeOff, IconVolumeUp } from '../../../base/icons/svg';
|
||||
import JitsiMeetJS from '../../../base/lib-jitsi-meet';
|
||||
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
|
||||
import { setOverflowMenuVisible } from '../../../toolbox/actions.web';
|
||||
import { startAudioScreenShareFlow } from '../../actions.web';
|
||||
import { isAudioOnlySharing, isScreenAudioSupported } from '../../functions';
|
||||
|
||||
interface IProps extends AbstractButtonProps {
|
||||
|
||||
/**
|
||||
* Whether or not the local participant is audio only screen sharing.
|
||||
*/
|
||||
_isAudioOnlySharing: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component that renders a toolbar button for toggling audio only screen share.
|
||||
*/
|
||||
class ShareAudioButton extends AbstractButton<IProps> {
|
||||
override accessibilityLabel = 'toolbar.accessibilityLabel.shareaudio';
|
||||
override icon = IconVolumeUp;
|
||||
override label = 'toolbar.shareaudio';
|
||||
override tooltip = 'toolbar.shareaudio';
|
||||
override toggledIcon = IconVolumeOff;
|
||||
override toggledLabel = 'toolbar.stopAudioSharing';
|
||||
|
||||
/**
|
||||
* Handles clicking / pressing the button, and opens a new dialog.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
override _handleClick() {
|
||||
const { dispatch } = this.props;
|
||||
|
||||
dispatch(startAudioScreenShareFlow());
|
||||
dispatch(setOverflowMenuVisible(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this button is in toggled state or not.
|
||||
*
|
||||
* @override
|
||||
* @protected
|
||||
* @returns {boolean}
|
||||
*/
|
||||
override _isToggled() {
|
||||
return this.props._isAudioOnlySharing;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @private
|
||||
* @returns {IProps}
|
||||
*/
|
||||
function _mapStateToProps(state: IReduxState) {
|
||||
|
||||
return {
|
||||
_isAudioOnlySharing: Boolean(isAudioOnlySharing(state)),
|
||||
visible: JitsiMeetJS.isDesktopSharingEnabled() && isScreenAudioSupported()
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(ShareAudioButton));
|
||||
117
react/features/screen-share/components/web/ShareAudioDialog.tsx
Normal file
117
react/features/screen-share/components/web/ShareAudioDialog.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
import React, { Component } from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { IReduxState, IStore } from '../../../app/types';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import { updateSettings } from '../../../base/settings/actions';
|
||||
import { shouldHideShareAudioHelper } from '../../../base/settings/functions.web';
|
||||
import { toggleScreensharing } from '../../../base/tracks/actions.web';
|
||||
import Checkbox from '../../../base/ui/components/web/Checkbox';
|
||||
import Dialog from '../../../base/ui/components/web/Dialog';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link ShareAudioDialog}.
|
||||
*/
|
||||
export interface IProps extends WithTranslation {
|
||||
|
||||
/**
|
||||
* Boolean stored in local storage that determines whether or not the dialog will be displayed again.
|
||||
*/
|
||||
_shouldHideShareAudioHelper: boolean;
|
||||
|
||||
/**
|
||||
* The redux {@code dispatch} function.
|
||||
*/
|
||||
dispatch: IStore['dispatch'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Component that displays the audio screen share helper dialog.
|
||||
*/
|
||||
class ShareAudioDialog extends Component<IProps> {
|
||||
|
||||
/**
|
||||
* Instantiates a new component.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this._onContinue = this._onContinue.bind(this);
|
||||
this._onSelectHideShareAudioHelper = this._onSelectHideShareAudioHelper.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue the normal screen sharing flow when the user clicks continue.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_onContinue() {
|
||||
// Pass undefined as the first parameter so the underlying logic decides weather or not to stop screen sharing.
|
||||
this.props.dispatch(toggleScreensharing(undefined, true));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback invoked when the hide audio helper checkbox has been selected. This setting will be persisted in
|
||||
* the local storage, thus the dialog won't be displayed again.
|
||||
*
|
||||
* @param {Object} e - The key event to handle.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onSelectHideShareAudioHelper({ target: { checked } }: React.ChangeEvent<HTMLInputElement>) {
|
||||
this.props.dispatch(updateSettings({ hideShareAudioHelper: checked }));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@Component#render}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
override render() {
|
||||
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
ok = {{ translationKey: 'dialog.shareAudio' }}
|
||||
onSubmit = { this._onContinue }
|
||||
size = 'large'
|
||||
titleKey = { t('dialog.shareAudioTitle') }>
|
||||
<div className = 'share-audio-dialog'>
|
||||
<img
|
||||
alt = { t('dialog.shareAudioAltText') }
|
||||
className = 'share-audio-animation'
|
||||
src = 'images/share-audio.gif'
|
||||
tabIndex = { 0 } />
|
||||
<Checkbox
|
||||
checked = { this.props._shouldHideShareAudioHelper }
|
||||
label = { t('dialog.hideShareAudioHelper') }
|
||||
name = 'hide-share-audio-helper'
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onChange = { this._onSelectHideShareAudioHelper } />
|
||||
</div>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {IReduxState} state - The Redux state.
|
||||
* @private
|
||||
* @returns {IProps}
|
||||
*/
|
||||
function _mapStateToProps(state: IReduxState) {
|
||||
|
||||
return {
|
||||
_shouldHideShareAudioHelper: Boolean(shouldHideShareAudioHelper(state))
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export default translate(connect(_mapStateToProps)(ShareAudioDialog));
|
||||
@@ -0,0 +1,95 @@
|
||||
import React, { Component } from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { IStore } from '../../../app/types';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import { toggleScreensharing } from '../../../base/tracks/actions';
|
||||
import Dialog from '../../../base/ui/components/web/Dialog';
|
||||
|
||||
export interface IProps extends WithTranslation {
|
||||
|
||||
/**
|
||||
* Whether or not the dialog was opened for the audio screen sharing flow or the normal one.
|
||||
*/
|
||||
_isAudioScreenShareWarning: Boolean;
|
||||
|
||||
/**
|
||||
* The redux {@code dispatch} function.
|
||||
*/
|
||||
dispatch: IStore['dispatch'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Component that displays the share audio helper dialog.
|
||||
*/
|
||||
class ShareScreenWarningDialog extends Component<IProps> {
|
||||
|
||||
/**
|
||||
* Instantiates a new component.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this._onStopSharing = this._onStopSharing.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop current screen sharing session.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_onStopSharing() {
|
||||
// Depending on the context from which this dialog is opened we'll either be toggling off an audio only
|
||||
// share session or a normal screen sharing one, this is indicated by the _isAudioScreenShareWarning prop.
|
||||
this.props.dispatch(toggleScreensharing(undefined,
|
||||
!this.props._isAudioScreenShareWarning));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@Component#render}.
|
||||
*§.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
override render() {
|
||||
const { t } = this.props;
|
||||
|
||||
let description1, description2, header1, header2, stopSharing, title;
|
||||
|
||||
if (this.props._isAudioScreenShareWarning) {
|
||||
header1 = 'dialog.shareAudioWarningH1';
|
||||
header2 = 'dialog.shareMediaWarningGenericH2';
|
||||
description1 = 'dialog.shareAudioWarningD1';
|
||||
description2 = 'dialog.shareAudioWarningD2';
|
||||
title = 'dialog.shareAudioWarningTitle';
|
||||
stopSharing = 'toolbar.stopScreenSharing';
|
||||
} else {
|
||||
header1 = 'dialog.shareScreenWarningTitle';
|
||||
header2 = 'dialog.shareMediaWarningGenericH2';
|
||||
description1 = 'dialog.shareScreenWarningD1';
|
||||
description2 = 'dialog.shareScreenWarningD2';
|
||||
title = 'dialog.shareScreenWarningTitle';
|
||||
stopSharing = 'toolbar.stopAudioSharing';
|
||||
}
|
||||
|
||||
return (<Dialog
|
||||
ok = {{ translationKey: stopSharing }}
|
||||
onSubmit = { this._onStopSharing }
|
||||
titleKey = { t(title) }>
|
||||
<div className = 'share-screen-warn-dialog'>
|
||||
<p className = 'header'> { t(header1) } </p>
|
||||
<p className = 'description' > { t(description1) } </p>
|
||||
<div className = 'separator-line' />
|
||||
<p className = 'header' > { t(header2) } </p>
|
||||
<p className = 'description' > { t(description2) } </p>
|
||||
</div>
|
||||
</Dialog>);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(connect()(ShareScreenWarningDialog));
|
||||
58
react/features/screen-share/functions.ts
Normal file
58
react/features/screen-share/functions.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { IReduxState } from '../app/types';
|
||||
import { isWindows } from '../base/environment/environment';
|
||||
import { isMobileBrowser } from '../base/environment/utils';
|
||||
import { browser } from '../base/lib-jitsi-meet';
|
||||
import { getLocalDesktopTrack } from '../base/tracks/functions';
|
||||
|
||||
/**
|
||||
* Is the current screen sharing session audio only.
|
||||
*
|
||||
* @param {IReduxState} state - The state of the application.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isAudioOnlySharing(state: IReduxState) {
|
||||
return isScreenAudioShared(state) && !isScreenVideoShared(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* State of audio sharing.
|
||||
*
|
||||
* @param {IReduxState} state - The state of the application.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isScreenAudioShared(state: IReduxState) {
|
||||
return state['features/screen-share'].isSharingAudio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the visibility of the audio only screen share button. Currently only chrome browser and electron on
|
||||
* windows supports this functionality.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isScreenAudioSupported() {
|
||||
return (!isMobileBrowser() && browser.isChromiumBased()) || (browser.isElectron() && isWindows());
|
||||
}
|
||||
|
||||
/**
|
||||
* Is any screen media currently being shared, audio or video.
|
||||
*
|
||||
* @param {IReduxState} state - The state of the application.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isScreenMediaShared(state: IReduxState) {
|
||||
return isScreenAudioShared(state) || isScreenVideoShared(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is screen sharing currently active.
|
||||
*
|
||||
* @param {IReduxState} state - The state of the application.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isScreenVideoShared(state: IReduxState) {
|
||||
const tracks = state['features/base/tracks'];
|
||||
const localScreenshare = getLocalDesktopTrack(tracks);
|
||||
|
||||
return localScreenshare?.jitsiTrack && !localScreenshare.jitsiTrack.isMuted();
|
||||
}
|
||||
3
react/features/screen-share/logger.ts
Normal file
3
react/features/screen-share/logger.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { getLogger } from '../base/logging/functions';
|
||||
|
||||
export default getLogger('features/screen-share');
|
||||
72
react/features/screen-share/middleware.ts
Normal file
72
react/features/screen-share/middleware.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { IStore } from '../app/types';
|
||||
import { CONFERENCE_JOINED } from '../base/conference/actionTypes';
|
||||
import { MEDIA_TYPE } from '../base/media/constants';
|
||||
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
|
||||
|
||||
import { SET_SCREENSHARE_CAPTURE_FRAME_RATE, SET_SCREEN_AUDIO_SHARE_STATE } from './actionTypes';
|
||||
import logger from './logger';
|
||||
|
||||
/**
|
||||
* Implements the middleware of the feature screen-share.
|
||||
*
|
||||
* @param {Store} store - The redux store.
|
||||
* @returns {Function}
|
||||
*/
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
const result = next(action);
|
||||
const { getState } = store;
|
||||
const state = getState();
|
||||
|
||||
switch (action.type) {
|
||||
case CONFERENCE_JOINED: {
|
||||
_setScreenshareCaptureFps(store);
|
||||
break;
|
||||
}
|
||||
case SET_SCREENSHARE_CAPTURE_FRAME_RATE: {
|
||||
const { captureFrameRate } = action;
|
||||
|
||||
_setScreenshareCaptureFps(store, captureFrameRate);
|
||||
break;
|
||||
}
|
||||
|
||||
case SET_SCREEN_AUDIO_SHARE_STATE: {
|
||||
const { isSharingAudio } = action;
|
||||
const { participantId } = state['features/large-video'];
|
||||
|
||||
if (isSharingAudio) {
|
||||
logger.debug(`User with id: ${participantId} playing audio sharing.`);
|
||||
APP.API.notifyAudioOrVideoSharingToggled(MEDIA_TYPE.AUDIO, 'playing', participantId);
|
||||
} else {
|
||||
logger.debug(`User with id: ${participantId} stop audio sharing.`);
|
||||
APP.API.notifyAudioOrVideoSharingToggled(MEDIA_TYPE.AUDIO, 'stop', participantId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets the capture frame rate for screenshare.
|
||||
*
|
||||
* @param {Store} store - The redux store.
|
||||
* @param {number} frameRate - Frame rate to be configured.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _setScreenshareCaptureFps(store: IStore, frameRate?: number) {
|
||||
const state = store.getState();
|
||||
const { conference } = state['features/base/conference'];
|
||||
const { captureFrameRate } = state['features/screen-share'];
|
||||
const screenShareFps = frameRate ?? captureFrameRate;
|
||||
|
||||
if (!conference) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (screenShareFps) {
|
||||
logger.debug(`Setting screenshare capture frame rate as ${screenShareFps}`);
|
||||
conference.setDesktopSharingFrameRate(screenShareFps);
|
||||
}
|
||||
|
||||
}
|
||||
44
react/features/screen-share/reducer.ts
Normal file
44
react/features/screen-share/reducer.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
import ReducerRegistry from '../base/redux/ReducerRegistry';
|
||||
|
||||
import {
|
||||
SET_SCREENSHARE_CAPTURE_FRAME_RATE,
|
||||
SET_SCREENSHARE_TRACKS,
|
||||
SET_SCREEN_AUDIO_SHARE_STATE
|
||||
} from './actionTypes';
|
||||
|
||||
export interface IScreenShareState {
|
||||
captureFrameRate?: number;
|
||||
desktopAudioTrack?: any;
|
||||
isSharingAudio?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the Redux actions of the feature features/screen-share.
|
||||
*/
|
||||
ReducerRegistry.register<IScreenShareState>('features/screen-share', (state = {}, action): IScreenShareState => {
|
||||
const { captureFrameRate, isSharingAudio, desktopAudioTrack } = action;
|
||||
|
||||
switch (action.type) {
|
||||
case SET_SCREEN_AUDIO_SHARE_STATE:
|
||||
return {
|
||||
...state,
|
||||
isSharingAudio
|
||||
};
|
||||
|
||||
case SET_SCREENSHARE_CAPTURE_FRAME_RATE:
|
||||
return {
|
||||
...state,
|
||||
captureFrameRate
|
||||
};
|
||||
|
||||
case SET_SCREENSHARE_TRACKS:
|
||||
return {
|
||||
...state,
|
||||
desktopAudioTrack
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user