feat(mobile/navigation): revert to stack navigator (#11811)

* feat(mobile/navigation): replaced native stack with stack navigator and other ui fixes
pull/11816/head jitsi-meet_7514
Calinteodor 2 years ago committed by GitHub
parent e9cfa78aaf
commit 0d50f1867d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 115
      package-lock.json
  2. 2
      package.json
  3. 2
      react/features/app/components/App.native.js
  4. 26
      react/features/base/modal/components/JitsiKeyboardAvoidingView.js
  5. 7
      react/features/base/modal/components/JitsiScreen.js
  6. 6
      react/features/conference/components/native/styles.js
  7. 3
      react/features/mobile/navigation/components/HeaderNavigationButton.js
  8. 4
      react/features/mobile/navigation/components/RootNavigationContainer.js
  9. 4
      react/features/mobile/navigation/components/conference/components/ConferenceNavigationContainer.tsx
  10. 4
      react/features/mobile/navigation/components/lobby/components/LobbyNavigationContainer.js
  11. 51
      react/features/mobile/navigation/screenOptions.js
  12. 6
      react/features/polls/components/native/PollCreate.js
  13. 19
      react/features/polls/components/native/styles.js

115
package-lock.json generated

@ -49,7 +49,7 @@
"@react-navigation/elements": "1.2.1",
"@react-navigation/material-top-tabs": "6.0.6",
"@react-navigation/native": "6.0.6",
"@react-navigation/native-stack": "6.6.2",
"@react-navigation/stack": "6.2.2",
"@svgr/webpack": "4.3.2",
"@tensorflow/tfjs-backend-wasm": "3.13.0",
"@tensorflow/tfjs-core": "3.13.0",
@ -5026,26 +5026,36 @@
"react-native": "*"
}
},
"node_modules/@react-navigation/native-stack": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.6.2.tgz",
"integrity": "sha512-pFMuzhxbPml5MBvJVAzHWoaUkQaefAOKpuUnAs/AxNQuHQwwnxRmDit1PQLuIPo7g7DlfwFXagDHE1R0tbnS8Q==",
"node_modules/@react-navigation/routers": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.0.tgz",
"integrity": "sha512-8xJL+djIzpFdRW/sGlKojQ06fWgFk1c5jER9501HYJ12LF5DIJFr/tqBI2TJ6bk+y+QFu0nbNyeRC80OjRlmkA==",
"dependencies": {
"nanoid": "^3.1.23"
}
},
"node_modules/@react-navigation/stack": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.2.2.tgz",
"integrity": "sha512-P9ZfmluOXNmbs7YdG1UWS1fAh87Yse9aX8TgqOz4FlHEm5q7g5eaM35QgWByt+wif3UiqE40D8wXpqRQvMgPWg==",
"dependencies": {
"@react-navigation/elements": "^1.3.3",
"@react-navigation/elements": "^1.3.4",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
"peerDependencies": {
"@react-navigation/native": "^6.0.0",
"react": "*",
"react-native": "*",
"react-native-gesture-handler": ">= 1.0.0",
"react-native-safe-area-context": ">= 3.0.0",
"react-native-screens": ">= 3.0.0"
}
},
"node_modules/@react-navigation/native-stack/node_modules/@react-navigation/elements": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.3.tgz",
"integrity": "sha512-Lv2lR7si5gNME8dRsqz57d54m4FJtrwHRjNQLOyQO546ZxO+g864cSvoLC6hQedQU0+IJnPTsZiEI2hHqfpEpw==",
"node_modules/@react-navigation/stack/node_modules/@react-navigation/elements": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.4.tgz",
"integrity": "sha512-O0jICpjn3jskVo4yiWzZozmj7DZy1ZBbn3O7dbenuUjZSj/cscjwaapmZZFGcI/IMmjmx8UTKsybhCFEIbGf3g==",
"peerDependencies": {
"@react-navigation/native": "^6.0.0",
"react": "*",
@ -5053,14 +5063,34 @@
"react-native-safe-area-context": ">= 3.0.0"
}
},
"node_modules/@react-navigation/routers": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.0.tgz",
"integrity": "sha512-8xJL+djIzpFdRW/sGlKojQ06fWgFk1c5jER9501HYJ12LF5DIJFr/tqBI2TJ6bk+y+QFu0nbNyeRC80OjRlmkA==",
"node_modules/@react-navigation/stack/node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
"dependencies": {
"nanoid": "^3.1.23"
"color-convert": "^2.0.1",
"color-string": "^1.9.0"
},
"engines": {
"node": ">=12.5.0"
}
},
"node_modules/@react-navigation/stack/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/@react-navigation/stack/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@sideway/address": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
@ -23766,22 +23796,6 @@
"nanoid": "^3.1.23"
}
},
"@react-navigation/native-stack": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.6.2.tgz",
"integrity": "sha512-pFMuzhxbPml5MBvJVAzHWoaUkQaefAOKpuUnAs/AxNQuHQwwnxRmDit1PQLuIPo7g7DlfwFXagDHE1R0tbnS8Q==",
"requires": {
"@react-navigation/elements": "^1.3.3",
"warn-once": "^0.1.0"
},
"dependencies": {
"@react-navigation/elements": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.3.tgz",
"integrity": "sha512-Lv2lR7si5gNME8dRsqz57d54m4FJtrwHRjNQLOyQO546ZxO+g864cSvoLC6hQedQU0+IJnPTsZiEI2hHqfpEpw=="
}
}
},
"@react-navigation/routers": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.0.tgz",
@ -23790,6 +23804,45 @@
"nanoid": "^3.1.23"
}
},
"@react-navigation/stack": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.2.2.tgz",
"integrity": "sha512-P9ZfmluOXNmbs7YdG1UWS1fAh87Yse9aX8TgqOz4FlHEm5q7g5eaM35QgWByt+wif3UiqE40D8wXpqRQvMgPWg==",
"requires": {
"@react-navigation/elements": "^1.3.4",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
"dependencies": {
"@react-navigation/elements": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.4.tgz",
"integrity": "sha512-O0jICpjn3jskVo4yiWzZozmj7DZy1ZBbn3O7dbenuUjZSj/cscjwaapmZZFGcI/IMmjmx8UTKsybhCFEIbGf3g=="
},
"color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
"requires": {
"color-convert": "^2.0.1",
"color-string": "^1.9.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}
}
},
"@sideway/address": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",

