feat(filmstrip/toolbox) mobile ui updates (#11051)

This commit is contained in:
Calinteodor 2022-03-01 17:41:45 +02:00 committed by GitHub
parent c35473d5e4
commit 577d62ea53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 107 additions and 96 deletions

View File

@ -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)
};
}

View File

@ -45,7 +45,7 @@ export default {
flexDirection: 'row',
flexGrow: 0,
justifyContent: 'flex-end',
marginBottom: BaseTheme.spacing[1]
margin: 6
},
/**

View File

@ -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>
);
};

View File

@ -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

View File

@ -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%'
}
};