Skip to content

Commit 025dcf7

Browse files
authored
Merge pull request #9895 from Expensify/jasper-updateGlobalOfflineIndicator
Update Global Offline Indicator
2 parents 96b263f + 695c643 commit 025dcf7

26 files changed

+1177
-1199
lines changed

src/components/OfflineIndicator.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import {View} from 'react-native';
3+
import PropTypes from 'prop-types';
34
import {withNetwork} from './OnyxProvider';
45
import networkPropTypes from './networkPropTypes';
56
import Icon from './Icon';
@@ -9,11 +10,15 @@ import Text from './Text';
910
import styles from '../styles/styles';
1011
import compose from '../libs/compose';
1112
import withLocalize, {withLocalizePropTypes} from './withLocalize';
13+
import withWindowDimensions from './withWindowDimensions';
1214

1315
const propTypes = {
1416
/** Information about the network */
1517
network: networkPropTypes.isRequired,
1618

19+
/** Is the window width narrow, like on a mobile device */
20+
isSmallScreenWidth: PropTypes.bool.isRequired,
21+
1722
...withLocalizePropTypes,
1823
};
1924

@@ -24,7 +29,7 @@ const OfflineIndicator = (props) => {
2429

2530
return (
2631
<View style={[
27-
styles.chatItemComposeSecondaryRowOffset,
32+
props.isSmallScreenWidth ? styles.offlineIndicatorMobile : styles.offlineIndicator,
2833
styles.flexRow,
2934
styles.alignItemsCenter]}
3035
>
@@ -44,6 +49,7 @@ OfflineIndicator.propTypes = propTypes;
4449
OfflineIndicator.displayName = 'OfflineIndicator';
4550

4651
export default compose(
52+
withWindowDimensions,
4753
withLocalize,
4854
withNetwork(),
4955
)(OfflineIndicator);

src/components/ScreenWrapper.js

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import _ from 'underscore';
22
import React from 'react';
33
import PropTypes from 'prop-types';
4-
import {View} from 'react-native';
4+
import {View, KeyboardAvoidingView} from 'react-native';
55
import {SafeAreaInsetsContext} from 'react-native-safe-area-context';
66
import {withOnyx} from 'react-native-onyx';
77
import styles from '../styles/styles';
@@ -15,6 +15,10 @@ import compose from '../libs/compose';
1515
import ONYXKEYS from '../ONYXKEYS';
1616
import CONST from '../CONST';
1717
import withNavigation from './withNavigation';
18+
import withWindowDimensions from './withWindowDimensions';
19+
import OfflineIndicator from './OfflineIndicator';
20+
import {withNetwork} from './OnyxProvider';
21+
import networkPropTypes from './networkPropTypes';
1822

1923
const propTypes = {
2024
/** Array of additional styles to add */
@@ -35,6 +39,13 @@ const propTypes = {
3539
// Called when navigated Screen's transition is finished.
3640
onTransitionEnd: PropTypes.func,
3741

42+
/** Is the window width narrow, like on a mobile device */
43+
isSmallScreenWidth: PropTypes.bool.isRequired,
44+
45+
/** The behavior to pass to the KeyboardAvoidingView, requires some trial and error depending on the layout/devices used.
46+
* Search 'switch(behavior)' in ./node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js for more context */
47+
keyboardAvoidingViewBehavior: PropTypes.oneOf(['padding', 'height', 'position']),
48+
3849
// react-navigation navigation object available to screen components
3950
navigation: PropTypes.shape({
4051
// Method to attach listener to Navigation state.
@@ -47,6 +58,9 @@ const propTypes = {
4758
willAlertModalBecomeVisible: PropTypes.bool,
4859
}),
4960

61+
/** Information about the network */
62+
network: networkPropTypes.isRequired,
63+
5064
};
5165

5266
const defaultProps = {
@@ -58,6 +72,7 @@ const defaultProps = {
5872
addListener: () => {},
5973
},
6074
modal: {},
75+
keyboardAvoidingViewBehavior: 'padding',
6176
};
6277

6378
class ScreenWrapper extends React.Component {
@@ -105,27 +120,36 @@ class ScreenWrapper extends React.Component {
105120
paddingStyle.paddingTop = paddingTop;
106121
}
107122

108-
if (this.props.includePaddingBottom) {
123+
// We always need the safe area padding bottom if we're showing the offline indicator since it is bottom-docked.
124+
if (this.props.includePaddingBottom || this.props.network.isOffline) {
109125
paddingStyle.paddingBottom = paddingBottom;
110126
}
111127

112128
return (
113-
<View style={[
114-
...this.props.style,
115-
styles.flex1,
116-
paddingStyle,
117-
]}
129+
<View
130+
style={[
131+
...this.props.style,
132+
styles.flex1,
133+
paddingStyle,
134+
]}
118135
>
119-
<HeaderGap />
120-
{// If props.children is a function, call it to provide the insets to the children.
121-
_.isFunction(this.props.children)
122-
? this.props.children({
123-
insets,
124-
didScreenTransitionEnd: this.state.didScreenTransitionEnd,
125-
})
126-
: this.props.children
127-
}
128-
<KeyboardShortcutsModal />
136+
<KeyboardAvoidingView style={[styles.w100, styles.h100]} behavior={this.props.keyboardAvoidingViewBehavior}>
137+
<HeaderGap />
138+
{// If props.children is a function, call it to provide the insets to the children.
139+
_.isFunction(this.props.children)
140+
? this.props.children({
141+
insets,
142+
didScreenTransitionEnd: this.state.didScreenTransitionEnd,
143+
})
144+
: this.props.children
145+
}
146+
<KeyboardShortcutsModal />
147+
{this.props.isSmallScreenWidth && this.props.network.isOffline && (
148+
<View style={styles.chatItemComposeSecondaryRow}>
149+
<OfflineIndicator />
150+
</View>
151+
)}
152+
</KeyboardAvoidingView>
129153
</View>
130154
);
131155
}}
@@ -139,9 +163,11 @@ ScreenWrapper.defaultProps = defaultProps;
139163

140164
export default compose(
141165
withNavigation,
166+
withWindowDimensions,
142167
withOnyx({
143168
modal: {
144169
key: ONYXKEYS.MODAL,
145170
},
146171
}),
172+
withNetwork(),
147173
)(ScreenWrapper);

src/pages/AddPersonalBankAccountPage.js

Lines changed: 57 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import AddPlaidBankAccount from '../components/AddPlaidBankAccount';
1313
import getPlaidOAuthReceivedRedirectURI from '../libs/getPlaidOAuthReceivedRedirectURI';
1414
import compose from '../libs/compose';
1515
import ONYXKEYS from '../ONYXKEYS';
16-
import KeyboardAvoidingView from '../components/KeyboardAvoidingView';
1716
import Text from '../components/Text';
1817
import styles from '../styles/styles';
1918
import Button from '../components/Button';
@@ -125,67 +124,65 @@ class AddPersonalBankAccountPage extends React.Component {
125124

126125
return (
127126
<ScreenWrapper>
128-
<KeyboardAvoidingView>
129-
<HeaderWithCloseButton
130-
title={this.props.translate('bankAccount.addBankAccount')}
131-
onCloseButtonPress={Navigation.goBack}
132-
shouldShowBackButton
133-
onBackButtonPress={Navigation.goBack}
134-
/>
135-
{success ? (
136-
<>
137-
<Text style={[styles.formSuccess, styles.mh5]}>
138-
{success}
139-
</Text>
140-
<View style={[styles.mh5, styles.mb5, styles.flex1, styles.justifyContentEnd]}>
141-
<Button
142-
success
143-
text={this.props.translate('common.continue')}
144-
onPress={() => Navigation.navigate(ROUTES.SETTINGS_PAYMENTS)}
145-
/>
146-
</View>
147-
</>
148-
) : (
149-
<FormScrollView>
150-
<View style={[styles.mh5, styles.mb5]}>
151-
<AddPlaidBankAccount
152-
onSelect={(params) => {
153-
this.setState({
154-
selectedPlaidBankAccount: params.selectedPlaidBankAccount,
155-
});
156-
}}
157-
onExitPlaid={Navigation.goBack}
158-
receivedRedirectURI={getPlaidOAuthReceivedRedirectURI()}
159-
/>
160-
{!_.isUndefined(this.state.selectedPlaidBankAccount) && (
161-
<View style={[styles.mb5]}>
162-
<TextInput
163-
label={this.props.translate('addPersonalBankAccountPage.enterPassword')}
164-
secureTextEntry
165-
value={this.state.password}
166-
autoCompleteType="password"
167-
textContentType="password"
168-
autoCapitalize="none"
169-
autoFocus={canFocusInputOnScreenFocus()}
170-
onChangeText={text => this.setState({password: text})}
171-
errorText={this.getErrorText('password')}
172-
hasError={this.getErrors().password}
173-
/>
174-
</View>
175-
)}
176-
</View>
127+
<HeaderWithCloseButton
128+
title={this.props.translate('bankAccount.addBankAccount')}
129+
onCloseButtonPress={Navigation.goBack}
130+
shouldShowBackButton
131+
onBackButtonPress={Navigation.goBack}
132+
/>
133+
{success ? (
134+
<>
135+
<Text style={[styles.formSuccess, styles.mh5]}>
136+
{success}
137+
</Text>
138+
<View style={[styles.mh5, styles.mb5, styles.flex1, styles.justifyContentEnd]}>
139+
<Button
140+
success
141+
text={this.props.translate('common.continue')}
142+
onPress={() => Navigation.navigate(ROUTES.SETTINGS_PAYMENTS)}
143+
/>
144+
</View>
145+
</>
146+
) : (
147+
<FormScrollView>
148+
<View style={[styles.mh5, styles.mb5]}>
149+
<AddPlaidBankAccount
150+
onSelect={(params) => {
151+
this.setState({
152+
selectedPlaidBankAccount: params.selectedPlaidBankAccount,
153+
});
154+
}}
155+
onExitPlaid={Navigation.goBack}
156+
receivedRedirectURI={getPlaidOAuthReceivedRedirectURI()}
157+
/>
177158
{!_.isUndefined(this.state.selectedPlaidBankAccount) && (
178-
<FormAlertWithSubmitButton
179-
isAlertVisible={Boolean(error)}
180-
buttonText={this.props.translate('common.saveAndContinue')}
181-
onSubmit={this.submit}
182-
message={error}
183-
isLoading={loading}
184-
/>
159+
<View style={[styles.mb5]}>
160+
<TextInput
161+
label={this.props.translate('addPersonalBankAccountPage.enterPassword')}
162+
secureTextEntry
163+
value={this.state.password}
164+
autoCompleteType="password"
165+
textContentType="password"
166+
autoCapitalize="none"
167+
autoFocus={canFocusInputOnScreenFocus()}
168+
onChangeText={text => this.setState({password: text})}
169+
errorText={this.getErrorText('password')}
170+
hasError={this.getErrors().password}
171+
/>
172+
</View>
185173
)}
186-
</FormScrollView>
187-
)}
188-
</KeyboardAvoidingView>
174+
</View>
175+
{!_.isUndefined(this.state.selectedPlaidBankAccount) && (
176+
<FormAlertWithSubmitButton
177+
isAlertVisible={Boolean(error)}
178+
buttonText={this.props.translate('common.saveAndContinue')}
179+
onSubmit={this.submit}
180+
message={error}
181+
isLoading={loading}
182+
/>
183+
)}
184+
</FormScrollView>
185+
)}
189186
</ScreenWrapper>
190187
);
191188
}

0 commit comments

Comments
 (0)