feat(share-room): disable Invite Others button when Share is visible (#12765)
* feat(share-room): disable/enable Invite Others button
This commit is contained in:
parent
c50111a57d
commit
a59ab3b0d9
|
@ -6,6 +6,7 @@ import '../mobile/call-integration/reducer';
|
||||||
import '../mobile/external-api/reducer';
|
import '../mobile/external-api/reducer';
|
||||||
import '../mobile/full-screen/reducer';
|
import '../mobile/full-screen/reducer';
|
||||||
import '../mobile/watchos/reducer';
|
import '../mobile/watchos/reducer';
|
||||||
|
import '../share-room/reducer';
|
||||||
|
|
||||||
import './reducer.native';
|
import './reducer.native';
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ import { IRecordingState } from '../recording/reducer';
|
||||||
import { IRemoteControlState } from '../remote-control/reducer';
|
import { IRemoteControlState } from '../remote-control/reducer';
|
||||||
import { IScreenShareState } from '../screen-share/reducer';
|
import { IScreenShareState } from '../screen-share/reducer';
|
||||||
import { IScreenshotCaptureState } from '../screenshot-capture/reducer';
|
import { IScreenshotCaptureState } from '../screenshot-capture/reducer';
|
||||||
|
import { IShareRoomState } from '../share-room/reducer';
|
||||||
import { ISharedVideoState } from '../shared-video/reducer';
|
import { ISharedVideoState } from '../shared-video/reducer';
|
||||||
import { ISpeakerStatsState } from '../speaker-stats/reducer';
|
import { ISpeakerStatsState } from '../speaker-stats/reducer';
|
||||||
import { ISubtitlesState } from '../subtitles/reducer';
|
import { ISubtitlesState } from '../subtitles/reducer';
|
||||||
|
@ -148,6 +149,7 @@ export interface IReduxState {
|
||||||
'features/screen-share': IScreenShareState;
|
'features/screen-share': IScreenShareState;
|
||||||
'features/screenshot-capture': IScreenshotCaptureState;
|
'features/screenshot-capture': IScreenshotCaptureState;
|
||||||
'features/settings': ISettingsState;
|
'features/settings': ISettingsState;
|
||||||
|
'features/share-room': IShareRoomState;
|
||||||
'features/shared-video': ISharedVideoState;
|
'features/shared-video': ISharedVideoState;
|
||||||
'features/speaker-stats': ISpeakerStatsState;
|
'features/speaker-stats': ISpeakerStatsState;
|
||||||
'features/subtitles': ISubtitlesState;
|
'features/subtitles': ISubtitlesState;
|
||||||
|
|
|
@ -1,47 +1,62 @@
|
||||||
|
/* eslint-disable lines-around-comment */
|
||||||
|
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
import { WithTranslation } from 'react-i18next';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
|
|
||||||
import { INVITE_ENABLED, getFeatureFlag } from '../../../base/flags';
|
import { IReduxState } from '../../../app/types';
|
||||||
import { translate } from '../../../base/i18n';
|
// @ts-ignore
|
||||||
|
import { INVITE_ENABLED, getFeatureFlag } from '../../../base/flags/';
|
||||||
|
import { translate } from '../../../base/i18n/functions';
|
||||||
|
// @ts-ignore
|
||||||
import { Icon, IconAddUser } from '../../../base/icons';
|
import { Icon, IconAddUser } from '../../../base/icons';
|
||||||
import { getParticipantCountWithFake } from '../../../base/participants';
|
import { getParticipantCountWithFake } from '../../../base/participants/functions';
|
||||||
import { connect } from '../../../base/redux';
|
import { connect } from '../../../base/redux/functions';
|
||||||
|
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||||
import Button from '../../../base/ui/components/native/Button';
|
import Button from '../../../base/ui/components/native/Button';
|
||||||
import { BUTTON_TYPES } from '../../../base/ui/constants.native';
|
import { BUTTON_TYPES } from '../../../base/ui/constants.native';
|
||||||
import { isInBreakoutRoom } from '../../../breakout-rooms/functions';
|
import { isInBreakoutRoom } from '../../../breakout-rooms/functions';
|
||||||
import { doInvitePeople } from '../../../invite/actions.native';
|
import { doInvitePeople } from '../../../invite/actions.native';
|
||||||
|
import { toggleShareDialog } from '../../../share-room/actions';
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Props type of the component.
|
* Props type of the component.
|
||||||
*/
|
*/
|
||||||
type Props = {
|
type Props = WithTranslation & {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if currently in a breakout room.
|
* True if currently in a breakout room.
|
||||||
*/
|
*/
|
||||||
_isInBreakoutRoom: boolean,
|
_isInBreakoutRoom: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the invite functions (dial out, invite, share...etc) are disabled.
|
* True if the invite functions (dial out, invite, share...etc) are disabled.
|
||||||
*/
|
*/
|
||||||
_isInviteFunctionsDiabled: boolean,
|
_isInviteFunctionsDisabled: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if it's a lonely meeting (participant count excluding fakes is 1).
|
* True if it's a lonely meeting (participant count excluding fakes is 1).
|
||||||
*/
|
*/
|
||||||
_isLonelyMeeting: boolean,
|
_isLonelyMeeting: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tackles share meeting url visibility.
|
||||||
|
*/
|
||||||
|
_shareDialogVisible: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Redux Dispatch function.
|
* The Redux Dispatch function.
|
||||||
*/
|
*/
|
||||||
dispatch: Function,
|
dispatch: Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to be used to translate i18n labels.
|
* Function to be used to translate i18n labels.
|
||||||
*/
|
*/
|
||||||
t: Function
|
t: Function;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,19 +74,6 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
||||||
this._onPress = this._onPress.bind(this);
|
this._onPress = this._onPress.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the "add people" icon.
|
|
||||||
*
|
|
||||||
* @returns {ReactElement}
|
|
||||||
*/
|
|
||||||
_renderAddPeopleIcon() {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
size = { 20 }
|
|
||||||
src = { IconAddUser } />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements {@code PureComponent#render}.
|
* Implements {@code PureComponent#render}.
|
||||||
*
|
*
|
||||||
|
@ -80,10 +82,13 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
_isInBreakoutRoom,
|
_isInBreakoutRoom,
|
||||||
_isInviteFunctionsDiabled,
|
_isInviteFunctionsDisabled,
|
||||||
_isLonelyMeeting,
|
_isLonelyMeeting,
|
||||||
|
_shareDialogVisible,
|
||||||
t
|
t
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const { icon01, icon03 } = BaseTheme.palette;
|
||||||
|
const color = _shareDialogVisible ? icon03 : icon01;
|
||||||
|
|
||||||
if (!_isLonelyMeeting) {
|
if (!_isLonelyMeeting) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -94,10 +99,17 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
||||||
<Text style = { styles.lonelyMessage }>
|
<Text style = { styles.lonelyMessage }>
|
||||||
{ t('lonelyMeetingExperience.youAreAlone') }
|
{ t('lonelyMeetingExperience.youAreAlone') }
|
||||||
</Text>
|
</Text>
|
||||||
{ !_isInviteFunctionsDiabled && !_isInBreakoutRoom && (
|
{ !_isInviteFunctionsDisabled && !_isInBreakoutRoom && (
|
||||||
<Button
|
<Button
|
||||||
accessibilityLabel = 'lonelyMeetingExperience.button'
|
accessibilityLabel = 'lonelyMeetingExperience.button'
|
||||||
icon = { this._renderAddPeopleIcon }
|
disabled = { _shareDialogVisible }
|
||||||
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
|
icon = { () => (
|
||||||
|
<Icon
|
||||||
|
color = { color }
|
||||||
|
size = { 20 }
|
||||||
|
src = { IconAddUser } />
|
||||||
|
) }
|
||||||
labelKey = 'lonelyMeetingExperience.button'
|
labelKey = 'lonelyMeetingExperience.button'
|
||||||
onClick = { this._onPress }
|
onClick = { this._onPress }
|
||||||
type = { BUTTON_TYPES.PRIMARY } />
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
|
@ -112,6 +124,7 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onPress() {
|
_onPress() {
|
||||||
|
this.props.dispatch(toggleShareDialog(true));
|
||||||
this.props.dispatch(doInvitePeople());
|
this.props.dispatch(doInvitePeople());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,16 +136,18 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
||||||
* @private
|
* @private
|
||||||
* @returns {Props}
|
* @returns {Props}
|
||||||
*/
|
*/
|
||||||
function _mapStateToProps(state) {
|
function _mapStateToProps(state: IReduxState) {
|
||||||
const { disableInviteFunctions } = state['features/base/config'];
|
const { disableInviteFunctions } = state['features/base/config'];
|
||||||
const { conference } = state['features/base/conference'];
|
const { conference } = state['features/base/conference'];
|
||||||
|
const { shareDialogVisible } = state['features/share-room'];
|
||||||
const flag = getFeatureFlag(state, INVITE_ENABLED, true);
|
const flag = getFeatureFlag(state, INVITE_ENABLED, true);
|
||||||
const _isInBreakoutRoom = isInBreakoutRoom(state);
|
const _isInBreakoutRoom = isInBreakoutRoom(state);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_isInBreakoutRoom,
|
_isInBreakoutRoom,
|
||||||
_isInviteFunctionsDiabled: !flag || disableInviteFunctions,
|
_isInviteFunctionsDisabled: !flag || disableInviteFunctions,
|
||||||
_isLonelyMeeting: conference && getParticipantCountWithFake(state) === 1
|
_isLonelyMeeting: conference && getParticipantCountWithFake(state) === 1,
|
||||||
|
_shareDialogVisible: shareDialogVisible
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,3 +21,13 @@ export const BEGIN_SHARE_ROOM = 'BEGIN_SHARE_ROOM';
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
export const END_SHARE_ROOM = 'END_SHARE_ROOM';
|
export const END_SHARE_ROOM = 'END_SHARE_ROOM';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of (redux) action which toggles the share meeting url dialog visibility.
|
||||||
|
*
|
||||||
|
* {
|
||||||
|
* type: TOGGLE_SHARE_DIALOG,
|
||||||
|
* visible: boolean
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
export const TOGGLE_SHARE_DIALOG = 'TOGGLE_SHARE_DIALOG';
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import { IStore } from '../app/types';
|
import { IStore } from '../app/types';
|
||||||
import { getInviteURL } from '../base/connection/functions';
|
import { getInviteURL } from '../base/connection/functions';
|
||||||
|
|
||||||
import { BEGIN_SHARE_ROOM, END_SHARE_ROOM } from './actionTypes';
|
import {
|
||||||
|
BEGIN_SHARE_ROOM,
|
||||||
|
END_SHARE_ROOM,
|
||||||
|
TOGGLE_SHARE_DIALOG
|
||||||
|
} from './actionTypes';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begins the UI procedure to share the URL for the current conference/room.
|
* Begins the UI procedure to share the URL for the current conference/room.
|
||||||
|
@ -16,7 +20,8 @@ export function beginShareRoom(roomURL?: string) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
roomURL = getInviteURL(getState);
|
roomURL = getInviteURL(getState);
|
||||||
}
|
}
|
||||||
roomURL && dispatch({
|
|
||||||
|
dispatch({
|
||||||
type: BEGIN_SHARE_ROOM,
|
type: BEGIN_SHARE_ROOM,
|
||||||
roomURL
|
roomURL
|
||||||
});
|
});
|
||||||
|
@ -43,3 +48,22 @@ export function endShareRoom(roomURL: string, shared: boolean) {
|
||||||
shared
|
shared
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UI procedure for sharing conference room URL inside a dialog.
|
||||||
|
*
|
||||||
|
* @param {boolean} visible - True if share dialog is visible; false,
|
||||||
|
* otherwise.
|
||||||
|
* @public
|
||||||
|
* @returns {{
|
||||||
|
* type: TOGGLE_SHARE_DIALOG,
|
||||||
|
* visible: boolean
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
export function toggleShareDialog(visible: boolean) {
|
||||||
|
return {
|
||||||
|
type: TOGGLE_SHARE_DIALOG,
|
||||||
|
visible
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
|
||||||
import { getShareInfoText } from '../invite/functions';
|
import { getShareInfoText } from '../invite/functions';
|
||||||
|
|
||||||
import { BEGIN_SHARE_ROOM } from './actionTypes';
|
import { BEGIN_SHARE_ROOM } from './actionTypes';
|
||||||
import { endShareRoom } from './actions';
|
import { endShareRoom, toggleShareDialog } from './actions';
|
||||||
import logger from './logger';
|
import logger from './logger';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,8 +53,10 @@ function _shareRoom(roomURL: string, { dispatch, getState }: IStore) {
|
||||||
.then(
|
.then(
|
||||||
/* onFulfilled */ value => {
|
/* onFulfilled */ value => {
|
||||||
onFulfilled(value.action === Share.sharedAction);
|
onFulfilled(value.action === Share.sharedAction);
|
||||||
|
dispatch(toggleShareDialog(false));
|
||||||
},
|
},
|
||||||
/* onRejected */ reason => {
|
/* onRejected */ reason => {
|
||||||
|
dispatch(toggleShareDialog(false));
|
||||||
logger.error(
|
logger.error(
|
||||||
`Failed to share conference/room URL ${roomURL}:`,
|
`Failed to share conference/room URL ${roomURL}:`,
|
||||||
reason);
|
reason);
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import ReducerRegistry from '../base/redux/ReducerRegistry';
|
||||||
|
|
||||||
|
import { TOGGLE_SHARE_DIALOG } from './actionTypes';
|
||||||
|
|
||||||
|
const DEFAULT_STATE = {
|
||||||
|
shareDialogVisible: false
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface IShareRoomState {
|
||||||
|
shareDialogVisible: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReducerRegistry.register<IShareRoomState>('features/share-room', (state = DEFAULT_STATE, action): IShareRoomState => {
|
||||||
|
switch (action.type) {
|
||||||
|
case TOGGLE_SHARE_DIALOG:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
shareDialogVisible: action.visible
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
});
|
Loading…
Reference in New Issue