@ -54,7 +54,7 @@
"@react-navigation/elements": "1.2.1",
"@react-navigation/material-top-tabs": "6.0.6",
"@react-navigation/native": "6.0.6",
"@react-navigation/native-stack": "6.6.2",
"@react-navigation/stack": "6.2.2",
"@svgr/webpack": "4.3.2",
"@tensorflow/tfjs-backend-wasm": "3.13.0",
"@tensorflow/tfjs-core": "3.13.0",

@ -1,7 +1,6 @@
import React from 'react';
import { Platform, StyleSheet, View } from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { FullWindowOverlay } from 'react-native-screens';
import SplashScreen from 'react-native-splash-screen';
import { DialogContainer } from '../../base/dialog';
@ -24,7 +23,6 @@ import '../reducers';
declare var __DEV__;
const DialogContainerWrapper = Platform.select({
ios: FullWindowOverlay,
default: View
});

@ -1,6 +1,6 @@
// @flow
import { getDefaultHeaderHeight } from '@react-navigation/elements';
import { useHeaderHeight } from '@react-navigation/elements';
import React, { useCallback, useEffect, useState } from 'react';
import {
Keyboard,
@ -8,7 +8,7 @@ import {
Platform,
StatusBar
} from 'react-native';
import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { StyleType } from '../../styles';
@ -34,11 +34,6 @@ type Props = {
*/
hasTabNavigator: boolean,
/**
* Is the screen presented as a modal?
*/
isModalPresentation: boolean,
/**
* Additional style to be appended to the KeyboardAvoidingView.
*/
@ -51,33 +46,26 @@ const JitsiKeyboardAvoidingView = (
contentContainerStyle,
hasTabNavigator,
hasBottomTextInput,
isModalPresentation,
style
}: Props) => {
const frame = useSafeAreaFrame();
const headerHeight = useHeaderHeight();
const insets = useSafeAreaInsets();
const [ bottomPadding, setBottomPadding ] = useState(insets.bottom);
const [ topPadding, setTopPadding ] = useState(insets.top);
useEffect(() => {
// This useEffect is needed because insets are undefined at first for some reason
// https://github.com/th3rdwave/react-native-safe-area-context/issues/54
setBottomPadding(insets.bottom);
setTopPadding(insets.top);
}, [ insets.bottom, insets.top ]);
}, [ insets.bottom ]);
const headerHeight = getDefaultHeaderHeight(frame, isModalPresentation, topPadding);
// Notch devices have in general a header height between 103 and 106px
const topNotchDevice = headerHeight > 100;
const deviceHeight = topNotchDevice ? headerHeight - 50 : headerHeight;
const tabNavigatorPadding
= hasTabNavigator ? deviceHeight : 0;
= hasTabNavigator ? headerHeight : 0;
const noNotchDevicePadding = bottomPadding || 10;
const iosVerticalOffset
= deviceHeight + noNotchDevicePadding + tabNavigatorPadding;
= headerHeight + noNotchDevicePadding + tabNavigatorPadding;
const androidVerticalOffset = hasBottomTextInput
? deviceHeight + StatusBar.currentHeight : deviceHeight;
? headerHeight + StatusBar.currentHeight : headerHeight;
// Tells the view what to do with taps
const shouldSetResponse = useCallback(() => true);

