Skip to content

Commit 24957c0

Browse files
author
Chris Bobbe
committed
LoadingBanner: Add, to show loading state and stale data simultaneously.
For zulip#3387, provide the component to be used to show a loading banner during the /register request. This will be much improved with an animation, but progress is blocked by zulip#3899. One idea is to give the exit animation a shorter duration than the entrance animation, to give the impression that we've been awaiting updates just as attentively as the user, and that we're eager to show the updates and get out of the way immediately.
1 parent 834ae9c commit 24957c0

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

src/common/LoadingBanner.js

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/* @flow strict-local */
2+
3+
import React, { PureComponent } from 'react';
4+
import { StyleSheet, View } from 'react-native';
5+
6+
import type { Dispatch } from '../types';
7+
import { connect } from '../react-redux';
8+
import { getLoading } from '../selectors';
9+
import { Label, LoadingIndicator } from '.';
10+
import type { ThemeColors } from '../styles';
11+
import { ThemeContext } from '../styles';
12+
13+
const key = 'LoadingBanner';
14+
15+
const styles = StyleSheet.create({
16+
block: {
17+
flexDirection: 'row',
18+
justifyContent: 'center',
19+
alignItems: 'center',
20+
backgroundColor: 'hsl(6, 98%, 57%)',
21+
},
22+
none: { display: 'none' },
23+
});
24+
25+
type SelectorProps = $ReadOnly<{|
26+
loading: boolean,
27+
|}>;
28+
29+
type Props = $ReadOnly<{|
30+
spinnerColor?: 'black' | 'white' | 'default',
31+
textColor?: string,
32+
backgroundColor?: string,
33+
34+
dispatch: Dispatch,
35+
...SelectorProps,
36+
|}>;
37+
38+
/**
39+
* Display a notice that the app is connecting to the server, when appropriate.
40+
*/
41+
class LoadingBanner extends PureComponent<Props> {
42+
static contextType = ThemeContext;
43+
context: ThemeColors;
44+
45+
render() {
46+
if (!this.props.loading) {
47+
return <View key={key} style={styles.none} />;
48+
}
49+
const {
50+
spinnerColor = 'default',
51+
textColor = this.context.color,
52+
backgroundColor = this.context.backgroundColor,
53+
} = this.props;
54+
const style = {
55+
width: '100%',
56+
flexDirection: 'row',
57+
justifyContent: 'center',
58+
alignItems: 'center',
59+
backgroundColor,
60+
};
61+
return (
62+
<View key={key} style={style}>
63+
<View>
64+
<LoadingIndicator size={14} color={spinnerColor} />
65+
</View>
66+
<Label
67+
style={{
68+
fontSize: 14,
69+
margin: 2,
70+
color: textColor,
71+
}}
72+
text="Connecting..."
73+
/>
74+
</View>
75+
);
76+
}
77+
}
78+
79+
export default connect<SelectorProps, _, _>(state => ({
80+
loading: getLoading(state),
81+
}))(LoadingBanner);

src/common/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export { default as KeyboardAvoider } from './KeyboardAvoider';
1515
export { default as Label } from './Label';
1616
export { default as LineSeparator } from './LineSeparator';
1717
export { default as LoadingIndicator } from './LoadingIndicator';
18+
export { default as LoadingBanner } from './LoadingBanner';
1819
export { default as Logo } from './Logo';
1920
export { default as OfflineNotice } from './OfflineNotice';
2021
export { default as OptionButton } from './OptionButton';

0 commit comments

Comments
 (0)