diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 637e69f66..48784f20f 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -749,4 +749,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: bef1335067eaa4e8c558b1248f8ab3948de855bc
-COCOAPODS: 1.11.2
+COCOAPODS: 1.11.3
diff --git a/react/features/app/components/App.native.js b/react/features/app/components/App.native.js
index b374d38b5..4c2f1e707 100644
--- a/react/features/app/components/App.native.js
+++ b/react/features/app/components/App.native.js
@@ -1,10 +1,11 @@
// @flow
-import React from 'react';
+import React, { Fragment } from 'react';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import SplashScreen from 'react-native-splash-screen';
import { DialogContainer } from '../../base/dialog';
+import BottomSheetContainer from '../../base/dialog/components/native/BottomSheetContainer';
import { updateFlags } from '../../base/flags/actions';
import { CALL_INTEGRATION_ENABLED, SERVER_URL_CHANGE_ENABLED } from '../../base/flags/constants';
import { getFeatureFlag } from '../../base/flags/functions';
@@ -240,7 +241,10 @@ export class App extends AbstractApp {
*/
_renderDialogContainer() {
return (
-
+
+
+
+
);
}
}
diff --git a/react/features/base/dialog/actionTypes.ts b/react/features/base/dialog/actionTypes.ts
index 365f98061..266fea5bb 100644
--- a/react/features/base/dialog/actionTypes.ts
+++ b/react/features/base/dialog/actionTypes.ts
@@ -7,6 +7,15 @@
*/
export const HIDE_DIALOG = 'HIDE_DIALOG';
+/**
+ * The type of Redux action which closes a sheet.
+ *
+ * {
+ * type: HIDE_SHEET
+ * }
+ */
+export const HIDE_SHEET = 'HIDE_SHEET';
+
/**
* The type of Redux action which begins a request to open a dialog.
*
@@ -18,3 +27,15 @@ export const HIDE_DIALOG = 'HIDE_DIALOG';
*
*/
export const OPEN_DIALOG = 'OPEN_DIALOG';
+
+/**
+ * The type of Redux action which begins a request to open a sheet.
+ *
+ * {
+ * type: OPEN_SHEET,
+ * component: React.Component,
+ * props: PropTypes
+ * }
+ *
+ */
+export const OPEN_SHEET = 'OPEN_SHEET';
diff --git a/react/features/base/dialog/actions.js b/react/features/base/dialog/actions.js
index 31075f028..8ec133466 100644
--- a/react/features/base/dialog/actions.js
+++ b/react/features/base/dialog/actions.js
@@ -2,7 +2,12 @@
import type { Dispatch } from 'redux';
-import { HIDE_DIALOG, OPEN_DIALOG } from './actionTypes';
+import {
+ HIDE_DIALOG,
+ HIDE_SHEET,
+ OPEN_DIALOG,
+ OPEN_SHEET
+} from './actionTypes';
import { isDialogOpen } from './functions';
/**
@@ -24,6 +29,19 @@ export function hideDialog(component: ?Object) {
};
}
+/**
+ * Closes the active sheet.
+ *
+ * @returns {{
+ * type: HIDE_SHEET,
+ * }}
+ */
+export function hideSheet() {
+ return {
+ type: HIDE_SHEET
+ };
+}
+
/**
* Signals Dialog to open dialog.
*
@@ -44,6 +62,26 @@ export function openDialog(component: Object, componentProps: ?Object) {
};
}
+/**
+ * Opens the requested sheet.
+ *
+ * @param {Object} component - The component to display as a sheet.
+ * @param {Object} [componentProps] - The React {@code Component} props of the
+ * specified {@code component}.
+ * @returns {{
+ * type: OPEN_SHEET,
+ * component: React.Component,
+ * componentProps: (Object | undefined)
+ * }}
+ */
+export function openSheet(component: Object, componentProps: ?Object) {
+ return {
+ type: OPEN_SHEET,
+ component,
+ componentProps
+ };
+}
+
/**
* Signals Dialog to open a dialog with the specified component if the component
* is not already open. If it is open, then Dialog is signaled to close its
diff --git a/react/features/base/dialog/components/native/BottomSheet.js b/react/features/base/dialog/components/native/BottomSheet.js
index 055278527..5dfa1e5a8 100644
--- a/react/features/base/dialog/components/native/BottomSheet.js
+++ b/react/features/base/dialog/components/native/BottomSheet.js
@@ -2,6 +2,8 @@ import React, { PureComponent, type Node } from 'react';
import { SafeAreaView, ScrollView, View } from 'react-native';
import { SlidingView } from '../../../react';
+import { connect } from '../../../redux';
+import { hideSheet } from '../../actions';
import { bottomSheetStyles as styles } from './styles';
@@ -20,6 +22,11 @@ type Props = {
*/
children: Node,
+ /**
+ * Redux Dispatch function.
+ */
+ dispatch: Function,
+
/**
* Handler for the cancel event, which happens when the user dismisses
* the sheet.
@@ -61,6 +68,31 @@ class BottomSheet extends PureComponent {
showSlidingView: true
};
+ /**
+ * Initializes a new instance.
+ *
+ * @param {Props} props - The React {@code Component} props to initialize
+ * the new instance with.
+ */
+ constructor(props: Props) {
+ super(props);
+
+ this._onCancel = this._onCancel.bind(this);
+ }
+
+ /**
+ * Handles the cancel event, when the user dismissed the sheet. By default we close it.
+ *
+ * @returns {void}
+ */
+ _onCancel() {
+ if (this.props.onCancel) {
+ this.props.onCancel();
+ } else {
+ this.props.dispatch(hideSheet());
+ }
+ }
+
/**
* Implements React's {@link Component#render()}.
*
@@ -80,7 +112,7 @@ class BottomSheet extends PureComponent {
{
}
}
-export default BottomSheet;
+export default connect()(BottomSheet);
diff --git a/react/features/base/dialog/components/native/BottomSheetContainer.tsx b/react/features/base/dialog/components/native/BottomSheetContainer.tsx
new file mode 100644
index 000000000..35cc80caa
--- /dev/null
+++ b/react/features/base/dialog/components/native/BottomSheetContainer.tsx
@@ -0,0 +1,26 @@
+import React from 'react';
+import { Platform, StyleSheet, View } from 'react-native';
+import { FullWindowOverlay } from 'react-native-screens';
+import { useSelector } from 'react-redux';
+
+const Wrapper = Platform.select({
+ ios: FullWindowOverlay,
+ default: View
+});
+
+const BottomSheetContainer: () => JSX.Element = () => {
+ const { sheet, sheetProps } = useSelector(state => state['features/base/dialog']);
+ const { reducedUI } = useSelector(state => state['features/base/responsive-ui']);
+
+ if (!sheet || reducedUI) {
+ return null;
+ }
+
+ return (
+
+ { React.createElement(sheet, sheetProps) }
+
+ );
+}
+
+export default BottomSheetContainer;
diff --git a/react/features/base/dialog/reducer.js b/react/features/base/dialog/reducer.js
index cafde62be..56b47911b 100644
--- a/react/features/base/dialog/reducer.js
+++ b/react/features/base/dialog/reducer.js
@@ -1,8 +1,11 @@
-/* @flow */
-
import { assign, ReducerRegistry } from '../redux';
-import { HIDE_DIALOG, OPEN_DIALOG } from './actionTypes';
+import {
+ HIDE_DIALOG,
+ HIDE_SHEET,
+ OPEN_DIALOG,
+ OPEN_SHEET
+} from './actionTypes';
/**
* Reduces redux actions which show or hide dialogs.
@@ -32,6 +35,18 @@ ReducerRegistry.register('features/base/dialog', (state = {}, action) => {
component: action.component,
componentProps: action.componentProps
});
+
+ case HIDE_SHEET:
+ return assign(state, {
+ sheet: undefined,
+ sheetProps: undefined
+ });
+
+ case OPEN_SHEET:
+ return assign(state, {
+ sheet: action.component,
+ sheetProps: action.componentProps
+ });
}
return state;
diff --git a/react/features/conference/components/native/carmode/SoundDeviceButton.tsx b/react/features/conference/components/native/carmode/SoundDeviceButton.tsx
index 96921f19b..8ac3fc553 100644
--- a/react/features/conference/components/native/carmode/SoundDeviceButton.tsx
+++ b/react/features/conference/components/native/carmode/SoundDeviceButton.tsx
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import { Button } from 'react-native-paper';
import { useDispatch } from 'react-redux';
-import { openDialog } from '../../../../base/dialog/actions';
+import { openSheet } from '../../../../base/dialog/actions';
import AudioRoutePickerDialog from '../../../../mobile/audio-mode/components/AudioRoutePickerDialog';
import AudioIcon from './AudioIcon';
@@ -19,7 +19,7 @@ const SelectSoundDevice = () : JSX.Element => {
const dispatch = useDispatch();
const onSelect = useCallback(() =>
- dispatch(openDialog(AudioRoutePickerDialog))
+ dispatch(openSheet(AudioRoutePickerDialog))
, [ dispatch ]);
return (
diff --git a/react/features/mobile/audio-mode/components/AudioDeviceToggleButton.js b/react/features/mobile/audio-mode/components/AudioDeviceToggleButton.js
index eeb30f581..a229c89f5 100644
--- a/react/features/mobile/audio-mode/components/AudioDeviceToggleButton.js
+++ b/react/features/mobile/audio-mode/components/AudioDeviceToggleButton.js
@@ -1,7 +1,6 @@
-// @flow
import type { Dispatch } from 'redux';
-import { openDialog } from '../../../base/dialog';
+import { openSheet } from '../../../base/dialog';
import { translate } from '../../../base/i18n';
import { IconVolumeEmpty } from '../../../base/icons';
import { connect } from '../../../base/redux';
@@ -32,7 +31,7 @@ class AudioDeviceToggleButton extends AbstractButton {
* @returns {void}
*/
_handleClick() {
- this.props.dispatch(openDialog(AudioRoutePickerDialog));
+ this.props.dispatch(openSheet(AudioRoutePickerDialog));
}
}
diff --git a/react/features/mobile/audio-mode/components/AudioRoutePickerDialog.js b/react/features/mobile/audio-mode/components/AudioRoutePickerDialog.js
index 3d0b01f91..ea8029c4f 100644
--- a/react/features/mobile/audio-mode/components/AudioRoutePickerDialog.js
+++ b/react/features/mobile/audio-mode/components/AudioRoutePickerDialog.js
@@ -1,10 +1,8 @@
-// @flow
-
import _ from 'lodash';
import React, { Component } from 'react';
import { NativeModules, Text, TouchableHighlight, View } from 'react-native';
-import { hideDialog, BottomSheet } from '../../../base/dialog';
+import { hideSheet, BottomSheet } from '../../../base/dialog';
import { bottomSheetStyles } from '../../../base/dialog/components/native/styles';
import { translate } from '../../../base/i18n';
import {
@@ -143,11 +141,6 @@ const deviceInfoMap = {
}
};
-/**
- * The exported React {@code Component}.
- */
-let AudioRoutePickerDialog_; // eslint-disable-line prefer-const
-
/**
* Implements a React {@code Component} which prompts the user when a password
* is required to join a conference.
@@ -218,36 +211,10 @@ class AudioRoutePickerDialog extends Component {
constructor(props: Props) {
super(props);
- // Bind event handlers so they are only bound once per instance.
- this._onCancel = this._onCancel.bind(this);
-
// Trigger an initial update.
AudioMode.updateDeviceList && AudioMode.updateDeviceList();
}
- /**
- * Dispatches a redux action to hide this sheet.
- *
- * @returns {void}
- */
- _hide() {
- this.props.dispatch(hideDialog(AudioRoutePickerDialog_));
- }
-
- _onCancel: () => void;
-
- /**
- * Cancels the dialog by hiding it.
- *
- * @private
- * @returns {void}
- */
- _onCancel() {
- this._hide();
- }
-
- _onSelectDeviceFn: (Device) => Function;
-
/**
* Builds and returns a function which handles the selection of a device
* on the sheet. The selected device will be used by {@code AudioMode}.
@@ -258,7 +225,7 @@ class AudioRoutePickerDialog extends Component {
*/
_onSelectDeviceFn(device: Device) {
return () => {
- this._hide();
+ this.props.dispatch(hideSheet());
AudioMode.setAudioDevice(device.uid || device.type);
};
}
@@ -329,7 +296,7 @@ class AudioRoutePickerDialog extends Component {
}
return (
-
+
{ content }
);
@@ -348,6 +315,4 @@ function _mapStateToProps(state) {
};
}
-AudioRoutePickerDialog_ = translate(connect(_mapStateToProps)(AudioRoutePickerDialog));
-
-export default AudioRoutePickerDialog_;
+export default translate(connect(_mapStateToProps)(AudioRoutePickerDialog));
diff --git a/react/features/participants-pane/actions.native.js b/react/features/participants-pane/actions.native.js
index 13355b6ec..b145c9c0f 100644
--- a/react/features/participants-pane/actions.native.js
+++ b/react/features/participants-pane/actions.native.js
@@ -1,6 +1,6 @@
-// @flow
+import type { Dispatch } from 'redux';
-import { openDialog } from '../base/dialog';
+import { openSheet } from '../base/dialog';
import { SharedVideoMenu } from '../video-menu';
import { LocalVideoMenu } from '../video-menu/components/native';
import ConnectionStatusComponent
@@ -20,7 +20,7 @@ export * from './actions.any';
* @returns {Function}
*/
export function showContextMenuReject(participant: Object) {
- return openDialog(ContextMenuLobbyParticipantReject, { participant });
+ return openSheet(ContextMenuLobbyParticipantReject, { participant });
}
@@ -31,7 +31,7 @@ export function showContextMenuReject(participant: Object) {
* @returns {Function}
*/
export function showConnectionStatus(participantID: string) {
- return openDialog(ConnectionStatusComponent, { participantID });
+ return openSheet(ConnectionStatusComponent, { participantID });
}
/**
@@ -46,9 +46,9 @@ export function showContextMenuDetails(participantId: string, local: boolean = f
const { remoteVideoMenu } = getState()['features/base/config'];
if (local) {
- dispatch(openDialog(LocalVideoMenu));
+ dispatch(openSheet(LocalVideoMenu));
} else if (!remoteVideoMenu?.disabled) {
- dispatch(openDialog(RemoteVideoMenu, { participantId }));
+ dispatch(openSheet(RemoteVideoMenu, { participantId }));
}
};
}
@@ -60,7 +60,7 @@ export function showContextMenuDetails(participantId: string, local: boolean = f
* @returns {Function}
*/
export function showSharedVideoMenu(participantId: string) {
- return openDialog(SharedVideoMenu, { participantId });
+ return openSheet(SharedVideoMenu, { participantId });
}
/**
diff --git a/react/features/participants-pane/components/breakout-rooms/components/native/BreakoutRoomContextMenu.js b/react/features/participants-pane/components/breakout-rooms/components/native/BreakoutRoomContextMenu.js
index ba1b1ee05..dd3deb6ca 100644
--- a/react/features/participants-pane/components/breakout-rooms/components/native/BreakoutRoomContextMenu.js
+++ b/react/features/participants-pane/components/breakout-rooms/components/native/BreakoutRoomContextMenu.js
@@ -1,5 +1,3 @@
-// @flow
-
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { TouchableOpacity } from 'react-native';
@@ -7,7 +5,7 @@ import { Text } from 'react-native-paper';
import { useDispatch, useSelector } from 'react-redux';
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../../../analytics';
-import { hideDialog } from '../../../../../base/dialog/actions';
+import { hideSheet } from '../../../../../base/dialog/actions';
import BottomSheet from '../../../../../base/dialog/components/native/BottomSheet';
import {
Icon,
@@ -29,7 +27,6 @@ type Props = {
const BreakoutRoomContextMenu = ({ room }: Props) => {
const dispatch = useDispatch();
- const closeDialog = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
const isLocalModerator = useSelector(isLocalParticipantModerator);
const { hideJoinRoomButton } = useSelector(getBreakoutRoomsConfig);
const { t } = useTranslation();
@@ -37,23 +34,22 @@ const BreakoutRoomContextMenu = ({ room }: Props) => {
const onJoinRoom = useCallback(() => {
sendAnalytics(createBreakoutRoomsEvent('join'));
dispatch(moveToRoom(room.jid));
- closeDialog();
+ dispatch(hideSheet());
}, [ dispatch, room ]);
const onRemoveBreakoutRoom = useCallback(() => {
dispatch(removeBreakoutRoom(room.jid));
- closeDialog();
+ dispatch(hideSheet());
}, [ dispatch, room ]);
const onCloseBreakoutRoom = useCallback(() => {
dispatch(closeBreakoutRoom(room.id));
- closeDialog();
+ dispatch(hideSheet());
}, [ dispatch, room ]);
return (
{
!hideJoinRoomButton && (
diff --git a/react/features/participants-pane/components/breakout-rooms/components/native/CollapsibleRoom.js b/react/features/participants-pane/components/breakout-rooms/components/native/CollapsibleRoom.js
index 273a4a39d..2fdc50be8 100644
--- a/react/features/participants-pane/components/breakout-rooms/components/native/CollapsibleRoom.js
+++ b/react/features/participants-pane/components/breakout-rooms/components/native/CollapsibleRoom.js
@@ -1,11 +1,9 @@
-// @flow
-
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { FlatList } from 'react-native';
import { useDispatch } from 'react-redux';
-import { openDialog } from '../../../../../base/dialog';
+import { openSheet } from '../../../../../base/dialog';
import { participantMatchesSearch } from '../../../../functions';
import CollapsibleList from '../../../native/CollapsibleList';
import styles from '../../../native/styles';
@@ -41,7 +39,7 @@ export const CollapsibleRoom = ({ room, searchString }: Props) => {
const dispatch = useDispatch();
const { t } = useTranslation();
const _openContextMenu = useCallback(() => {
- dispatch(openDialog(BreakoutRoomContextMenu, { room }));
+ dispatch(openSheet(BreakoutRoomContextMenu, { room }));
}, [ room ]);
const roomParticipantsNr = Object.values(room.participants || {}).length;
const title
diff --git a/react/features/participants-pane/components/native/ContextMenuLobbyParticipantReject.js b/react/features/participants-pane/components/native/ContextMenuLobbyParticipantReject.js
index b92850f92..a861a911d 100644
--- a/react/features/participants-pane/components/native/ContextMenuLobbyParticipantReject.js
+++ b/react/features/participants-pane/components/native/ContextMenuLobbyParticipantReject.js
@@ -1,5 +1,3 @@
-// @flow
-
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { TouchableOpacity, View } from 'react-native';
@@ -7,7 +5,6 @@ import { Text } from 'react-native-paper';
import { useDispatch, useSelector } from 'react-redux';
import { Avatar } from '../../../base/avatar';
-import { hideDialog } from '../../../base/dialog';
import BottomSheet from '../../../base/dialog/components/native/BottomSheet';
import {
Icon, IconClose
@@ -16,6 +13,7 @@ import { setKnockingParticipantApproval } from '../../../lobby/actions.native';
import { getKnockingParticipantsById } from '../../../lobby/functions';
import styles from './styles';
+
type Props = {
/**
@@ -28,7 +26,6 @@ const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) => {
const dispatch = useDispatch();
const knockParticipantsIDArr = useSelector(getKnockingParticipantsById);
const knockParticipantIsAvailable = knockParticipantsIDArr.find(knockPartId => knockPartId === p.id);
- const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
const displayName = p.name;
const reject = useCallback(() => dispatch(setKnockingParticipantApproval(p.id, false), [ dispatch ]));
const { t } = useTranslation();
@@ -50,7 +47,6 @@ const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) => {
return (
{
const dispatch = useDispatch();
- const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
- const muteAllVideo = useCallback(() =>
- dispatch(openDialog(MuteEveryonesVideoDialog)),
- [ dispatch ]);
+ const muteAllVideo = useCallback(() => {
+ dispatch(openDialog(MuteEveryonesVideoDialog));
+ dispatch(hideSheet());
+ }, [ dispatch ]);
const { t } = useTranslation();
const isModerationSupported = useSelector(isAvModerationSupported);
@@ -54,7 +52,6 @@ export const ContextMenuMore = () => {
return (
{
const dispatch = useDispatch();
const [ searchString, setSearchString ] = useState('');
- const openMoreMenu = useCallback(() => dispatch(openDialog(ContextMenuMore)), [ dispatch ]);
+ const openMoreMenu = useCallback(() => dispatch(openSheet(ContextMenuMore)), [ dispatch ]);
const isLocalModerator = useSelector(isLocalParticipantModerator);
const muteAll = useCallback(() => dispatch(openDialog(MuteEveryoneDialog)),
[ dispatch ]);
diff --git a/react/features/recent-list/components/RecentList.native.js b/react/features/recent-list/components/RecentList.native.js
index 9dd36a9c4..c43b49e46 100644
--- a/react/features/recent-list/components/RecentList.native.js
+++ b/react/features/recent-list/components/RecentList.native.js
@@ -1,11 +1,9 @@
-// @flow
-
import React from 'react';
import { TouchableWithoutFeedback, View } from 'react-native';
import type { Dispatch } from 'redux';
import { getDefaultURL } from '../../app/functions';
-import { openDialog } from '../../base/dialog/actions';
+import { openSheet } from '../../base/dialog/actions';
import { translate } from '../../base/i18n';
import { NavigateSectionList, type Section } from '../../base/react';
import { connect } from '../../base/redux';
@@ -56,9 +54,6 @@ type Props = {
*
*/
class RecentList extends AbstractRecentList {
- _getRenderListEmptyComponent: () => React$Node;
- _onPress: string => {};
-
/**
* Initializes a new {@code RecentList} instance.
*
@@ -105,8 +100,6 @@ class RecentList extends AbstractRecentList {
);
}
- _onLongPress: (Object) => void;
-
/**
* Handles the list's navigate action.
*
@@ -115,7 +108,7 @@ class RecentList extends AbstractRecentList {
* @returns {void}
*/
_onLongPress(item) {
- this.props.dispatch(openDialog(RecentListItemMenu, { item }));
+ this.props.dispatch(openSheet(RecentListItemMenu, { item }));
}
}
diff --git a/react/features/recent-list/components/RecentListItemMenu.native.js b/react/features/recent-list/components/RecentListItemMenu.native.js
index 6d1d65c2d..fe2ab330a 100644
--- a/react/features/recent-list/components/RecentListItemMenu.native.js
+++ b/react/features/recent-list/components/RecentListItemMenu.native.js
@@ -1,9 +1,7 @@
-// @flow
-
import React, { PureComponent } from 'react';
import { Text, View } from 'react-native';
-import { BottomSheet, hideDialog, isDialogOpen } from '../../base/dialog';
+import { BottomSheet, hideSheet } from '../../base/dialog';
import { bottomSheetStyles } from '../../base/dialog/components/native/styles';
import { type Item } from '../../base/react/Types';
import { connect } from '../../base/redux';
@@ -22,17 +20,9 @@ type Props = {
/**
* Item being rendered in this menu.
*/
- item: Item,
-
- /**
- * True if the menu is currently open, false otherwise.
- */
- _isOpen: boolean
+ item: Item
}
-// eslint-disable-next-line prefer-const
-let RecentListItemMenu_;
-
/**
* Class to implement a popup menu that opens upon long pressing a recent list item.
*/
@@ -65,7 +55,6 @@ class RecentListItemMenu extends PureComponent {
return (
@@ -73,8 +62,6 @@ class RecentListItemMenu extends PureComponent {
);
}
- _onCancel: () => boolean;
-
/**
* Callback to hide this menu.
*
@@ -82,17 +69,9 @@ class RecentListItemMenu extends PureComponent {
* @returns {boolean}
*/
_onCancel() {
- if (this.props._isOpen) {
- this.props.dispatch(hideDialog(RecentListItemMenu_));
-
- return true;
- }
-
- return false;
+ this.props.dispatch(hideSheet());
}
- _renderMenuHeader: () => React$Element;
-
/**
* Function to render the menu's header.
*
@@ -118,19 +97,4 @@ class RecentListItemMenu extends PureComponent {
}
}
-/**
- * Function that maps parts of Redux state tree into component props.
- *
- * @param {Object} state - Redux state.
- * @private
- * @returns {Props}
- */
-function _mapStateToProps(state) {
- return {
- _isOpen: isDialogOpen(state, RecentListItemMenu_)
- };
-}
-
-RecentListItemMenu_ = connect(_mapStateToProps)(RecentListItemMenu);
-
-export default RecentListItemMenu_;
+export default connect()(RecentListItemMenu);
diff --git a/react/features/recording/actions.native.js b/react/features/recording/actions.native.js
index e1a02cd2e..2338565ee 100644
--- a/react/features/recording/actions.native.js
+++ b/react/features/recording/actions.native.js
@@ -1,6 +1,4 @@
-// @flow
-
-import { openDialog } from '../base/dialog';
+import { openSheet } from '../base/dialog';
import JitsiMeetJS from '../base/lib-jitsi-meet';
import { NOTIFICATION_TIMEOUT_TYPE, showNotification } from '../notifications';
@@ -15,7 +13,7 @@ export * from './actions.any';
*/
export function openHighlightDialog() {
return (dispatch: Function) => {
- dispatch(openDialog(HighlightDialog));
+ dispatch(openSheet(HighlightDialog));
};
}
diff --git a/react/features/recording/components/Recording/native/HighlightDialog.js b/react/features/recording/components/Recording/native/HighlightDialog.js
index 2384d1fd5..99679300b 100644
--- a/react/features/recording/components/Recording/native/HighlightDialog.js
+++ b/react/features/recording/components/Recording/native/HighlightDialog.js
@@ -1,27 +1,26 @@
-// @flow
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { Text, View } from 'react-native';
import { Button } from 'react-native-paper';
import { useDispatch, batch } from 'react-redux';
-import { hideDialog, BottomSheet } from '../../../../base/dialog';
+import { BottomSheet, hideSheet } from '../../../../base/dialog';
import { highlightMeetingMoment } from '../../../actions.any';
import styles from '../styles.native';
const HighlightDialog = () => {
const dispatch = useDispatch();
const { t } = useTranslation();
- const closeDialog = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
+ const closeDialog = useCallback(() => dispatch(hideSheet()), [ dispatch ]);
const highlightMoment = useCallback(() => {
batch(() => {
dispatch(highlightMeetingMoment());
- dispatch(hideDialog());
+ dispatch(hideSheet());
});
}, [ dispatch ]);
return (
-
+
{ `${t('recording.highlightMoment')}?` }
diff --git a/react/features/toolbox/components/native/OverflowMenu.js b/react/features/toolbox/components/native/OverflowMenu.js
index 8db04d9d6..9153dd7ad 100644
--- a/react/features/toolbox/components/native/OverflowMenu.js
+++ b/react/features/toolbox/components/native/OverflowMenu.js
@@ -3,7 +3,7 @@
import React, { PureComponent } from 'react';
import { Divider } from 'react-native-paper';
-import { BottomSheet, hideDialog, isDialogOpen } from '../../../base/dialog';
+import { BottomSheet, hideSheet } from '../../../base/dialog';
import { bottomSheetStyles } from '../../../base/dialog/components/native/styles';
import { connect } from '../../../base/redux';
import { SharedDocumentButton } from '../../../etherpad';
@@ -73,15 +73,6 @@ type State = {
scrolledToTop: boolean
}
-/**
- * The exported React {@code Component}. We need it to execute
- * {@link hideDialog}.
- *
- * XXX It does not break our coding style rule to not utilize globals for state,
- * because it is merely another name for {@code export}'s {@code default}.
- */
-let OverflowMenu_; // eslint-disable-line prefer-const
-
/**
* Implements a React {@code Component} with some extra actions in addition to
* those in the toolbar.
@@ -139,7 +130,6 @@ class OverflowMenu extends PureComponent {
return (
@@ -167,26 +157,16 @@ class OverflowMenu extends PureComponent {
);
}
- _onCancel: () => boolean;
-
/**
* Hides this {@code OverflowMenu}.
*
* @private
- * @returns {boolean}
+ * @returns {void}
*/
_onCancel() {
- if (this.props._isOpen) {
- this.props.dispatch(hideDialog(OverflowMenu_));
-
- return true;
- }
-
- return false;
+ this.props.dispatch(hideSheet());
}
- _renderReactionMenu: () => React$Element;
-
/**
* Functoin to render the reaction menu as the footer of the bottom sheet.
*
@@ -210,13 +190,10 @@ function _mapStateToProps(state) {
const { disableSelfView } = state['features/base/settings'];
return {
- _isOpen: isDialogOpen(state, OverflowMenu_),
_reactionsEnabled: isReactionsEnabled(state),
_selfViewHidden: Boolean(disableSelfView),
_width: state['features/base/responsive-ui'].clientWidth
};
}
-OverflowMenu_ = connect(_mapStateToProps)(OverflowMenu);
-
-export default OverflowMenu_;
+export default connect(_mapStateToProps)(OverflowMenu);
diff --git a/react/features/toolbox/components/native/OverflowMenuButton.js b/react/features/toolbox/components/native/OverflowMenuButton.js
index 40e02f617..b803556c4 100644
--- a/react/features/toolbox/components/native/OverflowMenuButton.js
+++ b/react/features/toolbox/components/native/OverflowMenuButton.js
@@ -1,6 +1,4 @@
-// @flow
-
-import { openDialog } from '../../../base/dialog';
+import { openSheet } from '../../../base/dialog';
import { getFeatureFlag, OVERFLOW_MENU_ENABLED } from '../../../base/flags';
import { translate } from '../../../base/i18n';
import { IconHorizontalPoints } from '../../../base/icons';
@@ -35,7 +33,7 @@ class OverflowMenuButton extends AbstractButton {
* @returns {void}
*/
_handleClick() {
- this.props.dispatch(openDialog(OverflowMenu));
+ this.props.dispatch(openSheet(OverflowMenu));
}
}
diff --git a/react/features/video-menu/actions.native.js b/react/features/video-menu/actions.native.js
index bf0ac7209..02b37d475 100644
--- a/react/features/video-menu/actions.native.js
+++ b/react/features/video-menu/actions.native.js
@@ -1,33 +1 @@
-// @flow
-import { hideDialog } from '../base/dialog';
-
-import { RemoteVideoMenu, SharedVideoMenu, LocalVideoMenu } from './components/native';
-
-/**
- * Hides the local video menu.
- *
- * @returns {Function}
- */
-export function hideLocalVideoMenu() {
- return hideDialog(LocalVideoMenu);
-}
-
-/**
- * Hides the remote video menu.
- *
- * @returns {Function}
- */
-export function hideRemoteVideoMenu() {
- return hideDialog(RemoteVideoMenu);
-}
-
-/**
- * Hides the shared video menu.
- *
- * @returns {Function}
- */
-export function hideSharedVideoMenu() {
- return hideDialog(SharedVideoMenu);
-}
-
export * from './actions.any';
diff --git a/react/features/video-menu/components/native/ConnectionStatusButton.js b/react/features/video-menu/components/native/ConnectionStatusButton.js
index 3614d5793..851e76ce7 100644
--- a/react/features/video-menu/components/native/ConnectionStatusButton.js
+++ b/react/features/video-menu/components/native/ConnectionStatusButton.js
@@ -1,6 +1,4 @@
-// @flow
-
-import { openDialog } from '../../../base/dialog';
+import { openSheet } from '../../../base/dialog';
import { translate } from '../../../base/i18n';
import { IconInfo } from '../../../base/icons';
import { connect } from '../../../base/redux';
@@ -42,7 +40,7 @@ class ConnectionStatusButton extends AbstractButton {
_handleClick() {
const { dispatch, participantID } = this.props;
- dispatch(openDialog(ConnectionStatusComponent, {
+ dispatch(openSheet(ConnectionStatusComponent, {
participantID
}));
}
diff --git a/react/features/video-menu/components/native/ConnectionStatusComponent.js b/react/features/video-menu/components/native/ConnectionStatusComponent.js
index dd4dc1c8c..8d65980de 100644
--- a/react/features/video-menu/components/native/ConnectionStatusComponent.js
+++ b/react/features/video-menu/components/native/ConnectionStatusComponent.js
@@ -1,13 +1,10 @@
-// @flow
-
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import { withTheme } from 'react-native-paper';
-
import { Avatar } from '../../../base/avatar';
import { getSourceNameSignalingFeatureFlag } from '../../../base/config';
-import { BottomSheet, isDialogOpen, hideDialog } from '../../../base/dialog';
+import { BottomSheet, hideSheet } from '../../../base/dialog';
import { bottomSheetStyles } from '../../../base/dialog/components/native/styles';
import { translate } from '../../../base/i18n';
import { IconArrowDownLarge, IconArrowUpLarge } from '../../../base/icons';
@@ -87,9 +84,6 @@ type State = {
connectionString: string
};
-// eslint-disable-next-line prefer-const
-let ConnectionStatusComponent_;
-
/**
* Class to implement a popup menu that show the connection statistics.
*/
@@ -126,9 +120,9 @@ class ConnectionStatusComponent extends Component {
* Implements React's {@link Component#render()}.
*
* @inheritdoc
- * @returns {React$Node}
+ * @returns {ReactNode}
*/
- render(): React$Node {
+ render() {
const { t, theme } = this.props;
const { palette } = theme;
@@ -402,8 +396,6 @@ class ConnectionStatusComponent extends Component {
}
}
- _onCancel: () => boolean;
-
/**
* Callback to hide the {@code ConnectionStatusComponent}.
*
@@ -419,17 +411,9 @@ class ConnectionStatusComponent extends Component {
this.props._sourceName, this._onStatsUpdated);
}
- if (this.props._isOpen) {
- this.props.dispatch(hideDialog(ConnectionStatusComponent_));
-
- return true;
- }
-
- return false;
+ this.props.dispatch(hideSheet());
}
- _renderMenuHeader: () => React$Element;
-
/**
* Function to render the menu's header.
*
@@ -466,13 +450,10 @@ function _mapStateToProps(state, ownProps) {
const { participantID } = ownProps;
return {
- _isOpen: isDialogOpen(state, ConnectionStatusComponent_),
_participantDisplayName: getParticipantDisplayName(state, participantID),
_sourceNameSignalingEnabled: getSourceNameSignalingFeatureFlag(state),
_sourceName: getSourceNameByParticipantId(state, ownProps.participantId)
};
}
-ConnectionStatusComponent_ = translate(connect(_mapStateToProps)(withTheme(ConnectionStatusComponent)));
-
-export default ConnectionStatusComponent_;
+export default translate(connect(_mapStateToProps)(withTheme(ConnectionStatusComponent)));
diff --git a/react/features/video-menu/components/native/LocalVideoMenu.js b/react/features/video-menu/components/native/LocalVideoMenu.js
index ecd56df30..33347eb8e 100644
--- a/react/features/video-menu/components/native/LocalVideoMenu.js
+++ b/react/features/video-menu/components/native/LocalVideoMenu.js
@@ -1,10 +1,8 @@
-// @flow
-
import React, { PureComponent } from 'react';
import { Text, View } from 'react-native';
import { Avatar } from '../../../base/avatar';
-import { BottomSheet, isDialogOpen } from '../../../base/dialog';
+import { BottomSheet } from '../../../base/dialog';
import { bottomSheetStyles } from '../../../base/dialog/components/native/styles';
import { translate } from '../../../base/i18n';
import {
@@ -13,7 +11,6 @@ import {
} from '../../../base/participants';
import { connect } from '../../../base/redux';
import ToggleSelfViewButton from '../../../toolbox/components/native/ToggleSelfViewButton';
-import { hideLocalVideoMenu } from '../../actions.native';
import ConnectionStatusButton from './ConnectionStatusButton';
import styles from './styles';
@@ -26,11 +23,6 @@ const AVATAR_SIZE = 24;
type Props = {
- /**
- * True if the menu is currently open, false otherwise.
- */
- _isOpen: boolean,
-
/**
* The local participant.
*/
@@ -52,9 +44,6 @@ type Props = {
t: Function
}
-// eslint-disable-next-line prefer-const
-let LocalVideoMenu_;
-
/**
* Class to implement a popup menu that opens upon long pressing a thumbnail.
*/
@@ -67,7 +56,6 @@ class LocalVideoMenu extends PureComponent {
constructor(props: Props) {
super(props);
- this._onCancel = this._onCancel.bind(this);
this._renderMenuHeader = this._renderMenuHeader.bind(this);
}
@@ -79,7 +67,6 @@ class LocalVideoMenu extends PureComponent {
render() {
const { _participant } = this.props;
const buttonProps = {
- afterClick: this._onCancel,
showLabel: true,
participantID: _participant.id,
styles: bottomSheetStyles.buttons
@@ -87,7 +74,6 @@ class LocalVideoMenu extends PureComponent {
return (
@@ -96,26 +82,6 @@ class LocalVideoMenu extends PureComponent {
);
}
- _onCancel: () => boolean;
-
- /**
- * Callback to hide the {@code RemoteVideoMenu}.
- *
- * @private
- * @returns {boolean}
- */
- _onCancel() {
- if (this.props._isOpen) {
- this.props.dispatch(hideLocalVideoMenu());
-
- return true;
- }
-
- return false;
- }
-
- _renderMenuHeader: () => React$Element;
-
/**
* Function to render the menu's header.
*
@@ -151,12 +117,9 @@ function _mapStateToProps(state) {
const participant = getLocalParticipant(state);
return {
- _isOpen: isDialogOpen(state, LocalVideoMenu_),
_participant: participant,
_participantDisplayName: getParticipantDisplayName(state, participant.id)
};
}
-LocalVideoMenu_ = translate(connect(_mapStateToProps)(LocalVideoMenu));
-
-export default LocalVideoMenu_;
+export default translate(connect(_mapStateToProps)(LocalVideoMenu));
diff --git a/react/features/video-menu/components/native/RemoteVideoMenu.js b/react/features/video-menu/components/native/RemoteVideoMenu.js
index e2109458a..5128d9448 100644
--- a/react/features/video-menu/components/native/RemoteVideoMenu.js
+++ b/react/features/video-menu/components/native/RemoteVideoMenu.js
@@ -1,11 +1,9 @@
-// @flow
-
import React, { PureComponent } from 'react';
import { Text, View } from 'react-native';
import { Divider } from 'react-native-paper';
import { Avatar } from '../../../base/avatar';
-import { BottomSheet, isDialogOpen } from '../../../base/dialog';
+import { BottomSheet, hideSheet } from '../../../base/dialog';
import { bottomSheetStyles } from '../../../base/dialog/components/native/styles';
import { KICK_OUT_ENABLED, getFeatureFlag } from '../../../base/flags';
import { translate } from '../../../base/i18n';
@@ -16,7 +14,6 @@ import {
import { connect } from '../../../base/redux';
import { getBreakoutRooms, getCurrentRoomId } from '../../../breakout-rooms/functions';
import PrivateMessageButton from '../../../chat/components/native/PrivateMessageButton';
-import { hideRemoteVideoMenu } from '../../actions.native';
import ConnectionStatusButton from '../native/ConnectionStatusButton';
import AskUnmuteButton from './AskUnmuteButton';
@@ -74,11 +71,6 @@ type Props = {
*/
_disableGrantModerator: Boolean,
- /**
- * True if the menu is currently open, false otherwise.
- */
- _isOpen: boolean,
-
/**
* Whether the participant is present in the room or not.
*/
@@ -100,9 +92,6 @@ type Props = {
t: Function
}
-// eslint-disable-next-line prefer-const
-let RemoteVideoMenu_;
-
/**
* Class to implement a popup menu that opens upon long pressing a thumbnail.
*/
@@ -145,7 +134,6 @@ class RemoteVideoMenu extends PureComponent {
return (
@@ -157,7 +145,9 @@ class RemoteVideoMenu extends PureComponent {
{ !_disableGrantModerator && }
{ !_disablePrivateChat && }
-
+
{_rooms.length > 1 && <>
@@ -175,8 +165,6 @@ class RemoteVideoMenu extends PureComponent {
);
}
- _onCancel: () => boolean;
-
/**
* Callback to hide the {@code RemoteVideoMenu}.
*
@@ -184,17 +172,9 @@ class RemoteVideoMenu extends PureComponent {
* @returns {boolean}
*/
_onCancel() {
- if (this.props._isOpen) {
- this.props.dispatch(hideRemoteVideoMenu());
-
- return true;
- }
-
- return false;
+ this.props.dispatch(hideSheet());
}
- _renderMenuHeader: () => React$Element;
-
/**
* Function to render the menu's header.
*
@@ -242,13 +222,10 @@ function _mapStateToProps(state, ownProps) {
_disableKick: Boolean(shouldDisableKick),
_disableRemoteMute: Boolean(disableRemoteMute),
_disablePrivateChat: Boolean(disablePrivateChat),
- _isOpen: isDialogOpen(state, RemoteVideoMenu_),
_isParticipantAvailable: Boolean(isParticipantAvailable),
_participantDisplayName: getParticipantDisplayName(state, participantId),
_rooms
};
}
-RemoteVideoMenu_ = translate(connect(_mapStateToProps)(RemoteVideoMenu));
-
-export default RemoteVideoMenu_;
+export default translate(connect(_mapStateToProps)(RemoteVideoMenu));
diff --git a/react/features/video-menu/components/native/SharedVideoMenu.js b/react/features/video-menu/components/native/SharedVideoMenu.js
index c6e015d85..18a6cdb7b 100644
--- a/react/features/video-menu/components/native/SharedVideoMenu.js
+++ b/react/features/video-menu/components/native/SharedVideoMenu.js
@@ -5,7 +5,7 @@ import { Text, View } from 'react-native';
import { Divider } from 'react-native-paper';
import { Avatar } from '../../../base/avatar';
-import { BottomSheet, isDialogOpen } from '../../../base/dialog';
+import { BottomSheet, hideSheet } from '../../../base/dialog';
import { bottomSheetStyles } from '../../../base/dialog/components/native/styles';
import {
getParticipantById,
@@ -13,7 +13,6 @@ import {
} from '../../../base/participants';
import { connect } from '../../../base/redux';
import { SharedVideoButton } from '../../../shared-video/components';
-import { hideSharedVideoMenu } from '../../actions.native';
import styles from './styles';
@@ -51,9 +50,6 @@ type Props = {
_participantDisplayName: string,
}
-// eslint-disable-next-line prefer-const
-let SharedVideoMenu_;
-
/**
* Class to implement a popup menu that opens upon long pressing a fake participant thumbnail.
*/
@@ -90,7 +86,6 @@ class SharedVideoMenu extends PureComponent {
return (
@@ -99,8 +94,6 @@ class SharedVideoMenu extends PureComponent {
);
}
- _onCancel: () => boolean;
-
/**
* Callback to hide the {@code SharedVideoMenu}.
*
@@ -108,17 +101,9 @@ class SharedVideoMenu extends PureComponent {
* @returns {boolean}
*/
_onCancel() {
- if (this.props._isOpen) {
- this.props.dispatch(hideSharedVideoMenu());
-
- return true;
- }
-
- return false;
+ this.props.dispatch(hideSheet());
}
- _renderMenuHeader: () => React$Element;
-
/**
* Function to render the menu's header.
*
@@ -156,12 +141,9 @@ function _mapStateToProps(state, ownProps) {
const isParticipantAvailable = getParticipantById(state, participantId);
return {
- _isOpen: isDialogOpen(state, SharedVideoMenu_),
_isParticipantAvailable: Boolean(isParticipantAvailable),
_participantDisplayName: getParticipantDisplayName(state, participantId)
};
}
-SharedVideoMenu_ = connect(_mapStateToProps)(SharedVideoMenu);
-
-export default SharedVideoMenu_;
+export default connect(_mapStateToProps)(SharedVideoMenu);