@ -37,11 +37,6 @@ type Props = {
*/
hasTabNavigator?: boolean,
/**
* Is the screen presented as a modal?
*/
isModalPresentation?: boolean,
/**
* Insets for the SafeAreaView.
*/
@ -59,7 +54,6 @@ const JitsiScreen = ({
footerComponent,
hasTabNavigator = false,
hasBottomTextInput = false,
isModalPresentation = true,
safeAreaInsets = [ 'left', 'right' ],
style
}: Props) => (
@ -69,7 +63,6 @@ const JitsiScreen = ({
contentContainerStyle = { contentContainerStyle }
hasBottomTextInput = { hasBottomTextInput }
hasTabNavigator = { hasTabNavigator }
isModalPresentation = { isModalPresentation }
style = { style }>
<SafeAreaView
edges = { safeAreaInsets }

@ -41,14 +41,20 @@ export default {
width: BaseTheme.spacing[6]
},
headerNavigationIcon: {
marginLeft: 12
},
headerNavigationText: {
color: BaseTheme.palette.text01,
marginLeft: BaseTheme.spacing[3],
fontSize: HEADER_ACTION_BUTTON_SIZE
},
headerNavigationTextBold: {
...BaseTheme.typography.labelButton,
color: BaseTheme.palette.text01,
marginRight: BaseTheme.spacing[3],
fontSize: HEADER_ACTION_BUTTON_SIZE
},

@ -61,7 +61,8 @@ const HeaderNavigationButton
styles.headerNavigationButton ] } >
<Icon
size = { 24 }
src = { src } />
src = { src }
style = { styles.headerNavigationIcon } />
</TouchableRipple>
) : (
<TouchableRipple

@ -1,5 +1,5 @@
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createStackNavigator } from '@react-navigation/stack';
import React, { useCallback } from 'react';
import { connect } from '../../../base/redux';
@ -24,7 +24,7 @@ import ConferenceNavigationContainer
import WelcomePageNavigationContainer
from './welcome/components/WelcomePageNavigationContainer';
const RootStack = createNativeStackNavigator();
const RootStack = createStackNavigator();
type Props = {

@ -1,5 +1,5 @@
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createStackNavigator } from '@react-navigation/stack';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
@ -46,7 +46,7 @@ import {
conferenceNavigationRef
} from '../ConferenceNavigationContainerRef';
const ConferenceStack = createNativeStackNavigator();
const ConferenceStack = createStackNavigator();
const ConferenceNavigationContainer = () => {
const isPollsDisabled = useSelector(getDisablePolls);

@ -1,5 +1,5 @@
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createStackNavigator } from '@react-navigation/stack';
import React from 'react';
import { useSelector } from 'react-redux';
@ -12,7 +12,7 @@ import {
} from '../../../screenOptions';
import { lobbyNavigationContainerRef } from '../LobbyNavigationContainerRef';
const LobbyStack = createNativeStackNavigator();
const LobbyStack = createStackNavigator();
const LobbyNavigationContainer = () => {

@ -1,3 +1,4 @@
import { TransitionPresets } from '@react-navigation/stack';
import React from 'react';
import { Platform } from 'react-native';
@ -16,6 +17,23 @@ import { lobbyScreenHeaderCloseButton, screenHeaderCloseButton } from './functio
import { goBack as goBackToWelcomeScreen } from './rootNavigationContainerRef';
/**
* Default modal transition for the current platform.
*/
export const modalPresentation = Platform.select({
ios: TransitionPresets.ModalPresentationIOS,
default: TransitionPresets.DefaultTransition
});
/**
* Screen options and transition types.
*/
export const fullScreenOptions = {
...TransitionPresets.ModalTransition,
gestureEnabled: false,
headerShown: false
};
/**
* Navigation container theme.
*/
@ -29,7 +47,7 @@ export const navigationContainerTheme = {
* Drawer navigator screens options and transition types.
*/
export const drawerNavigatorScreenOptions = {
animation: 'default',
...TransitionPresets.ModalTransition,
gestureEnabled: true,
headerShown: false
};
@ -39,16 +57,12 @@ export const drawerNavigatorScreenOptions = {
* Drawer screen options and transition types.
*/
export const drawerScreenOptions = {
animation: 'default',
...TransitionPresets.ModalTransition,
gestureEnabled: true,
headerShown: true,
headerStyle: {
backgroundColor: BaseTheme.palette.screen02Header
},
orientation: Platform.select({
ios: 'default',
android: 'all'
})
}
};
/**
@ -138,15 +152,7 @@ export const helpScreenOptions = {
/**
* Screen options for conference.
*/
export const conferenceScreenOptions = {
animation: 'default',
gestureEnabled: false,
headerShown: false,
orientation: Platform.select({
ios: 'default',
android: 'all'
})
};
export const conferenceScreenOptions = fullScreenOptions;
/**
* Tab bar options for chat screen.
@ -172,6 +178,7 @@ export const chatTabBarOptions = {
* Screen options for presentation type modals.
*/
export const presentationScreenOptions = {
...modalPresentation,
headerBackTitleVisible: false,
headerLeft: () => screenHeaderCloseButton(goBack),
headerStatusBarHeight: 0,
@ -180,20 +187,13 @@ export const presentationScreenOptions = {
},
headerTitleStyle: {
color: BaseTheme.palette.text01
},
orientation: Platform.select({
ios: 'default',
android: 'all'
})
}
};
/**
* Screen options for car mode.
*/
export const carmodeScreenOptions = {
...presentationScreenOptions,
orientation: 'portrait'
};
export const carmodeScreenOptions = presentationScreenOptions;
/**
* Screen options for chat.
@ -205,7 +205,6 @@ export const chatScreenOptions = presentationScreenOptions;
*/
export const dialInSummaryScreenOptions = {
...presentationScreenOptions,
animation: 'slide_from_bottom',
headerLeft: () => screenHeaderCloseButton(goBackToWelcomeScreen)
};

@ -1,7 +1,7 @@
// @flow
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { View, Text, TextInput, FlatList } from 'react-native';
import { View, Text, TextInput, FlatList, Platform } from 'react-native';
import { Divider, TouchableRipple } from 'react-native-paper';
import Button from '../../../base/react/components/native/Button';
@ -127,6 +127,8 @@ const PollCreate = (props: AbstractProps) => {
}
</View>
);
const buttonRowStyles = Platform.OS === 'android'
? chatStyles.buttonRowAndroid : chatStyles.buttonRowIos;
return (
<View style = { chatStyles.pollCreateContainer }>
@ -167,7 +169,7 @@ const PollCreate = (props: AbstractProps) => {
style = { chatStyles.pollCreateAddButton }
type = { SECONDARY } />
<View
style = { chatStyles.buttonRow }>
style = { buttonRowStyles }>
<Button
accessibilityLabel = 'polls.create.cancel'
label = 'polls.create.cancel'

@ -170,10 +170,29 @@ export const chatStyles = createStyleSheet({
marginHorizontal: BaseTheme.spacing[2]
},
pollSendLabel: {
color: BaseTheme.palette.text01,
textTransform: 'capitalize'
},
pollSendDisabledLabel: {
color: BaseTheme.palette.text03,
textTransform: 'capitalize'
},
buttonRow: {
flexDirection: 'row'
},
buttonRowAndroid: {
flexDirection: 'row',
marginBottom: BaseTheme.spacing[3]
},
buttonRowIos: {
flexDirection: 'row'
},
answerContent: {
paddingBottom: 8
},

Loading…
Cancel
Save