From 6b68fba2201e4e24fc0cd4dffde2b1d01401142e Mon Sep 17 00:00:00 2001 From: Bettenbuk Zoltan Date: Wed, 19 Dec 2018 19:40:17 +0100 Subject: [PATCH] [RN] Add remote video menu --- lang/main.json | 2 + .../base/dialog/components/native/styles.js | 41 +++++++ .../react/components/AbstractContainer.js | 6 + .../base/react/components/native/Container.js | 4 +- .../filmstrip/components/native/Thumbnail.js | 31 +++++ react/features/remote-video-menu/actions.js | 14 +++ .../MuteRemoteParticipantDialog.native.js | 0 .../components/index.native.js | 3 + .../remote-video-menu/components/index.web.js | 3 + .../components/native/KickButton.js | 46 +++++++ .../native/KickRemoteParticipantDialog.js | 84 +++++++++++++ .../components/native/MuteButton.js | 116 ++++++++++++++++++ .../native/MuteRemoteParticipantDialog.js | 80 ++++++++++++ .../components/native/RemoteVideoMenu.js | 109 ++++++++++++++++ .../components/native/index.js | 3 + .../components/native/styles.js | 20 +++ .../components/{ => web}/KickButton.js | 6 +- .../components/{ => web}/MuteButton.js | 6 +- .../MuteRemoteParticipantDialog.js} | 8 +- .../{ => web}/RemoteControlButton.js | 4 +- .../components/{ => web}/RemoteVideoMenu.js | 0 .../{ => web}/RemoteVideoMenuButton.js | 0 .../{ => web}/RemoteVideoMenuTriggerButton.js | 2 +- .../components/{ => web}/VolumeSlider.js | 0 .../components/{ => web}/index.js | 2 + .../toolbox/components/native/OverflowMenu.js | 9 +- .../toolbox/components/native/styles.js | 48 -------- 27 files changed, 582 insertions(+), 65 deletions(-) create mode 100644 react/features/remote-video-menu/actions.js delete mode 100644 react/features/remote-video-menu/components/MuteRemoteParticipantDialog.native.js create mode 100644 react/features/remote-video-menu/components/index.native.js create mode 100644 react/features/remote-video-menu/components/index.web.js create mode 100644 react/features/remote-video-menu/components/native/KickButton.js create mode 100644 react/features/remote-video-menu/components/native/KickRemoteParticipantDialog.js create mode 100644 react/features/remote-video-menu/components/native/MuteButton.js create mode 100644 react/features/remote-video-menu/components/native/MuteRemoteParticipantDialog.js create mode 100644 react/features/remote-video-menu/components/native/RemoteVideoMenu.js create mode 100644 react/features/remote-video-menu/components/native/index.js create mode 100644 react/features/remote-video-menu/components/native/styles.js rename react/features/remote-video-menu/components/{ => web}/KickButton.js (94%) rename react/features/remote-video-menu/components/{ => web}/MuteButton.js (95%) rename react/features/remote-video-menu/components/{MuteRemoteParticipantDialog.web.js => web/MuteRemoteParticipantDialog.js} (93%) rename react/features/remote-video-menu/components/{ => web}/RemoteControlButton.js (97%) rename react/features/remote-video-menu/components/{ => web}/RemoteVideoMenu.js (100%) rename react/features/remote-video-menu/components/{ => web}/RemoteVideoMenuButton.js (100%) rename react/features/remote-video-menu/components/{ => web}/RemoteVideoMenuTriggerButton.js (99%) rename react/features/remote-video-menu/components/{ => web}/VolumeSlider.js (100%) rename react/features/remote-video-menu/components/{ => web}/index.js (97%) diff --git a/lang/main.json b/lang/main.json index b464e56a0..a131d898f 100644 --- a/lang/main.json +++ b/lang/main.json @@ -385,8 +385,10 @@ "externalInstallationMsg": "You need to install our desktop sharing extension.", "inlineInstallationMsg": "You need to install our desktop sharing extension.", "inlineInstallExtension": "Install now", + "kickParticipantDialog": "Are you sure you want to kick this participant?", "muteParticipantTitle": "Mute this member?", "muteParticipantBody": "You won't be able to unmute them, but they can unmute themselves at any time.", + "muteParticipantDialog": "Are you sure you want to mute this participant? You won't be able to unmute them, but they can unmute themselves at any time.", "muteParticipantButton": "Mute", "liveStreamingDisabledTooltip": "Start live stream disabled.", "liveStreamingDisabledForGuestTooltip": "Guests can't start live streaming.", diff --git a/react/features/base/dialog/components/native/styles.js b/react/features/base/dialog/components/native/styles.js index 5a82498ba..574174911 100644 --- a/react/features/base/dialog/components/native/styles.js +++ b/react/features/base/dialog/components/native/styles.js @@ -12,6 +12,47 @@ const DIALOG_BORDER_COLOR = 'rgba(255, 255, 255, 0.2)'; export const FIELD_UNDERLINE = ColorPalette.transparent; export const PLACEHOLDER_COLOR = ColorPalette.lightGrey; +/** + * Default styles for the items of a {@code BottomSheet}-based menu. + * + * These have been implemented as per the Material Design guidelines: + * {@link https://material.io/guidelines/components/bottom-sheets.html}. + */ +const bottomSheetItemStyles = createStyleSheet({ + /** + * Container style for a generic item rendered in the menu. + */ + style: { + alignItems: 'center', + flexDirection: 'row', + height: 48 + }, + + /** + * Style for the {@code Icon} element in a generic item of the menu. + */ + iconStyle: { + color: ColorPalette.white, + fontSize: 24 + }, + + /** + * Style for the label in a generic item rendered in the menu. + */ + labelStyle: { + color: ColorPalette.white, + flexShrink: 1, + fontSize: 16, + marginLeft: 32, + opacity: 0.90 + } +}); + +export const bottomSheetItemStylesCombined = { + ...bottomSheetItemStyles, + underlayColor: ColorPalette.overflowMenuItemUnderlay +}; + /** * The React {@code Component} styles of {@code BottomSheet}. These have * been implemented as per the Material Design guidelines: diff --git a/react/features/base/react/components/AbstractContainer.js b/react/features/base/react/components/AbstractContainer.js index 726a29a02..4945c2956 100644 --- a/react/features/base/react/components/AbstractContainer.js +++ b/react/features/base/react/components/AbstractContainer.js @@ -31,6 +31,12 @@ export type Props = { */ onClick?: ?Function, + /** + * The event handler/listener to be invoked when this + * {@code AbstractContainer} is long pressed on React Native. + */ + onLongPress?: ?Function, + /** * The style (as in stylesheet) to be applied to this * {@code AbstractContainer}. diff --git a/react/features/base/react/components/native/Container.js b/react/features/base/react/components/native/Container.js index 08a218cc9..5122bcc71 100644 --- a/react/features/base/react/components/native/Container.js +++ b/react/features/base/react/components/native/Container.js @@ -27,6 +27,7 @@ export default class Container extends AbstractContainer

{ accessibilityLabel, accessible, onClick, + onLongPress, touchFeedback = onClick, underlayColor, visible = true, @@ -38,7 +39,7 @@ export default class Container extends AbstractContainer

{ return null; } - const onClickOrTouchFeedback = onClick || touchFeedback; + const onClickOrTouchFeedback = onClick || onLongPress || touchFeedback; let element = super._render( View, @@ -57,6 +58,7 @@ export default class Container extends AbstractContainer

{ { accessibilityLabel, accessible, + onLongPress, onPress: onClick, ...touchFeedback && { underlayColor } }, diff --git a/react/features/filmstrip/components/native/Thumbnail.js b/react/features/filmstrip/components/native/Thumbnail.js index 8bbcee099..ff0cfd5de 100644 --- a/react/features/filmstrip/components/native/Thumbnail.js +++ b/react/features/filmstrip/components/native/Thumbnail.js @@ -3,15 +3,19 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; +import { openDialog } from '../../../base/dialog'; import { Audio, MEDIA_TYPE } from '../../../base/media'; import { PARTICIPANT_ROLE, ParticipantView, + isLocalParticipantModerator, pinParticipant } from '../../../base/participants'; import { Container } from '../../../base/react'; import { getTrackByMediaTypeAndParticipant } from '../../../base/tracks'; +import { RemoteVideoMenu } from '../../../remote-video-menu'; + import AudioMutedIndicator from './AudioMutedIndicator'; import DominantSpeakerIndicator from './DominantSpeakerIndicator'; import ModeratorIndicator from './ModeratorIndicator'; @@ -29,6 +33,11 @@ type Props = { */ _audioTrack: Object, + /** + * True if the local participant is a moderator. + */ + _isModerator: boolean, + /** * The Redux representation of the state "features/large-video". */ @@ -84,6 +93,7 @@ class Thumbnail extends Component { // Bind event handlers so they are only bound once for every instance. this._onClick = this._onClick.bind(this); + this._onShowRemoteVideoMenu = this._onShowRemoteVideoMenu.bind(this); } /** @@ -95,6 +105,7 @@ class Thumbnail extends Component { render() { const { _audioTrack: audioTrack, + _isModerator, _largeVideo: largeVideo, _videoTrack: videoTrack, disablePin, @@ -114,10 +125,13 @@ class Thumbnail extends Component { const participantInLargeVideo = participantId === largeVideo.participantId; const videoMuted = !videoTrack || videoTrack.muted; + const showRemoteVideoMenu = _isModerator && !participant.local; return ( { // TODO The following currently ignores interfaceConfig.filmStripOnly. dispatch(pinParticipant(participant.pinned ? null : participant.id)); } + + _onShowRemoteVideoMenu: () => void; + + /** + * Handles long press on the thumbnail. + * + * @returns {void} + */ + _onShowRemoteVideoMenu() { + const { dispatch, participant } = this.props; + + dispatch(openDialog(RemoteVideoMenu, { + participant + })); + } } /** @@ -177,6 +206,7 @@ class Thumbnail extends Component { * @private * @returns {{ * _audioTrack: Track, + * _isModerator: boolean, * _largeVideo: Object, * _videoTrack: Track * }} @@ -195,6 +225,7 @@ function _mapStateToProps(state, ownProps) { return { _audioTrack: audioTrack, + _isModerator: isLocalParticipantModerator(state), _largeVideo: largeVideo, _videoTrack: videoTrack }; diff --git a/react/features/remote-video-menu/actions.js b/react/features/remote-video-menu/actions.js new file mode 100644 index 000000000..16534a7f2 --- /dev/null +++ b/react/features/remote-video-menu/actions.js @@ -0,0 +1,14 @@ +// @flow + +import { hideDialog } from '../base/dialog'; + +import { RemoteVideoMenu } from './components'; + +/** + * Hides the remote video menu. + * + * @returns {Function} + */ +export function hideRemoteVideoMenu() { + return hideDialog(RemoteVideoMenu); +} diff --git a/react/features/remote-video-menu/components/MuteRemoteParticipantDialog.native.js b/react/features/remote-video-menu/components/MuteRemoteParticipantDialog.native.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/react/features/remote-video-menu/components/index.native.js b/react/features/remote-video-menu/components/index.native.js new file mode 100644 index 000000000..a32ec6061 --- /dev/null +++ b/react/features/remote-video-menu/components/index.native.js @@ -0,0 +1,3 @@ +// @flow + +export * from './native'; diff --git a/react/features/remote-video-menu/components/index.web.js b/react/features/remote-video-menu/components/index.web.js new file mode 100644 index 000000000..40d5f4652 --- /dev/null +++ b/react/features/remote-video-menu/components/index.web.js @@ -0,0 +1,3 @@ +// @flow + +export * from './web'; diff --git a/react/features/remote-video-menu/components/native/KickButton.js b/react/features/remote-video-menu/components/native/KickButton.js new file mode 100644 index 000000000..2f10d590a --- /dev/null +++ b/react/features/remote-video-menu/components/native/KickButton.js @@ -0,0 +1,46 @@ +// @flow + +import { connect } from 'react-redux'; + +import { openDialog } from '../../../base/dialog'; +import { translate } from '../../../base/i18n'; +import { AbstractButton } from '../../../base/toolbox'; +import type { AbstractButtonProps } from '../../../base/toolbox'; + +import KickRemoteParticipantDialog from './KickRemoteParticipantDialog'; + +type Props = AbstractButtonProps & { + + /** + * The redux {@code dispatch} function. + */ + dispatch: Function, + + /** + * The participant object that this button is supposed to kick. + */ + participant: Object +}; + +/** + * A remote video menu button which kicks the remote participant. + */ +class KickButton extends AbstractButton { + accessibilityLabel = 'toolbar.accessibilityLabel.audioRoute'; + iconName = 'icon-kick'; + label = 'videothumbnail.kick'; + + /** + * Handles clicking / pressing the button, and kicks the participant. + * + * @private + * @returns {void} + */ + _handleClick() { + const { dispatch, participant } = this.props; + + dispatch(openDialog(KickRemoteParticipantDialog, { participant })); + } +} + +export default translate(connect()(KickButton)); diff --git a/react/features/remote-video-menu/components/native/KickRemoteParticipantDialog.js b/react/features/remote-video-menu/components/native/KickRemoteParticipantDialog.js new file mode 100644 index 000000000..99615c0b5 --- /dev/null +++ b/react/features/remote-video-menu/components/native/KickRemoteParticipantDialog.js @@ -0,0 +1,84 @@ +// @flow + +import React, { Component } from 'react'; +import { connect } from 'react-redux'; + +import { + createRemoteVideoMenuButtonEvent, + sendAnalytics +} from '../../../analytics'; +import { ConfirmDialog } from '../../../base/dialog'; +import { translate } from '../../../base/i18n'; +import { kickParticipant } from '../../../base/participants'; + +type Props = { + + /** + * The Redux dispatch function. + */ + dispatch: Function, + + /** + * The remote participant to be kicked. + */ + participant: Object, + + /** + * Function to translate i18n labels. + */ + t: Function +}; + +/** + * Dialog to confirm a remote participant kick action. + */ +class KickRemoteParticipantDialog extends Component { + /** + * Initializes a new {@code KickRemoteParticipantDialog} instance. + * + * @inheritdoc + */ + constructor(props: Props) { + super(props); + + this._onSubmit = this._onSubmit.bind(this); + } + + /** + * Implements React's {@link Component#render()}. + * + * @inheritdoc + * @returns {ReactElement} + */ + render() { + return ( + + ); + } + + _onSubmit: () => boolean; + + /** + * Callback for the confirm button. + * + * @private + * @returns {boolean} - True (to note that the modal should be closed). + */ + _onSubmit() { + const { dispatch, participant } = this.props; + + sendAnalytics(createRemoteVideoMenuButtonEvent( + 'kick.button', + { + 'participant_id': participant.id + })); + + dispatch(kickParticipant(participant.id)); + + return true; + } +} + +export default translate(connect()(KickRemoteParticipantDialog)); diff --git a/react/features/remote-video-menu/components/native/MuteButton.js b/react/features/remote-video-menu/components/native/MuteButton.js new file mode 100644 index 000000000..b95294806 --- /dev/null +++ b/react/features/remote-video-menu/components/native/MuteButton.js @@ -0,0 +1,116 @@ +// @flow + +import { connect } from 'react-redux'; + +import { + createRemoteVideoMenuButtonEvent, + sendAnalytics +} from '../../../analytics'; +import { openDialog } from '../../../base/dialog'; +import { translate } from '../../../base/i18n'; +import { MEDIA_TYPE } from '../../../base/media'; +import { + AbstractButton, + type AbstractButtonProps +} from '../../../base/toolbox'; +import { getTrackByMediaTypeAndParticipant } from '../../../base/tracks'; + +import MuteRemoteParticipantDialog from './MuteRemoteParticipantDialog'; + +type Props = AbstractButtonProps & { + + /** + * The audio track of the participant. + */ + _audioTrack: ?Object, + + /** + * The redux {@code dispatch} function. + */ + dispatch: Function, + + /** + * The participant object that this button is supposed to mute/unmute. + */ + participant: Object +}; + +/** + * A remote video menu button which mutes the remote participant. + */ +class MuteButton extends AbstractButton { + accessibilityLabel = 'toolbar.accessibilityLabel.audioRoute'; + iconName = 'icon-mic-disabled'; + label = 'videothumbnail.domute'; + toggledLabel = 'videothumbnail.muted'; + + /** + * Handles clicking / pressing the button, and mutes the participant. + * + * @private + * @returns {void} + */ + _handleClick() { + const { dispatch, participant } = this.props; + + sendAnalytics(createRemoteVideoMenuButtonEvent( + 'mute.button', + { + 'participant_id': participant.id + })); + + dispatch(openDialog(MuteRemoteParticipantDialog, { participant })); + } + + /** + * Renders the item disabled if the participant is muted. + * + * @inheritdoc + */ + _isDisabled() { + return this._isMuted(); + } + + /** + * Returns true if the participant is muted, false otherwise. + * + * @returns {boolean} + */ + _isMuted() { + const { _audioTrack } = this.props; + + return !_audioTrack || _audioTrack.muted; + } + + /** + * Renders the item toggled if the participant is muted. + * + * @inheritdoc + */ + _isToggled() { + return this._isMuted(); + } +} + +/** + * Function that maps parts of Redux state tree into component props. + * + * @param {Object} state - Redux state. + * @param {Object} ownProps - Properties of component. + * @private + * @returns {{ + * _audioTrack: Track + * }} + */ +function _mapStateToProps(state, ownProps) { + const tracks = state['features/base/tracks']; + const audioTrack + = getTrackByMediaTypeAndParticipant( + tracks, MEDIA_TYPE.AUDIO, ownProps.participant.id); + + return { + _audioTrack: audioTrack + }; +} + +export default translate(connect(_mapStateToProps)(MuteButton)); diff --git a/react/features/remote-video-menu/components/native/MuteRemoteParticipantDialog.js b/react/features/remote-video-menu/components/native/MuteRemoteParticipantDialog.js new file mode 100644 index 000000000..c06d1affc --- /dev/null +++ b/react/features/remote-video-menu/components/native/MuteRemoteParticipantDialog.js @@ -0,0 +1,80 @@ +// @flow + +import React, { Component } from 'react'; +import { connect } from 'react-redux'; + +import { + createRemoteMuteConfirmedEvent, + sendAnalytics +} from '../../../analytics'; +import { ConfirmDialog } from '../../../base/dialog'; +import { translate } from '../../../base/i18n'; +import { muteRemoteParticipant } from '../../../base/participants'; + +type Props = { + + /** + * The Redux dispatch function. + */ + dispatch: Function, + + /** + * The remote participant to be muted. + */ + participant: Object, + + /** + * Function to translate i18n labels. + */ + t: Function +}; + +/** + * Dialog to confirm a remote participant mute action. + */ +class MuteRemoteParticipantDialog extends Component { + /** + * Initializes a new {@code MuteRemoteParticipantDialog} instance. + * + * @inheritdoc + */ + constructor(props: Props) { + super(props); + + this._onSubmit = this._onSubmit.bind(this); + } + + /** + * Implements React's {@link Component#render()}. + * + * @inheritdoc + * @returns {ReactElement} + */ + render() { + return ( + + ); + } + + _onSubmit: () => boolean; + + /** + * Callback for the confirm button. + * + * @private + * @returns {boolean} - True (to note that the modal should be closed). + */ + _onSubmit() { + const { dispatch, participant } = this.props; + + sendAnalytics(createRemoteMuteConfirmedEvent(participant.id)); + + dispatch(muteRemoteParticipant(participant.id)); + + return true; + } +} + +export default translate(connect()(MuteRemoteParticipantDialog)); diff --git a/react/features/remote-video-menu/components/native/RemoteVideoMenu.js b/react/features/remote-video-menu/components/native/RemoteVideoMenu.js new file mode 100644 index 000000000..670ab368f --- /dev/null +++ b/react/features/remote-video-menu/components/native/RemoteVideoMenu.js @@ -0,0 +1,109 @@ +// @flow + +import React, { Component } from 'react'; +import { Text, View } from 'react-native'; +import { connect } from 'react-redux'; + +import { + BottomSheet, + bottomSheetItemStylesCombined +} from '../../../base/dialog'; +import { getParticipantDisplayName } from '../../../base/participants'; + +import { hideRemoteVideoMenu } from '../../actions'; + +import KickButton from './KickButton'; +import MuteButton from './MuteButton'; +import styles from './styles'; + +type Props = { + + /** + * The Redux dispatch function. + */ + dispatch: Function, + + /** + * The participant for which this menu opened for. + */ + participant: Object, + + /** + * Display name of the participant retreived from Redux. + */ + _participantDisplayName: string +} + +/** + * Class to implement a popup menu that opens upon long pressing a thumbnail. + */ +class RemoteVideoMenu extends Component { + /** + * Constructor of the component. + * + * @inheritdoc + */ + constructor(props: Props) { + super(props); + + this._onCancel = this._onCancel.bind(this); + } + + /** + * Implements {@code Component#render}. + * + * @inheritdoc + */ + render() { + const buttonProps = { + afterClick: this._onCancel, + showLabel: true, + participant: this.props.participant, + styles: bottomSheetItemStylesCombined + }; + + return ( + + + + { this.props._participantDisplayName } + + + + + + ); + } + + _onCancel: () => void; + + /** + * Callback to hide the {@code RemoteVideoMenu}. + * + * @private + * @returns {void} + */ + _onCancel() { + this.props.dispatch(hideRemoteVideoMenu()); + } +} + +/** + * Function that maps parts of Redux state tree into component props. + * + * @param {Object} state - Redux state. + * @param {Object} ownProps - Properties of component. + * @private + * @returns {{ + * _participantDisplayName: string + * }} + */ +function _mapStateToProps(state, ownProps) { + const { id } = ownProps.participant; + + return { + _participantDisplayName: getParticipantDisplayName(state, id) + }; +} + +export default connect(_mapStateToProps)(RemoteVideoMenu); diff --git a/react/features/remote-video-menu/components/native/index.js b/react/features/remote-video-menu/components/native/index.js new file mode 100644 index 000000000..c8393b1ac --- /dev/null +++ b/react/features/remote-video-menu/components/native/index.js @@ -0,0 +1,3 @@ +// @flow + +export { default as RemoteVideoMenu } from './RemoteVideoMenu'; diff --git a/react/features/remote-video-menu/components/native/styles.js b/react/features/remote-video-menu/components/native/styles.js new file mode 100644 index 000000000..7479e40e2 --- /dev/null +++ b/react/features/remote-video-menu/components/native/styles.js @@ -0,0 +1,20 @@ +// @flow + +import { ColorPalette, createStyleSheet } from '../../../base/styles'; + +export default createStyleSheet({ + participantNameContainer: { + alignItems: 'center', + borderBottomColor: ColorPalette.darkGrey, + borderBottomWidth: 1, + flexDirection: 'row', + height: 48 + }, + + participantNameLabel: { + color: ColorPalette.lightGrey, + flexShrink: 1, + fontSize: 16, + opacity: 0.90 + } +}); diff --git a/react/features/remote-video-menu/components/KickButton.js b/react/features/remote-video-menu/components/web/KickButton.js similarity index 94% rename from react/features/remote-video-menu/components/KickButton.js rename to react/features/remote-video-menu/components/web/KickButton.js index a661cd2f4..b4a870bb6 100644 --- a/react/features/remote-video-menu/components/KickButton.js +++ b/react/features/remote-video-menu/components/web/KickButton.js @@ -6,9 +6,9 @@ import { connect } from 'react-redux'; import { createRemoteVideoMenuButtonEvent, sendAnalytics -} from '../../analytics'; -import { translate } from '../../base/i18n'; -import { kickParticipant } from '../../base/participants'; +} from '../../../analytics'; +import { translate } from '../../../base/i18n'; +import { kickParticipant } from '../../../base/participants'; import RemoteVideoMenuButton from './RemoteVideoMenuButton'; diff --git a/react/features/remote-video-menu/components/MuteButton.js b/react/features/remote-video-menu/components/web/MuteButton.js similarity index 95% rename from react/features/remote-video-menu/components/MuteButton.js rename to react/features/remote-video-menu/components/web/MuteButton.js index e574b1bf5..20c3f0c57 100644 --- a/react/features/remote-video-menu/components/MuteButton.js +++ b/react/features/remote-video-menu/components/web/MuteButton.js @@ -6,9 +6,9 @@ import { connect } from 'react-redux'; import { createRemoteVideoMenuButtonEvent, sendAnalytics -} from '../../analytics'; -import { translate } from '../../base/i18n'; -import { openDialog } from '../../base/dialog'; +} from '../../../analytics'; +import { translate } from '../../../base/i18n'; +import { openDialog } from '../../../base/dialog'; import RemoteVideoMenuButton from './RemoteVideoMenuButton'; import MuteRemoteParticipantDialog from './MuteRemoteParticipantDialog'; diff --git a/react/features/remote-video-menu/components/MuteRemoteParticipantDialog.web.js b/react/features/remote-video-menu/components/web/MuteRemoteParticipantDialog.js similarity index 93% rename from react/features/remote-video-menu/components/MuteRemoteParticipantDialog.web.js rename to react/features/remote-video-menu/components/web/MuteRemoteParticipantDialog.js index 4441634c1..65d806726 100644 --- a/react/features/remote-video-menu/components/MuteRemoteParticipantDialog.web.js +++ b/react/features/remote-video-menu/components/web/MuteRemoteParticipantDialog.js @@ -3,14 +3,14 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; -import { Dialog } from '../../base/dialog'; -import { translate } from '../../base/i18n'; +import { Dialog } from '../../../base/dialog'; +import { translate } from '../../../base/i18n'; import { createRemoteMuteConfirmedEvent, sendAnalytics -} from '../../analytics'; -import { muteRemoteParticipant } from '../../base/participants'; +} from '../../../analytics'; +import { muteRemoteParticipant } from '../../../base/participants'; /** * The type of the React {@code Component} props of diff --git a/react/features/remote-video-menu/components/RemoteControlButton.js b/react/features/remote-video-menu/components/web/RemoteControlButton.js similarity index 97% rename from react/features/remote-video-menu/components/RemoteControlButton.js rename to react/features/remote-video-menu/components/web/RemoteControlButton.js index 37fd70c96..3d8111cef 100644 --- a/react/features/remote-video-menu/components/RemoteControlButton.js +++ b/react/features/remote-video-menu/components/web/RemoteControlButton.js @@ -5,8 +5,8 @@ import React, { Component } from 'react'; import { createRemoteVideoMenuButtonEvent, sendAnalytics -} from '../../analytics'; -import { translate } from '../../base/i18n'; +} from '../../../analytics'; +import { translate } from '../../../base/i18n'; import RemoteVideoMenuButton from './RemoteVideoMenuButton'; diff --git a/react/features/remote-video-menu/components/RemoteVideoMenu.js b/react/features/remote-video-menu/components/web/RemoteVideoMenu.js similarity index 100% rename from react/features/remote-video-menu/components/RemoteVideoMenu.js rename to react/features/remote-video-menu/components/web/RemoteVideoMenu.js diff --git a/react/features/remote-video-menu/components/RemoteVideoMenuButton.js b/react/features/remote-video-menu/components/web/RemoteVideoMenuButton.js similarity index 100% rename from react/features/remote-video-menu/components/RemoteVideoMenuButton.js rename to react/features/remote-video-menu/components/web/RemoteVideoMenuButton.js diff --git a/react/features/remote-video-menu/components/RemoteVideoMenuTriggerButton.js b/react/features/remote-video-menu/components/web/RemoteVideoMenuTriggerButton.js similarity index 99% rename from react/features/remote-video-menu/components/RemoteVideoMenuTriggerButton.js rename to react/features/remote-video-menu/components/web/RemoteVideoMenuTriggerButton.js index a0366f17d..0686873f2 100644 --- a/react/features/remote-video-menu/components/RemoteVideoMenuTriggerButton.js +++ b/react/features/remote-video-menu/components/web/RemoteVideoMenuTriggerButton.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; -import { Popover } from '../../base/popover'; +import { Popover } from '../../../base/popover'; import { MuteButton, diff --git a/react/features/remote-video-menu/components/VolumeSlider.js b/react/features/remote-video-menu/components/web/VolumeSlider.js similarity index 100% rename from react/features/remote-video-menu/components/VolumeSlider.js rename to react/features/remote-video-menu/components/web/VolumeSlider.js diff --git a/react/features/remote-video-menu/components/index.js b/react/features/remote-video-menu/components/web/index.js similarity index 97% rename from react/features/remote-video-menu/components/index.js rename to react/features/remote-video-menu/components/web/index.js index b8daab3b9..3485ba422 100644 --- a/react/features/remote-video-menu/components/index.js +++ b/react/features/remote-video-menu/components/web/index.js @@ -1,3 +1,5 @@ +// @flow + export { default as KickButton } from './KickButton'; export { default as MuteButton } from './MuteButton'; export { diff --git a/react/features/toolbox/components/native/OverflowMenu.js b/react/features/toolbox/components/native/OverflowMenu.js index d0db50949..6ee82c614 100644 --- a/react/features/toolbox/components/native/OverflowMenu.js +++ b/react/features/toolbox/components/native/OverflowMenu.js @@ -4,7 +4,11 @@ import React, { Component } from 'react'; import { Platform } from 'react-native'; import { connect } from 'react-redux'; -import { BottomSheet, hideDialog } from '../../../base/dialog'; +import { + BottomSheet, + bottomSheetItemStylesCombined, + hideDialog +} from '../../../base/dialog'; import { AudioRouteButton } from '../../../mobile/audio-mode'; import { PictureInPictureButton } from '../../../mobile/picture-in-picture'; import { LiveStreamButton, RecordButton } from '../../../recording'; @@ -13,7 +17,6 @@ import { ClosedCaptionButton } from '../../../subtitles'; import { TileViewButton } from '../../../video-layout'; import AudioOnlyButton from './AudioOnlyButton'; -import { overflowMenuItemStyles } from './styles'; import ToggleCameraButton from './ToggleCameraButton'; /** @@ -63,7 +66,7 @@ class OverflowMenu extends Component { const buttonProps = { afterClick: this._onCancel, showLabel: true, - styles: overflowMenuItemStyles + styles: bottomSheetItemStylesCombined }; return ( diff --git a/react/features/toolbox/components/native/styles.js b/react/features/toolbox/components/native/styles.js index 1fca6c61e..60861e303 100644 --- a/react/features/toolbox/components/native/styles.js +++ b/react/features/toolbox/components/native/styles.js @@ -130,51 +130,3 @@ export const toolbarToggledButtonStyles = { iconStyle: styles.whiteToolbarButtonIcon, style: styles.whiteToolbarButton }; - -// Overflow menu: - -/** - * Styles for the {@code OverflowMenu} items. - * - * These have been implemented as per the Material Design guidelines: - * {@link https://material.io/guidelines/components/bottom-sheets.html}. - */ -const overflowMenuStyles = createStyleSheet({ - /** - * Container style for a {@code ToolboxItem} rendered in the - * {@code OverflowMenu}. - */ - container: { - alignItems: 'center', - flexDirection: 'row', - height: 48 - }, - - /** - * Style for the {@code Icon} element in a {@code ToolboxItem} rendered in - * the {@code OverflowMenu}. - */ - icon: { - color: ColorPalette.white, - fontSize: 24 - }, - - /** - * Style for the label in a {@code ToolboxItem} rendered in the - * {@code OverflowMenu}. - */ - label: { - color: ColorPalette.white, - flexShrink: 1, - fontSize: 16, - marginLeft: 32, - opacity: 0.90 - } -}); - -export const overflowMenuItemStyles = { - iconStyle: overflowMenuStyles.icon, - labelStyle: overflowMenuStyles.label, - style: overflowMenuStyles.container, - underlayColor: ColorPalette.overflowMenuItemUnderlay -};