feat(filmstrip/toolbox) mobile ui updates (#11051)
This commit is contained in:
parent
c35473d5e4
commit
577d62ea53
|
@ -1,13 +1,15 @@
|
|||
// @flow
|
||||
|
||||
import React, { PureComponent } from 'react';
|
||||
import { FlatList, SafeAreaView } from 'react-native';
|
||||
import { FlatList } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
|
||||
import { getLocalParticipant } from '../../../base/participants';
|
||||
import { Platform } from '../../../base/react';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui/constants';
|
||||
import { shouldHideSelfView } from '../../../base/settings/functions.any';
|
||||
import { isToolboxVisible } from '../../../toolbox/functions';
|
||||
import { setVisibleRemoteParticipants } from '../../actions';
|
||||
import { isFilmstripVisible, shouldRemoteVideosBeVisible } from '../../functions';
|
||||
|
||||
|
@ -37,6 +39,11 @@ type Props = {
|
|||
*/
|
||||
_disableSelfView: boolean,
|
||||
|
||||
/**
|
||||
* Whether or not the toolbox is displayed.
|
||||
*/
|
||||
_toolboxVisible: Boolean,
|
||||
|
||||
_localParticipantId: string,
|
||||
|
||||
/**
|
||||
|
@ -90,7 +97,7 @@ class Filmstrip extends PureComponent<Props> {
|
|||
// layer #0 sits behind the window, creates a hole in the window, and
|
||||
// there we render the LargeVideo; layer #1 is known as media overlay in
|
||||
// EGL terms, renders on top of layer #0, and, consequently, is for the
|
||||
// Filmstrip. With the separate LocalThumnail, we should have left the
|
||||
// Filmstrip. With the separate LocalThumbnail, we should have left the
|
||||
// remote participants' Thumbnails in layer #1 and utilized layer #2 for
|
||||
// LocalThumbnail. Unfortunately, layer #2 is not practical (that's why
|
||||
// I said we had two practical layers only) because it renders on top of
|
||||
|
@ -226,6 +233,7 @@ class Filmstrip extends PureComponent<Props> {
|
|||
const {
|
||||
_aspectRatio,
|
||||
_disableSelfView,
|
||||
_toolboxVisible,
|
||||
_localParticipantId,
|
||||
_participants,
|
||||
_visible
|
||||
|
@ -235,6 +243,7 @@ class Filmstrip extends PureComponent<Props> {
|
|||
return null;
|
||||
}
|
||||
|
||||
const bottomEdge = Platform.OS === 'ios' && !_toolboxVisible;
|
||||
const isNarrowAspectRatio = _aspectRatio === ASPECT_RATIO_NARROW;
|
||||
const filmstripStyle = isNarrowAspectRatio ? styles.filmstripNarrow : styles.filmstripWide;
|
||||
const { height, width } = this._getDimensions();
|
||||
|
@ -254,7 +263,9 @@ class Filmstrip extends PureComponent<Props> {
|
|||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style = { filmstripStyle }>
|
||||
<SafeAreaView
|
||||
edges = { [ bottomEdge && 'bottom', 'left', 'right' ].filter(Boolean) }
|
||||
style = { filmstripStyle }>
|
||||
{
|
||||
this._separateLocalThumbnail
|
||||
&& !isNarrowAspectRatio
|
||||
|
@ -307,6 +318,7 @@ function _mapStateToProps(state) {
|
|||
_disableSelfView: disableSelfView,
|
||||
_localParticipantId: getLocalParticipant(state)?.id,
|
||||
_participants: showRemoteVideos ? remoteParticipants : NO_REMOTE_VIDEOS,
|
||||
_toolboxVisible: isToolboxVisible(state),
|
||||
_visible: enabled && isFilmstripVisible(state)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ export default {
|
|||
flexDirection: 'row',
|
||||
flexGrow: 0,
|
||||
justifyContent: 'flex-end',
|
||||
marginBottom: BaseTheme.spacing[1]
|
||||
margin: 6
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,7 +4,6 @@ import { NavigationContainer } from '@react-navigation/native';
|
|||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { Chat } from '../../../../../chat';
|
||||
|
@ -63,81 +62,79 @@ const ConferenceNavigationContainer = () => {
|
|||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<SafeAreaProvider>
|
||||
<NavigationContainer
|
||||
independent = { true }
|
||||
ref = { conferenceNavigationRef }
|
||||
theme = { navigationContainerTheme }>
|
||||
<ConferenceStack.Navigator
|
||||
initialRouteName = { screen.conference.main }
|
||||
screenOptions = {{
|
||||
presentation: 'modal'
|
||||
}}>
|
||||
<ConferenceStack.Screen
|
||||
component = { Conference }
|
||||
name = { screen.conference.main }
|
||||
options = { conferenceScreenOptions } />
|
||||
<ConferenceStack.Screen
|
||||
component = { ChatScreen }
|
||||
name = { chatScreenName }
|
||||
options = {{
|
||||
...chatScreenOptions,
|
||||
title: t(chatTitleString)
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { ParticipantsPane }
|
||||
name = { screen.conference.participants }
|
||||
options = {{
|
||||
...participantsScreenOptions,
|
||||
title: t('participantsPane.header')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { SecurityDialog }
|
||||
name = { screen.conference.security }
|
||||
options = {{
|
||||
...securityScreenOptions,
|
||||
title: t('security.header')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { StartRecordingDialog }
|
||||
name = { screen.conference.recording }
|
||||
options = {{
|
||||
...recordingScreenOptions
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { StartLiveStreamDialog }
|
||||
name = { screen.conference.liveStream }
|
||||
options = {{
|
||||
...liveStreamScreenOptions
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { SpeakerStats }
|
||||
name = { screen.conference.speakerStats }
|
||||
options = {{
|
||||
...speakerStatsScreenOptions,
|
||||
title: t('speakerStats.speakerStats')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { LobbyScreen }
|
||||
name = { screen.lobby }
|
||||
options = { lobbyScreenOptions } />
|
||||
<ConferenceStack.Screen
|
||||
component = { AddPeopleDialog }
|
||||
name = { screen.conference.invite }
|
||||
options = {{
|
||||
...inviteScreenOptions,
|
||||
title: t('addPeople.add')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { SharedDocument }
|
||||
name = { screen.conference.sharedDocument }
|
||||
options = {{
|
||||
...sharedDocumentScreenOptions,
|
||||
title: t('documentSharing.title')
|
||||
}} />
|
||||
</ConferenceStack.Navigator>
|
||||
</NavigationContainer>
|
||||
</SafeAreaProvider>
|
||||
<NavigationContainer
|
||||
independent = { true }
|
||||
ref = { conferenceNavigationRef }
|
||||
theme = { navigationContainerTheme }>
|
||||
<ConferenceStack.Navigator
|
||||
initialRouteName = { screen.conference.main }
|
||||
screenOptions = {{
|
||||
presentation: 'modal'
|
||||
}}>
|
||||
<ConferenceStack.Screen
|
||||
component = { Conference }
|
||||
name = { screen.conference.main }
|
||||
options = { conferenceScreenOptions } />
|
||||
<ConferenceStack.Screen
|
||||
component = { ChatScreen }
|
||||
name = { chatScreenName }
|
||||
options = {{
|
||||
...chatScreenOptions,
|
||||
title: t(chatTitleString)
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { ParticipantsPane }
|
||||
name = { screen.conference.participants }
|
||||
options = {{
|
||||
...participantsScreenOptions,
|
||||
title: t('participantsPane.header')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { SecurityDialog }
|
||||
name = { screen.conference.security }
|
||||
options = {{
|
||||
...securityScreenOptions,
|
||||
title: t('security.header')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { StartRecordingDialog }
|
||||
name = { screen.conference.recording }
|
||||
options = {{
|
||||
...recordingScreenOptions
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { StartLiveStreamDialog }
|
||||
name = { screen.conference.liveStream }
|
||||
options = {{
|
||||
...liveStreamScreenOptions
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { SpeakerStats }
|
||||
name = { screen.conference.speakerStats }
|
||||
options = {{
|
||||
...speakerStatsScreenOptions,
|
||||
title: t('speakerStats.speakerStats')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { LobbyScreen }
|
||||
name = { screen.lobby }
|
||||
options = { lobbyScreenOptions } />
|
||||
<ConferenceStack.Screen
|
||||
component = { AddPeopleDialog }
|
||||
name = { screen.conference.invite }
|
||||
options = {{
|
||||
...inviteScreenOptions,
|
||||
title: t('addPeople.add')
|
||||
}} />
|
||||
<ConferenceStack.Screen
|
||||
component = { SharedDocument }
|
||||
name = { screen.conference.sharedDocument }
|
||||
options = {{
|
||||
...sharedDocumentScreenOptions,
|
||||
title: t('documentSharing.title')
|
||||
}} />
|
||||
</ConferenceStack.Navigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { SafeAreaView, View } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { Platform } from '../../../base/react';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { StyleType } from '../../../base/styles';
|
||||
import { ChatButton } from '../../../chat';
|
||||
|
@ -26,6 +28,11 @@ import styles from './styles';
|
|||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Whether or not the reactions feature is enabled.
|
||||
*/
|
||||
_reactionsEnabled: boolean,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
|
@ -39,12 +46,7 @@ type Props = {
|
|||
/**
|
||||
* The width of the screen.
|
||||
*/
|
||||
_width: number,
|
||||
|
||||
/**
|
||||
* Whether or not the reactions feature is enabled.
|
||||
*/
|
||||
_reactionsEnabled: boolean
|
||||
_width: number
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -54,11 +56,13 @@ type Props = {
|
|||
* @returns {React$Element}.
|
||||
*/
|
||||
function Toolbox(props: Props) {
|
||||
if (!props._visible) {
|
||||
const { _reactionsEnabled, _styles, _visible, _width } = props;
|
||||
|
||||
if (!_visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { _styles, _width, _reactionsEnabled } = props;
|
||||
const bottomEdge = Platform.OS === 'ios' && _visible;
|
||||
const { buttonStylesBorderless, hangupButtonStyles, toggledButtonStyles } = _styles;
|
||||
const additionalButtons = getMovableButtons(_width);
|
||||
const backgroundToggledStyle = {
|
||||
|
@ -75,6 +79,7 @@ function Toolbox(props: Props) {
|
|||
style = { styles.toolboxContainer }>
|
||||
<SafeAreaView
|
||||
accessibilityRole = 'toolbar'
|
||||
edges = { [ bottomEdge && 'bottom' ].filter(Boolean) }
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.toolbox }>
|
||||
<AudioMuteButton
|
||||
|
|
|
@ -18,7 +18,7 @@ const toolbarButton = {
|
|||
height: BUTTON_SIZE,
|
||||
justifyContent: 'center',
|
||||
marginHorizontal: 6,
|
||||
marginTop: 6,
|
||||
marginVertical: 6,
|
||||
width: BUTTON_SIZE
|
||||
};
|
||||
|
||||
|
@ -86,9 +86,7 @@ const styles = {
|
|||
borderTopLeftRadius: 3,
|
||||
borderTopRightRadius: 3,
|
||||
flexDirection: 'row',
|
||||
flexGrow: 0,
|
||||
justifyContent: 'space-between',
|
||||
margin: BaseTheme.spacing[2]
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -97,11 +95,10 @@ const styles = {
|
|||
toolboxContainer: {
|
||||
backgroundColor: BaseTheme.palette.uiBackground,
|
||||
flexDirection: 'column',
|
||||
flexGrow: 0,
|
||||
width: '100%',
|
||||
maxWidth: 580,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto'
|
||||
marginRight: 'auto',
|
||||
width: '100%'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue