feat(settings/native): fixed scroll inside screen (#12395)

* feat(settings): fixed scroll, bottom insets and bounce
This commit is contained in:
Calinteodor 2022-10-17 18:14:40 +03:00 committed by GitHub
parent a082a3fb0f
commit 4d817af060
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 179 additions and 180 deletions

View File

@ -1,7 +1,6 @@
// @flow
import React from 'react'; import React from 'react';
import { ScrollView, View } from 'react-native'; import { View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaView } from 'react-native-safe-area-context';
import { StyleType } from '../../styles'; import { StyleType } from '../../styles';
@ -20,7 +19,7 @@ type Props = {
/** /**
* The children component(s) of the Modal, to be rendered. * The children component(s) of the Modal, to be rendered.
*/ */
children: React$Node, children: React.ReactNode,
/** /**
* Disabled forced keyboard dismiss? * Disabled forced keyboard dismiss?
@ -47,11 +46,6 @@ type Props = {
*/ */
safeAreaInsets?: Array, safeAreaInsets?: Array,
/**
* Enable scroll for JitsiScreen.
*/
scrollEnabled?: boolean,
/** /**
* Additional style to be appended to the KeyboardAvoidingView containing the content of the modal. * Additional style to be appended to the KeyboardAvoidingView containing the content of the modal.
*/ */
@ -66,7 +60,6 @@ const JitsiScreen = ({
hasBottomTextInput = false, hasBottomTextInput = false,
disableForcedKeyboardDismiss = false, disableForcedKeyboardDismiss = false,
safeAreaInsets = [ 'left', 'right' ], safeAreaInsets = [ 'left', 'right' ],
scrollEnabled = false,
style style
}: Props) => { }: Props) => {
const renderContent = () => ( const renderContent = () => (
@ -85,16 +78,6 @@ const JitsiScreen = ({
</JitsiKeyboardAvoidingView> </JitsiKeyboardAvoidingView>
); );
if (scrollEnabled) {
return (
<ScrollView
bounces = { false }
style = { styles.jitsiScreenContainer }>
{ renderContent() }
</ScrollView>
);
}
return ( return (
<View style = { styles.jitsiScreenContainer }> <View style = { styles.jitsiScreenContainer }>
{ renderContent() } { renderContent() }

View File

@ -1,6 +1,3 @@
// @flow
import { ColorSchemeRegistry, schemeColor } from '../../color-scheme';
export default { export default {
@ -12,10 +9,3 @@ export default {
flex: 1 flex: 1
} }
}; };
ColorSchemeRegistry.register('Modal', {
page: {
alignItems: 'stretch',
backgroundColor: schemeColor('background')
}
});

View File

@ -1,6 +1,6 @@
import { NavigationContainer } from '@react-navigation/native'; import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack'; import { createStackNavigator } from '@react-navigation/stack';
import React from 'react'; import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import HelpView from '../../../../../settings/components/native/HelpView'; import HelpView from '../../../../../settings/components/native/HelpView';
@ -38,6 +38,14 @@ const SettingsNavigationContainer = ({ isInWelcomePage }: Props) => {
const baseSettingsScreenOptions = isInWelcomePage ? welcomeScreenOptions : settingsScreenOptions; const baseSettingsScreenOptions = isInWelcomePage ? welcomeScreenOptions : settingsScreenOptions;
const { t } = useTranslation(); const { t } = useTranslation();
const SettingsScreen = useCallback(() =>
(
<SettingsView
addBottomInset = { !isInWelcomePage }
scrollBounces = { isInWelcomePage } />
)
);
return ( return (
<NavigationContainer <NavigationContainer
independent = { true } independent = { true }
@ -46,12 +54,13 @@ const SettingsNavigationContainer = ({ isInWelcomePage }: Props) => {
<SettingsStack.Navigator <SettingsStack.Navigator
initialRouteName = { screen.settings.main }> initialRouteName = { screen.settings.main }>
<SettingsStack.Screen <SettingsStack.Screen
component = { SettingsView }
name = { screen.settings.main } name = { screen.settings.main }
options = {{ options = {{
...baseSettingsScreenOptions, ...baseSettingsScreenOptions,
title: t('settings.title') title: t('settings.title')
}} /> }}>
{ SettingsScreen }
</SettingsStack.Screen>
<SettingsStack.Screen <SettingsStack.Screen
component = { HelpView } component = { HelpView }
name = { screen.settings.links.help } name = { screen.settings.links.help }

View File

@ -8,6 +8,7 @@ import {
Alert, Alert,
NativeModules, NativeModules,
Platform, Platform,
ScrollView,
Text, Text,
View View
} from 'react-native'; } from 'react-native';
@ -150,6 +151,11 @@ interface Props extends WithTranslation {
*/ */
_visible: boolean; _visible: boolean;
/**
* Add bottom padding to the screen.
*/
addBottomInset?: boolean;
/** /**
* Redux store dispatch function. * Redux store dispatch function.
*/ */
@ -159,6 +165,11 @@ interface Props extends WithTranslation {
* Default prop for navigating between screen components(React Navigation). * Default prop for navigating between screen components(React Navigation).
*/ */
navigation: Object; navigation: Object;
/**
* Bounce when scrolling.
*/
scrollBounces?: boolean;
} }
/** /**
@ -258,7 +269,11 @@ class SettingsView extends Component<Props, State> {
startWithVideoMuted startWithVideoMuted
} = this.state; } = this.state;
const { t } = this.props; const {
addBottomInset = false,
scrollBounces = false,
t
} = this.props;
const textInputTheme = { const textInputTheme = {
colors: { colors: {
@ -272,157 +287,159 @@ class SettingsView extends Component<Props, State> {
return ( return (
<JitsiScreen <JitsiScreen
safeAreaInsets = { [ 'bottom', 'left', 'right' ] } disableForcedKeyboardDismiss = { true }
scrollEnabled = { true } safeAreaInsets = { [ addBottomInset && 'bottom', 'left', 'right' ].filter(Boolean) }
style = { styles.settingsViewContainer }> style = { styles.settingsViewContainer }>
<View style = { styles.avatarContainer }> <ScrollView bounces = { scrollBounces }>
<Avatar <View style = { styles.avatarContainer }>
participantId = { this.props._localParticipantId } <Avatar
size = { AVATAR_SIZE } /> participantId = { this.props._localParticipantId }
</View> size = { AVATAR_SIZE } />
<FormSectionAccordion </View>
label = 'settingsView.profileSection'> <FormSectionAccordion
<TextInput label = 'settingsView.profileSection'>
autoCorrect = { false } <TextInput
label = { t('settingsView.displayName') } autoCorrect = { false }
mode = 'outlined' label = { t('settingsView.displayName') }
onChangeText = { this._onChangeDisplayName } mode = 'outlined'
placeholder = { t('settingsView.displayNamePlaceholderText') } onChangeText = { this._onChangeDisplayName }
placeholderTextColor = { PLACEHOLDER_TEXT_COLOR } placeholder = { t('settingsView.displayNamePlaceholderText') }
spellCheck = { false } placeholderTextColor = { PLACEHOLDER_TEXT_COLOR }
style = { styles.textInputContainer } spellCheck = { false }
textContentType = { 'name' } // iOS only style = { styles.textInputContainer }
theme = { textInputTheme } textContentType = { 'name' } // iOS only
value = { displayName } /> theme = { textInputTheme }
<Divider style = { styles.fieldSeparator } /> value = { displayName } />
<TextInput <Divider style = { styles.fieldSeparator } />
autoCapitalize = 'none' <TextInput
autoCorrect = { false } autoCapitalize = 'none'
keyboardType = { 'email-address' } autoCorrect = { false }
label = { t('settingsView.email') } keyboardType = { 'email-address' }
mode = 'outlined' label = { t('settingsView.email') }
onChangeText = { this._onChangeEmail } mode = 'outlined'
placeholder = 'email@example.com' onChangeText = { this._onChangeEmail }
placeholderTextColor = { PLACEHOLDER_TEXT_COLOR } placeholder = 'email@example.com'
spellCheck = { false } placeholderTextColor = { PLACEHOLDER_TEXT_COLOR }
style = { styles.textInputContainer } spellCheck = { false }
textContentType = { 'emailAddress' } // iOS only style = { styles.textInputContainer }
theme = { textInputTheme } textContentType = { 'emailAddress' } // iOS only
value = { email } /> theme = { textInputTheme }
</FormSectionAccordion> value = { email } />
<FormSectionAccordion </FormSectionAccordion>
label = 'settingsView.conferenceSection'> <FormSectionAccordion
<TextInput label = 'settingsView.conferenceSection'>
autoCapitalize = 'none' <TextInput
autoCorrect = { false } autoCapitalize = 'none'
editable = { this.props._serverURLChangeEnabled } autoCorrect = { false }
keyboardType = { 'url' } editable = { this.props._serverURLChangeEnabled }
label = { t('settingsView.serverURL') } keyboardType = { 'url' }
mode = 'outlined' label = { t('settingsView.serverURL') }
onBlur = { this._onBlurServerURL } mode = 'outlined'
onChangeText = { this._onChangeServerURL } onBlur = { this._onBlurServerURL }
placeholder = { this.props._serverURL } onChangeText = { this._onChangeServerURL }
placeholderTextColor = { PLACEHOLDER_TEXT_COLOR } placeholder = { this.props._serverURL }
spellCheck = { false } placeholderTextColor = { PLACEHOLDER_TEXT_COLOR }
style = { styles.textInputContainer } spellCheck = { false }
textContentType = { 'URL' } // iOS only style = { styles.textInputContainer }
theme = { textInputTheme } textContentType = { 'URL' } // iOS only
value = { serverURL } /> theme = { textInputTheme }
<Divider style = { styles.fieldSeparator } /> value = { serverURL } />
<FormRow label = 'settingsView.startCarModeInLowBandwidthMode'> <Divider style = { styles.fieldSeparator } />
<Switch <FormRow label = 'settingsView.startCarModeInLowBandwidthMode'>
checked = { startCarMode }
// @ts-ignore
onChange = { this._onStartCarmodeInLowBandwidthMode } />
</FormRow>
<Divider style = { styles.fieldSeparator } />
<FormRow
label = 'settingsView.startWithAudioMuted'>
<Switch
checked = { startWithAudioMuted }
// @ts-ignore
onChange = { this._onStartAudioMutedChange } />
</FormRow>
<Divider style = { styles.fieldSeparator } />
<FormRow label = 'settingsView.startWithVideoMuted'>
<Switch
checked = { startWithVideoMuted }
// @ts-ignore
onChange = { this._onStartVideoMutedChange } />
</FormRow>
<Divider style = { styles.fieldSeparator } />
<FormRow label = 'videothumbnail.hideSelfView'>
<Switch
checked = { disableSelfView }
// @ts-ignore
onChange = { this._onDisableSelfView } />
</FormRow>
</FormSectionAccordion>
<FormSectionAccordion
label = 'settingsView.links'>
<Link
style = { styles.sectionLink }
// @ts-ignore
to = {{ screen: screen.settings.links.help }}>
{ t('settingsView.help') }
</Link>
<Divider style = { styles.fieldSeparator } />
<Link
style = { styles.sectionLink }
// @ts-ignore
to = {{ screen: screen.settings.links.terms }}>
{ t('settingsView.terms') }
</Link>
<Divider style = { styles.fieldSeparator } />
<Link
style = { styles.sectionLink }
// @ts-ignore
to = {{ screen: screen.settings.links.privacy }}>
{ t('settingsView.privacy') }
</Link>
</FormSectionAccordion>
<FormSectionAccordion
label = 'settingsView.buildInfoSection'>
<FormRow
label = 'settingsView.version'>
<Text style = { styles.text }>
{`${AppInfo.version} build ${AppInfo.buildNumber}`}
</Text>
</FormRow>
</FormSectionAccordion>
<FormSectionAccordion
label = 'settingsView.advanced'>
{ Platform.OS === 'android' && (
<>
<FormRow
label = 'settingsView.disableCallIntegration'>
<Switch
checked = { disableCallIntegration }
// @ts-ignore
onChange = { this._onDisableCallIntegration } />
</FormRow>
<Divider style = { styles.fieldSeparator } />
</>
)}
<FormRow
label = 'settingsView.disableP2P'>
<Switch
checked = { disableP2P }
// @ts-ignore
onChange = { this._onDisableP2P } />
</FormRow>
<Divider style = { styles.fieldSeparator } />
{AppInfo.GOOGLE_SERVICES_ENABLED && (
<FormRow
fieldSeparator = { true }
label = 'settingsView.disableCrashReporting'>
<Switch <Switch
checked = { disableCrashReporting } checked = { startCarMode }
// @ts-ignore // @ts-ignore
onChange = { this._onDisableCrashReporting } /> onChange = { this._onStartCarmodeInLowBandwidthMode } />
</FormRow> </FormRow>
)} <Divider style = { styles.fieldSeparator } />
</FormSectionAccordion> <FormRow
label = 'settingsView.startWithAudioMuted'>
<Switch
checked = { startWithAudioMuted }
// @ts-ignore
onChange = { this._onStartAudioMutedChange } />
</FormRow>
<Divider style = { styles.fieldSeparator } />
<FormRow label = 'settingsView.startWithVideoMuted'>
<Switch
checked = { startWithVideoMuted }
// @ts-ignore
onChange = { this._onStartVideoMutedChange } />
</FormRow>
<Divider style = { styles.fieldSeparator } />
<FormRow label = 'videothumbnail.hideSelfView'>
<Switch
checked = { disableSelfView }
// @ts-ignore
onChange = { this._onDisableSelfView } />
</FormRow>
</FormSectionAccordion>
<FormSectionAccordion
label = 'settingsView.links'>
<Link
style = { styles.sectionLink }
// @ts-ignore
to = {{ screen: screen.settings.links.help }}>
{ t('settingsView.help') }
</Link>
<Divider style = { styles.fieldSeparator } />
<Link
style = { styles.sectionLink }
// @ts-ignore
to = {{ screen: screen.settings.links.terms }}>
{ t('settingsView.terms') }
</Link>
<Divider style = { styles.fieldSeparator } />
<Link
style = { styles.sectionLink }
// @ts-ignore
to = {{ screen: screen.settings.links.privacy }}>
{ t('settingsView.privacy') }
</Link>
</FormSectionAccordion>
<FormSectionAccordion
label = 'settingsView.buildInfoSection'>
<FormRow
label = 'settingsView.version'>
<Text style = { styles.text }>
{`${AppInfo.version} build ${AppInfo.buildNumber}`}
</Text>
</FormRow>
</FormSectionAccordion>
<FormSectionAccordion
label = 'settingsView.advanced'>
{ Platform.OS === 'android' && (
<>
<FormRow
label = 'settingsView.disableCallIntegration'>
<Switch
checked = { disableCallIntegration }
// @ts-ignore
onChange = { this._onDisableCallIntegration } />
</FormRow>
<Divider style = { styles.fieldSeparator } />
</>
)}
<FormRow
label = 'settingsView.disableP2P'>
<Switch
checked = { disableP2P }
// @ts-ignore
onChange = { this._onDisableP2P } />
</FormRow>
<Divider style = { styles.fieldSeparator } />
{AppInfo.GOOGLE_SERVICES_ENABLED && (
<FormRow
fieldSeparator = { true }
label = 'settingsView.disableCrashReporting'>
<Switch
checked = { disableCrashReporting }
// @ts-ignore
onChange = { this._onDisableCrashReporting } />
</FormRow>
)}
</FormSectionAccordion>
</ScrollView>
</JitsiScreen> </JitsiScreen>
); );
} }