|
|
|
@ -1,5 +1,3 @@ |
|
|
|
|
// @flow
|
|
|
|
|
|
|
|
|
|
import { useIsFocused } from '@react-navigation/native'; |
|
|
|
|
import React, { useEffect } from 'react'; |
|
|
|
|
import { |
|
|
|
@ -8,12 +6,14 @@ import { |
|
|
|
|
Platform, |
|
|
|
|
SafeAreaView, |
|
|
|
|
StatusBar, |
|
|
|
|
View |
|
|
|
|
View, |
|
|
|
|
ViewStyle |
|
|
|
|
} from 'react-native'; |
|
|
|
|
import { withSafeAreaInsets } from 'react-native-safe-area-context'; |
|
|
|
|
import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context'; |
|
|
|
|
import { connect } from 'react-redux'; |
|
|
|
|
|
|
|
|
|
import { appNavigate } from '../../../app/actions'; |
|
|
|
|
import { IReduxState } from '../../../app/types'; |
|
|
|
|
import { FULLSCREEN_ENABLED, PIP_ENABLED } from '../../../base/flags/constants'; |
|
|
|
|
import { getFeatureFlag } from '../../../base/flags/functions'; |
|
|
|
|
import { getParticipantCount } from '../../../base/participants/functions'; |
|
|
|
@ -24,6 +24,7 @@ import { |
|
|
|
|
ASPECT_RATIO_NARROW, |
|
|
|
|
ASPECT_RATIO_WIDE |
|
|
|
|
} from '../../../base/responsive-ui/constants'; |
|
|
|
|
import { StyleType } from '../../../base/styles/functions.any'; |
|
|
|
|
import TestConnectionInfo from '../../../base/testing/components/TestConnectionInfo'; |
|
|
|
|
import { isCalendarEnabled } from '../../../calendar-sync/functions.native'; |
|
|
|
|
import DisplayNameLabel from '../../../display-name/components/native/DisplayNameLabel'; |
|
|
|
@ -63,27 +64,27 @@ import styles from './styles'; |
|
|
|
|
/** |
|
|
|
|
* The type of the React {@code Component} props of {@link Conference}. |
|
|
|
|
*/ |
|
|
|
|
type Props = AbstractProps & { |
|
|
|
|
interface IProps extends AbstractProps { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Application's aspect ratio. |
|
|
|
|
*/ |
|
|
|
|
_aspectRatio: Symbol, |
|
|
|
|
_aspectRatio: Symbol; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Whether the audio only is enabled or not. |
|
|
|
|
*/ |
|
|
|
|
_audioOnlyEnabled: boolean, |
|
|
|
|
_audioOnlyEnabled: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Branding styles for conference. |
|
|
|
|
*/ |
|
|
|
|
_brandingStyles: Object, |
|
|
|
|
_brandingStyles: StyleType; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Whether the calendar feature is enabled or not. |
|
|
|
|
*/ |
|
|
|
|
_calendarEnabled: boolean, |
|
|
|
|
_calendarEnabled: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The indicator which determines that we are still connecting to the |
|
|
|
@ -91,101 +92,101 @@ type Props = AbstractProps & { |
|
|
|
|
* joining the room. If truthy, then an activity/loading indicator will be |
|
|
|
|
* rendered. |
|
|
|
|
*/ |
|
|
|
|
_connecting: boolean, |
|
|
|
|
_connecting: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Set to {@code true} when the filmstrip is currently visible. |
|
|
|
|
*/ |
|
|
|
|
_filmstripVisible: boolean, |
|
|
|
|
_filmstripVisible: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The indicator which determines whether fullscreen (immersive) mode is enabled. |
|
|
|
|
*/ |
|
|
|
|
_fullscreenEnabled: boolean, |
|
|
|
|
_fullscreenEnabled: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The indicator which determines if the conference type is one to one. |
|
|
|
|
*/ |
|
|
|
|
_isOneToOneConference: boolean, |
|
|
|
|
_isOneToOneConference: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The indicator which determines if the participants pane is open. |
|
|
|
|
*/ |
|
|
|
|
_isParticipantsPaneOpen: boolean, |
|
|
|
|
_isParticipantsPaneOpen: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The ID of the participant currently on stage (if any). |
|
|
|
|
*/ |
|
|
|
|
_largeVideoParticipantId: string, |
|
|
|
|
_largeVideoParticipantId: string; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Local participant's display name. |
|
|
|
|
*/ |
|
|
|
|
_localParticipantDisplayName: string, |
|
|
|
|
_localParticipantDisplayName: string; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Whether Picture-in-Picture is enabled. |
|
|
|
|
*/ |
|
|
|
|
_pictureInPictureEnabled: boolean, |
|
|
|
|
_pictureInPictureEnabled: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The indicator which determines whether the UI is reduced (to accommodate |
|
|
|
|
* smaller display areas). |
|
|
|
|
*/ |
|
|
|
|
_reducedUI: boolean, |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The indicator which determines whether the Toolbox is visible. |
|
|
|
|
*/ |
|
|
|
|
_toolboxVisible: boolean, |
|
|
|
|
_reducedUI: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Indicates if we should auto-knock. |
|
|
|
|
*/ |
|
|
|
|
_shouldEnableAutoKnock: boolean, |
|
|
|
|
_shouldEnableAutoKnock: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Indicates whether the lobby screen should be visible. |
|
|
|
|
*/ |
|
|
|
|
_showLobby: boolean, |
|
|
|
|
_showLobby: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Indicates whether the car mode is enabled. |
|
|
|
|
*/ |
|
|
|
|
_startCarMode: boolean, |
|
|
|
|
_startCarMode: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The indicator which determines whether the Toolbox is visible. |
|
|
|
|
*/ |
|
|
|
|
_toolboxVisible: boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The redux {@code dispatch} function. |
|
|
|
|
*/ |
|
|
|
|
dispatch: Function, |
|
|
|
|
dispatch: Function; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Object containing the safe area insets. |
|
|
|
|
*/ |
|
|
|
|
insets: Object, |
|
|
|
|
insets: EdgeInsets; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Default prop for navigating between screen components(React Navigation). |
|
|
|
|
*/ |
|
|
|
|
navigation: Object |
|
|
|
|
}; |
|
|
|
|
navigation: any; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type State = { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The label that is currently expanded. |
|
|
|
|
*/ |
|
|
|
|
visibleExpandedLabel: ?string |
|
|
|
|
} |
|
|
|
|
visibleExpandedLabel?: string; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The conference page of the mobile (i.e. React Native) application. |
|
|
|
|
*/ |
|
|
|
|
class Conference extends AbstractConference<Props, State> { |
|
|
|
|
class Conference extends AbstractConference<IProps, State> { |
|
|
|
|
/** |
|
|
|
|
* Timeout ref. |
|
|
|
|
*/ |
|
|
|
|
_expandedLabelTimeout: Object; |
|
|
|
|
_expandedLabelTimeout: any; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Initializes a new Conference instance. |
|
|
|
@ -193,14 +194,14 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
* @param {Object} props - The read-only properties with which the new |
|
|
|
|
* instance is to be initialized. |
|
|
|
|
*/ |
|
|
|
|
constructor(props) { |
|
|
|
|
constructor(props: IProps) { |
|
|
|
|
super(props); |
|
|
|
|
|
|
|
|
|
this.state = { |
|
|
|
|
visibleExpandedLabel: undefined |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
this._expandedLabelTimeout = React.createRef(); |
|
|
|
|
this._expandedLabelTimeout = React.createRef<number>(); |
|
|
|
|
|
|
|
|
|
// Bind event handlers so they are only bound once per instance.
|
|
|
|
|
this._onClick = this._onClick.bind(this); |
|
|
|
@ -235,7 +236,7 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
* |
|
|
|
|
* @inheritdoc |
|
|
|
|
*/ |
|
|
|
|
componentDidUpdate(prevProps) { |
|
|
|
|
componentDidUpdate(prevProps: IProps) { |
|
|
|
|
const { |
|
|
|
|
_shouldEnableAutoKnock, |
|
|
|
|
_showLobby, |
|
|
|
@ -267,7 +268,7 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
// Tear handling any hardware button presses for back navigation down.
|
|
|
|
|
BackHandler.removeEventListener('hardwareBackPress', this._onHardwareBackPress); |
|
|
|
|
|
|
|
|
|
clearTimeout(this._expandedLabelTimeout.current); |
|
|
|
|
clearTimeout(this._expandedLabelTimeout.current ?? 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -301,8 +302,6 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_onClick: () => void; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Changes the value of the toolboxVisible state, thus allowing us to switch |
|
|
|
|
* between Toolbox and Filmstrip and change their visibility. |
|
|
|
@ -314,8 +313,6 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
this._setToolboxVisible(!this.props._toolboxVisible); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_onHardwareBackPress: () => boolean; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Handles a hardware button press for back navigation. Enters Picture-in-Picture mode |
|
|
|
|
* (if supported) or leaves the associated {@code Conference} otherwise. |
|
|
|
@ -340,8 +337,6 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_createOnPress: (string) => void; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Creates a function to be invoked when the onPress of the touchables are |
|
|
|
|
* triggered. |
|
|
|
@ -350,7 +345,7 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
* triggered. |
|
|
|
|
* @returns {Function} |
|
|
|
|
*/ |
|
|
|
|
_createOnPress(label) { |
|
|
|
|
_createOnPress(label: string) { |
|
|
|
|
return () => { |
|
|
|
|
const { visibleExpandedLabel } = this.state; |
|
|
|
|
|
|
|
|
@ -434,7 +429,7 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
|
|
|
|
|
<View |
|
|
|
|
pointerEvents = 'box-none' |
|
|
|
|
style = { styles.toolboxAndFilmstripContainer }> |
|
|
|
|
style = { styles.toolboxAndFilmstripContainer as ViewStyle }> |
|
|
|
|
|
|
|
|
|
<Captions onPress = { this._onClick } /> |
|
|
|
|
|
|
|
|
@ -463,17 +458,17 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
<SafeAreaView |
|
|
|
|
pointerEvents = 'box-none' |
|
|
|
|
style = { |
|
|
|
|
_toolboxVisible |
|
|
|
|
(_toolboxVisible |
|
|
|
|
? styles.titleBarSafeViewColor |
|
|
|
|
: styles.titleBarSafeViewTransparent }> |
|
|
|
|
: styles.titleBarSafeViewTransparent) as ViewStyle }> |
|
|
|
|
<TitleBar _createOnPress = { this._createOnPress } /> |
|
|
|
|
</SafeAreaView> |
|
|
|
|
<SafeAreaView |
|
|
|
|
pointerEvents = 'box-none' |
|
|
|
|
style = { |
|
|
|
|
_toolboxVisible |
|
|
|
|
(_toolboxVisible |
|
|
|
|
? [ styles.titleBarSafeViewTransparent, { top: this.props.insets.top + 50 } ] |
|
|
|
|
: styles.titleBarSafeViewTransparent |
|
|
|
|
: styles.titleBarSafeViewTransparent) as ViewStyle |
|
|
|
|
}> |
|
|
|
|
<View |
|
|
|
|
pointerEvents = 'box-none' |
|
|
|
@ -482,7 +477,7 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
</View> |
|
|
|
|
<View |
|
|
|
|
pointerEvents = 'box-none' |
|
|
|
|
style = { alwaysOnTitleBarStyles }> |
|
|
|
|
style = { alwaysOnTitleBarStyles as ViewStyle }> |
|
|
|
|
{/* eslint-disable-next-line react/jsx-no-bind */} |
|
|
|
|
<AlwaysOnLabels createOnPress = { this._createOnPress } /> |
|
|
|
|
</View> |
|
|
|
@ -532,7 +527,7 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
* @returns {React$Element} |
|
|
|
|
*/ |
|
|
|
|
_renderNotificationsContainer() { |
|
|
|
|
const notificationsStyle = {}; |
|
|
|
|
const notificationsStyle: ViewStyle = {}; |
|
|
|
|
|
|
|
|
|
// In the landscape mode (wide) there's problem with notifications being
|
|
|
|
|
// shadowed by the filmstrip rendered on the right. This makes the "x"
|
|
|
|
@ -559,8 +554,6 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_setToolboxVisible: (boolean) => void; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Dispatches an action changing the visibility of the {@link Toolbox}. |
|
|
|
|
* |
|
|
|
@ -569,7 +562,7 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
* {@code Toolbox} or {@code false} to hide it. |
|
|
|
|
* @returns {void} |
|
|
|
|
*/ |
|
|
|
|
_setToolboxVisible(visible) { |
|
|
|
|
_setToolboxVisible(visible: boolean) { |
|
|
|
|
this.props.dispatch(setToolboxVisible(visible)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -578,10 +571,11 @@ class Conference extends AbstractConference<Props, State> { |
|
|
|
|
* Maps (parts of) the redux state to the associated {@code Conference}'s props. |
|
|
|
|
* |
|
|
|
|
* @param {Object} state - The redux state. |
|
|
|
|
* @param {any} _ownProps - Component's own props. |
|
|
|
|
* @private |
|
|
|
|
* @returns {Props} |
|
|
|
|
* @returns {IProps} |
|
|
|
|
*/ |
|
|
|
|
function _mapStateToProps(state) { |
|
|
|
|
function _mapStateToProps(state: IReduxState, _ownProps: any) { |
|
|
|
|
const { isOpen } = state['features/participants-pane']; |
|
|
|
|
const { aspectRatio, reducedUI } = state['features/base/responsive-ui']; |
|
|
|
|
const { backgroundColor } = state['features/dynamic-branding']; |
|
|
|
@ -627,7 +621,7 @@ export default withSafeAreaInsets(connect(_mapStateToProps)(props => { |
|
|
|
|
return () => setPictureInPictureEnabled(false); |
|
|
|
|
}, [ isFocused ]); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
return ( // @ts-ignore
|
|
|
|
|
<Conference { ...props } /> |
|
|
|
|
); |
|
|
|
|
})); |