From 3e004811e087f5fab07422de01aaaaa23669a767 Mon Sep 17 00:00:00 2001 From: Calin Chitu Date: Tue, 26 Apr 2022 13:15:31 +0300 Subject: [PATCH] feat(lobby/native) LobbyScreen and LobbyChatScreen --- .../base/modal/components/JitsiScreen.js | 12 +- .../components/native/Conference.js | 2 +- .../components/native/LobbyChatScreen.js | 42 +++ .../lobby/components/native/LobbyScreen.js | 264 ++++++++++-------- .../features/lobby/components/native/index.js | 1 + .../lobby/components/native/styles.js | 156 ++++++++--- .../components/RootNavigationContainer.js | 2 - .../ConferenceNavigationContainerRef.js | 6 - .../ConferenceNavigationContainer.js | 15 +- .../lobby/LobbyNavigationContainerRef.js | 23 ++ .../components/LobbyNavigationContainer.js | 47 ++++ react/features/mobile/navigation/functions.js | 31 ++ .../features/mobile/navigation/middleware.js | 36 ++- react/features/mobile/navigation/routes.js | 6 +- .../mobile/navigation/screenOptions.js | 67 ++--- 15 files changed, 485 insertions(+), 225 deletions(-) create mode 100644 react/features/lobby/components/native/LobbyChatScreen.js create mode 100644 react/features/mobile/navigation/components/lobby/LobbyNavigationContainerRef.js create mode 100644 react/features/mobile/navigation/components/lobby/components/LobbyNavigationContainer.js create mode 100644 react/features/mobile/navigation/functions.js diff --git a/react/features/base/modal/components/JitsiScreen.js b/react/features/base/modal/components/JitsiScreen.js index 256481185..b8b589432 100644 --- a/react/features/base/modal/components/JitsiScreen.js +++ b/react/features/base/modal/components/JitsiScreen.js @@ -37,6 +37,11 @@ type Props = { */ hasTabNavigator?: boolean, + /** + * Insets for the SafeAreaView. + */ + safeAreaInsets?: Array, + /** * Additional style to be appended to the KeyboardAvoidingView containing the content of the modal. */ @@ -49,6 +54,7 @@ const JitsiScreen = ({ footerComponent, hasTabNavigator = false, hasBottomTextInput = false, + safeAreaInsets = [ 'bottom', 'left', 'right' ], style }: Props) => ( { children } diff --git a/react/features/conference/components/native/Conference.js b/react/features/conference/components/native/Conference.js index ab701ea21..09a082d12 100644 --- a/react/features/conference/components/native/Conference.js +++ b/react/features/conference/components/native/Conference.js @@ -183,7 +183,7 @@ class Conference extends AbstractConference { const { _showLobby } = this.props; if (!prevProps._showLobby && _showLobby) { - navigate(screen.lobby); + navigate(screen.lobby.root); } if (prevProps._showLobby && !_showLobby) { diff --git a/react/features/lobby/components/native/LobbyChatScreen.js b/react/features/lobby/components/native/LobbyChatScreen.js new file mode 100644 index 000000000..739b66ae7 --- /dev/null +++ b/react/features/lobby/components/native/LobbyChatScreen.js @@ -0,0 +1,42 @@ +import React from 'react'; + +import { translate } from '../../../base/i18n'; +import JitsiScreen from '../../../base/modal/components/JitsiScreen'; +import { connect } from '../../../base/redux'; +import ChatInputBar from '../../../chat/components/native/ChatInputBar'; +import MessageContainer from '../../../chat/components/native/MessageContainer'; +import AbstractLobbyScreen, { + Props as AbstractProps, + _mapStateToProps as abstractMapStateToProps +} from '../AbstractLobbyScreen'; + +import styles from './styles'; + + +/** + * Implements a chat screen that appears when communication is started + * between the moderator and the participant being in the lobby. + */ +class LobbyChatScreen extends + AbstractLobbyScreen { + /** + * Implements React's {@link Component#render()}. + * + * @inheritdoc + * @returns {ReactElement} + */ + render() { + const { _lobbyChatMessages } = this.props; + + return ( + + + + + ); + } + + _onSendMessage: () => void; +} + +export default translate(connect(abstractMapStateToProps)(LobbyChatScreen)); diff --git a/react/features/lobby/components/native/LobbyScreen.js b/react/features/lobby/components/native/LobbyScreen.js index 31929bcab..db1db4e31 100644 --- a/react/features/lobby/components/native/LobbyScreen.js +++ b/react/features/lobby/components/native/LobbyScreen.js @@ -2,50 +2,50 @@ import React from 'react'; import { Text, View, TouchableOpacity, TextInput } from 'react-native'; -import { SafeAreaView } from 'react-native-safe-area-context'; -import { Avatar } from '../../../base/avatar'; import { translate } from '../../../base/i18n'; -import { Icon, IconClose, IconEdit } from '../../../base/icons'; import JitsiScreen from '../../../base/modal/components/JitsiScreen'; import { LoadingIndicator } from '../../../base/react'; import { connect } from '../../../base/redux'; -import ChatInputBar from '../../../chat/components/native/ChatInputBar'; -import MessageContainer from '../../../chat/components/native/MessageContainer'; -import AbstractLobbyScreen, { _mapStateToProps } from '../AbstractLobbyScreen'; +import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui'; +import BaseTheme from '../../../base/ui/components/BaseTheme'; +import InviteButton + from '../../../invite/components/add-people-dialog/native/InviteButton'; +import { LargeVideo } from '../../../large-video/components'; +import { navigate } + from '../../../mobile/navigation/components/lobby/LobbyNavigationContainerRef'; +import { screen } from '../../../mobile/navigation/routes'; +import AudioMuteButton from '../../../toolbox/components/AudioMuteButton'; +import VideoMuteButton from '../../../toolbox/components/VideoMuteButton'; +import AbstractLobbyScreen, { + Props as AbstractProps, + _mapStateToProps as abstractMapStateToProps } from '../AbstractLobbyScreen'; import styles from './styles'; + +type Props = AbstractProps & { + + /** + * The current aspect ratio of the screen. + */ + _aspectRatio: Symbol +} + /** * Implements a waiting screen that represents the participant being in the lobby. */ -class LobbyScreen extends AbstractLobbyScreen { +class LobbyScreen extends AbstractLobbyScreen { /** * Implements {@code PureComponent#render}. * * @inheritdoc */ render() { - const { _meetingName, t } = this.props; - return ( - - {this.props._isLobbyChatActive && this.state.isChatOpen - ? this._renderLobbyChat() - : - - { t(this._getScreenTitleKey(), { moderator: this.props._lobbyMessageRecipient }) } - - - - { _meetingName } - - { this._renderContent()} - } - + <> + { this._renderLobby() } + ); } @@ -69,35 +69,58 @@ class LobbyScreen extends AbstractLobbyScreen { _onSwitchToPasswordMode: () => void; - _onSendMessage: () => void; - - _onToggleChat: () => void; - _renderContent: () => React$Element<*>; + _renderToolbarButtons: () => React$Element<*>; + + _renderLobby: () => React$Element<*>; + + _onNavigateToLobbyChat: () => void; + /** - * Renders the lobby chat. + * Navigates to the lobby chat screen. + * + * @private + * @returns {void} + */ + _onNavigateToLobbyChat() { + navigate(screen.lobby.chat); + } + + /** + * Renders the lobby. * * @inheritdoc */ - _renderLobbyChat() { - const { t } = this.props; + _renderLobby() { + const { _aspectRatio } = this.props; + let contentStyles; + let largeVideoContainerStyles; + let contentContainerStyles; + + if (_aspectRatio === ASPECT_RATIO_NARROW) { + largeVideoContainerStyles = styles.largeVideoContainer; + contentContainerStyles = styles.contentContainer; + } else { + contentStyles = styles.contentWide; + largeVideoContainerStyles = styles.largeVideoContainerWide; + contentContainerStyles = styles.contentContainerWide; + } return ( - <> - - - { t(this._getScreenTitleKey(), { moderator: this.props._lobbyMessageRecipient }) } - - - - + + + + + + + { this._renderContent() } + { this._renderToolbarButtons() } + - - - + ); } @@ -108,15 +131,15 @@ class LobbyScreen extends AbstractLobbyScreen { */ _renderJoining() { return ( - <> + { this.props.t('lobby.joiningMessage') } { this._renderStandardButtons() } - + ); } @@ -127,7 +150,7 @@ class LobbyScreen extends AbstractLobbyScreen { */ _renderParticipantForm() { const { t } = this.props; - const { displayName, email } = this.state; + const { displayName } = this.state; return ( @@ -138,13 +161,6 @@ class LobbyScreen extends AbstractLobbyScreen { onChangeText = { this._onChangeDisplayName } style = { styles.field } value = { displayName } /> - - { t('lobby.emailField') } - - ); } @@ -155,28 +171,7 @@ class LobbyScreen extends AbstractLobbyScreen { * @inheritdoc */ _renderParticipantInfo() { - const { displayName, email } = this.state; - - return ( - - - - - - - { displayName } - - { Boolean(email) && - { email } - } - - ); + return this._renderParticipantForm(); } /** @@ -215,7 +210,17 @@ class LobbyScreen extends AbstractLobbyScreen { const { t } = this.props; return ( - <> + + + + { t('lobby.backToKnockModeButton') } + + - - - { t('lobby.backToKnockModeButton') } - - - + + ); + } + + /** + * Renders the toolbar buttons menu. + * + * @inheritdoc + */ + _renderToolbarButtons() { + const { _aspectRatio } = this.props; + let toolboxContainerStyles; + + if (_aspectRatio === ASPECT_RATIO_NARROW) { + toolboxContainerStyles = styles.toolboxContainer; + } else { + toolboxContainerStyles = styles.toolboxContainerWide; + } + + return ( + + + + + ); } @@ -248,50 +270,72 @@ class LobbyScreen extends AbstractLobbyScreen { */ _renderStandardButtons() { const { _knocking, _renderPassword, _isLobbyChatActive, t } = this.props; + const { displayName } = this.state; + const askToJoinButtonStyles + = displayName ? styles.primaryButton : styles.primaryButtonDisabled; return ( - <> - { _knocking || + { _knocking && _isLobbyChatActive && - { t('lobby.knockButton') } - - } - { _knocking && _isLobbyChatActive && - { t('toolbar.openChat') } } + { _knocking || + + { t('lobby.knockButton') } + + } { _renderPassword && - + { t('lobby.enterPasswordButton') } } - + style = { [ + styles.button, + styles.cancelButton + ] }> + { t('dialog.Cancel') } - + ); } } +/** + * Maps part of the Redux state to the props of this component. + * + * @param {Object} state - The Redux state. + * @param {Props} ownProps - The own props of the component. + * @returns {{ + * _aspectRatio: Symbol + * }} + */ +function _mapStateToProps(state: Object, ownProps: Props) { + return { + ...abstractMapStateToProps(state, ownProps), + _aspectRatio: state['features/base/responsive-ui'].aspectRatio + }; +} + export default translate(connect(_mapStateToProps)(LobbyScreen)); diff --git a/react/features/lobby/components/native/index.js b/react/features/lobby/components/native/index.js index 1cbb0c0e2..5e6b17861 100644 --- a/react/features/lobby/components/native/index.js +++ b/react/features/lobby/components/native/index.js @@ -2,3 +2,4 @@ export { default as KnockingParticipantList } from './KnockingParticipantList'; export { default as LobbyScreen } from './LobbyScreen'; +export { default as LobbyChatScreen } from './LobbyChatScreen'; diff --git a/react/features/lobby/components/native/styles.js b/react/features/lobby/components/native/styles.js index 70129ecac..c1055a679 100644 --- a/react/features/lobby/components/native/styles.js +++ b/react/features/lobby/components/native/styles.js @@ -1,6 +1,6 @@ // @flow -import BaseTheme from '../../../base/ui/components/BaseTheme'; +import BaseTheme from '../../../base/ui/components/BaseTheme.native'; const SECONDARY_COLOR = BaseTheme.palette.border04; @@ -8,8 +8,24 @@ export default { button: { alignItems: 'center', borderRadius: 4, - marginVertical: BaseTheme.spacing[1], - paddingVertical: BaseTheme.spacing[2] + padding: BaseTheme.spacing[2], + width: '100%' + }, + + buttonStylesBorderless: { + iconStyle: { + backgroundColor: BaseTheme.palette.action02Active, + color: BaseTheme.palette.icon01, + fontSize: 24 + }, + style: { + backgroundColor: BaseTheme.palette.action02Active, + flexDirection: 'row', + justifyContent: 'center', + marginHorizontal: BaseTheme.spacing[3], + height: 24, + width: 24 + } }, lobbyChatWrapper: { @@ -26,29 +42,66 @@ export default { }, lobbyChatTitle: { - color: '#fff', + color: BaseTheme.palette.text01, fontSize: 20, fontWeight: 'bold', flexShrink: 1 }, lobbyChatCloseButton: { - fontSize: 20, - marginLeft: 20, - color: '#fff' + fontSize: 24, + marginLeft: BaseTheme.spacing[3], + marginTop: BaseTheme.spacing[1], + color: BaseTheme.palette.icon01 }, contentWrapper: { - alignItems: 'center', - display: 'flex', - flexDirection: 'column', - justifyItems: 'center', - height: '100%' + backgroundColor: BaseTheme.palette.ui02, + flex: 1 }, - closeIcon: { - color: 'red', - fontSize: 20 + contentWide: { + backgroundColor: BaseTheme.palette.ui02, + flex: 1, + flexDirection: 'row' + }, + + largeVideoContainer: { + alignItems: 'center', + display: 'flex', + justifyContent: 'center', + minHeight: '50%' + }, + + largeVideoContainerWide: { + height: '100%', + width: '50%' + }, + + contentContainer: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center' + }, + + contentContainerWide: { + justifyContent: 'center', + marginHorizontal: BaseTheme.spacing[2], + width: '50%' + }, + + toolboxContainer: { + alignItems: 'center', + display: 'flex', + flexDirection: 'row', + justifyContent: 'center', + marginTop: BaseTheme.spacing[4] + }, + + toolboxContainerWide: { + flexDirection: 'row', + justifyContent: 'center', + marginTop: BaseTheme.spacing[4] }, dialogTitle: { @@ -75,40 +128,55 @@ export default { }, field: { + backgroundColor: BaseTheme.palette.field02, borderColor: SECONDARY_COLOR, - borderRadius: 4, - borderWidth: 1, - marginVertical: 8, - padding: 8 + borderRadius: BaseTheme.shape.borderRadius, + borderWidth: 2, + marginHorizontal: BaseTheme.spacing[3], + padding: BaseTheme.spacing[2] }, fieldError: { - color: BaseTheme.palette.warning07, - fontSize: 10 - }, - - fieldRow: { - paddingTop: 16 + color: BaseTheme.palette.warning03, + marginLeft: BaseTheme.spacing[3], + fontSize: 16 }, fieldLabel: { + color: BaseTheme.palette.text01, + marginVertical: BaseTheme.spacing[4], textAlign: 'center' }, formWrapper: { - alignItems: 'stretch', + alignSelf: 'stretch' + }, + + standardButtonWrapper: { alignSelf: 'stretch', - paddingVertical: 16 + marginHorizontal: BaseTheme.spacing[3] + }, + + joiningContainer: { + alignItems: 'center', + display: 'flex', + justifyContent: 'center' }, joiningMessage: { - color: 'rgba(0, 0, 0, .7)', - paddingBottom: 36, + color: BaseTheme.palette.text01, + marginBottom: BaseTheme.spacing[2], textAlign: 'center' }, + passwordJoinButtonsWrapper: { + alignItems: 'stretch', + alignSelf: 'stretch', + marginHorizontal: BaseTheme.spacing[3] + }, + loadingIndicator: { - marginVertical: 36 + marginVertical: BaseTheme.spacing[4] }, participantBox: { @@ -122,29 +190,33 @@ export default { }, primaryButton: { - alignSelf: 'stretch', - backgroundColor: 'rgb(3, 118, 218)' + backgroundColor: BaseTheme.palette.action01, + marginTop: BaseTheme.spacing[4] + }, + + primaryButtonDisabled: { + backgroundColor: BaseTheme.palette.action03Disabled, + marginTop: BaseTheme.spacing[4] }, primaryButtonText: { - color: 'white' + color: BaseTheme.palette.text01 }, - secondaryButton: { - alignSelf: 'stretch', - backgroundColor: 'transparent' - }, - - secondaryText: { - color: 'rgba(0, 0, 0, .7)', + primaryText: { + color: BaseTheme.palette.text01, margin: 'auto', textAlign: 'center' }, cancelButton: { alignItems: 'center', - backgroundColor: 'transparent', - marginVertical: 4 + backgroundColor: BaseTheme.palette.action02Disabled, + marginTop: BaseTheme.spacing[4] + }, + + cancelButtonText: { + color: BaseTheme.palette.text01 }, // KnockingParticipantList diff --git a/react/features/mobile/navigation/components/RootNavigationContainer.js b/react/features/mobile/navigation/components/RootNavigationContainer.js index 0c82069df..f70179de8 100644 --- a/react/features/mobile/navigation/components/RootNavigationContainer.js +++ b/react/features/mobile/navigation/components/RootNavigationContainer.js @@ -1,5 +1,3 @@ -// @flow - import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import React from 'react'; diff --git a/react/features/mobile/navigation/components/conference/ConferenceNavigationContainerRef.js b/react/features/mobile/navigation/components/conference/ConferenceNavigationContainerRef.js index f01db0869..892da4851 100644 --- a/react/features/mobile/navigation/components/conference/ConferenceNavigationContainerRef.js +++ b/react/features/mobile/navigation/components/conference/ConferenceNavigationContainerRef.js @@ -1,8 +1,5 @@ -// @flow - import React from 'react'; -// $FlowExpectedError export const conferenceNavigationRef = React.createRef(); /** @@ -13,7 +10,6 @@ export const conferenceNavigationRef = React.createRef(); * @returns {Function} */ export function navigate(name: string, params: Object) { - // $FlowExpectedError return conferenceNavigationRef.current?.navigate(name, params); } @@ -23,7 +19,6 @@ export function navigate(name: string, params: Object) { * @returns {Function} */ export function goBack() { - // $FlowExpectedError return conferenceNavigationRef.current?.goBack(); } @@ -34,7 +29,6 @@ export function goBack() { * @returns {Function} */ export function setParams(params: Object) { - // $FlowExpectedError return conferenceNavigationRef.current?.setParams(params); } diff --git a/react/features/mobile/navigation/components/conference/components/ConferenceNavigationContainer.js b/react/features/mobile/navigation/components/conference/components/ConferenceNavigationContainer.js index d27d8e064..dffba8485 100644 --- a/react/features/mobile/navigation/components/conference/components/ConferenceNavigationContainer.js +++ b/react/features/mobile/navigation/components/conference/components/ConferenceNavigationContainer.js @@ -1,5 +1,3 @@ -// @flow - import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import React from 'react'; @@ -13,7 +11,6 @@ import { SharedDocument } from '../../../../../etherpad'; import { GifsMenu } from '../../../../../gifs/components'; import AddPeopleDialog from '../../../../../invite/components/add-people-dialog/native/AddPeopleDialog'; -import LobbyScreen from '../../../../../lobby/components/native/LobbyScreen'; import { ParticipantsPane } from '../../../../../participants-pane/components/native'; import { StartLiveStreamDialog } from '../../../../../recording'; import { StartRecordingDialog } @@ -31,7 +28,6 @@ import { gifsMenuOptions, inviteScreenOptions, liveStreamScreenOptions, - lobbyScreenOptions, navigationContainerTheme, participantsScreenOptions, recordingScreenOptions, @@ -42,6 +38,8 @@ import { } from '../../../screenOptions'; import ChatAndPollsNavigationContainer from '../../chat/components/ChatAndPollsNavigationContainer'; +import LobbyNavigationContainer + from '../../lobby/components/LobbyNavigationContainer'; import { conferenceNavigationRef } from '../ConferenceNavigationContainerRef'; @@ -134,9 +132,12 @@ const ConferenceNavigationContainer = () => { title: t('notify.gifsMenu') }} /> + component = { LobbyNavigationContainer } + name = { screen.lobby.root } + options = {{ + gestureEnabled: false, + headerShown: false + }} /> { + const { isLobbyChatActive } + = useSelector(state => state['features/chat']); + + return ( + + + + { + isLobbyChatActive + && + } + + + ); + +}; + +export default LobbyNavigationContainer; diff --git a/react/features/mobile/navigation/functions.js b/react/features/mobile/navigation/functions.js new file mode 100644 index 000000000..ff9d78665 --- /dev/null +++ b/react/features/mobile/navigation/functions.js @@ -0,0 +1,31 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { Platform } from 'react-native'; + +import { IconClose } from '../../base/icons'; + +import HeaderNavigationButton from './components/HeaderNavigationButton'; + +/** + * Close icon/text button based on platform. + * + * @param {Function} goBack - Goes back to the previous screen function. + * @returns {React.Component} + */ +export function screenHeaderCloseButton(goBack: Function) { + const { t } = useTranslation(); + + if (Platform.OS === 'ios') { + return ( + + ); + } + + return ( + + ); +} diff --git a/react/features/mobile/navigation/middleware.js b/react/features/mobile/navigation/middleware.js index 2050bb35c..1e2cc17a6 100644 --- a/react/features/mobile/navigation/middleware.js +++ b/react/features/mobile/navigation/middleware.js @@ -1,8 +1,7 @@ -// @flow - import debounce from 'lodash/debounce'; -import { SET_ROOM } from '../../base/conference/actionTypes'; +import { CONFERENCE_FAILED, SET_ROOM } from '../../base/conference/actionTypes'; +import { JitsiConferenceErrors } from '../../base/lib-jitsi-meet'; import { MiddlewareRegistry } from '../../base/redux'; import { readyToClose } from '../external-api/actions'; @@ -16,6 +15,9 @@ MiddlewareRegistry.register(store => next => action => { switch (action.type) { case SET_ROOM: return _setRoom(store, next, action); + + case CONFERENCE_FAILED: + return _conferenceFailed(store, next, action); } return next(action); @@ -61,3 +63,31 @@ function _setRoom({ dispatch, getState }, next, action) { return result; } + +/** + * Function to handle the conference failed event and navigate the user to the lobby screen + * based on the failure reason. + * + * @param {Object} store - The Redux store. + * @param {Function} next - The Redux next function. + * @param {Object} action - The Redux action. + * @returns {Object} + */ +function _conferenceFailed({ dispatch, getState }, next, action) { + const state = getState(); + const isWelcomePageEnabled = isWelcomePageAppEnabled(state); + const { error } = action; + + // We need to cover the case where knocking participant + // is rejected from entering the conference + if (error.name === JitsiConferenceErrors.CONFERENCE_ACCESS_DENIED) { + if (isWelcomePageEnabled) { + navigateRoot(screen.root); + } else { + // For JitsiSDK, WelcomePage is not available + _sendReadyToClose(dispatch); + } + } + + return next(action); +} diff --git a/react/features/mobile/navigation/routes.js b/react/features/mobile/navigation/routes.js index a3252bbde..139a3c5ca 100644 --- a/react/features/mobile/navigation/routes.js +++ b/react/features/mobile/navigation/routes.js @@ -34,5 +34,9 @@ export const screen = { invite: 'Invite', sharedDocument: 'Shared document' }, - lobby: 'Lobby' + lobby: { + root: 'Lobby root', + main: 'Lobby', + chat: 'Lobby chat' + } }; diff --git a/react/features/mobile/navigation/screenOptions.js b/react/features/mobile/navigation/screenOptions.js index 6280f8a81..183544928 100644 --- a/react/features/mobile/navigation/screenOptions.js +++ b/react/features/mobile/navigation/screenOptions.js @@ -1,13 +1,9 @@ -// @flow - import { TransitionPresets } from '@react-navigation/stack'; import React from 'react'; -import { useTranslation } from 'react-i18next'; import { Platform } from 'react-native'; import { Icon, - IconClose, IconHelp, IconHome, IconInfo, @@ -15,8 +11,9 @@ import { } from '../../base/icons'; import BaseTheme from '../../base/ui/components/BaseTheme.native'; -import HeaderNavigationButton from './components/HeaderNavigationButton'; import { goBack } from './components/conference/ConferenceNavigationContainerRef'; +import { goBack as goBackToLobbyScreen } from './components/lobby/LobbyNavigationContainerRef'; +import { screenHeaderCloseButton } from './functions'; /** @@ -167,16 +164,12 @@ export const helpScreenOptions = { /** * Screen options for conference. */ -export const conferenceScreenOptions = { - ...fullScreenOptions -}; +export const conferenceScreenOptions = fullScreenOptions; /** * Screen options for lobby modal. */ -export const lobbyScreenOptions = { - ...fullScreenOptions -}; +export const lobbyScreenOptions = fullScreenOptions; /** * Tab bar options for chat screen. @@ -198,23 +191,7 @@ export const chatTabBarOptions = { export const presentationScreenOptions = { ...conferenceModalPresentation, headerBackTitleVisible: false, - headerLeft: () => { - const { t } = useTranslation(); - - if (Platform.OS === 'ios') { - return ( - - ); - } - - return ( - - ); - }, + headerLeft: () => screenHeaderCloseButton(goBack), headerStatusBarHeight: 0, headerStyle: { backgroundColor: BaseTheme.palette.screen01Header @@ -227,50 +204,44 @@ export const presentationScreenOptions = { /** * Screen options for chat. */ -export const chatScreenOptions = { - ...presentationScreenOptions -}; +export const chatScreenOptions = presentationScreenOptions; /** * Screen options for invite modal. */ -export const inviteScreenOptions = { - ...presentationScreenOptions -}; +export const inviteScreenOptions = presentationScreenOptions; /** * Screen options for participants modal. */ -export const participantsScreenOptions = { - ...presentationScreenOptions -}; +export const participantsScreenOptions = presentationScreenOptions; /** * Screen options for speaker stats modal. */ -export const speakerStatsScreenOptions = { - ...presentationScreenOptions -}; +export const speakerStatsScreenOptions = presentationScreenOptions; /** * Screen options for security options modal. */ -export const securityScreenOptions = { - ...presentationScreenOptions -}; +export const securityScreenOptions = presentationScreenOptions; /** * Screen options for recording modal. */ -export const recordingScreenOptions = { - ...presentationScreenOptions -}; +export const recordingScreenOptions = presentationScreenOptions; /** * Screen options for live stream modal. */ -export const liveStreamScreenOptions = { - ...presentationScreenOptions +export const liveStreamScreenOptions = presentationScreenOptions; + +/** + * Screen options for lobby chat modal. + */ +export const lobbyChatScreenOptions = { + ...presentationScreenOptions, + headerLeft: () => screenHeaderCloseButton(goBackToLobbyScreen) }; /**