Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading banner during /register #3901

Merged
merged 11 commits into from
Mar 9, 2020
Merged
1 change: 0 additions & 1 deletion .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ rules:

# React Native. This plugin isn't included in the airbnb config, and
# nothing is enabled by default, so we enable its rules.
react-native/no-inline-styles: error
# react-native/no-unused-styles: error # This is buggy on the `this.styles` pattern.
# react-native/no-color-literals: error # TODO eliminate these and enable.

Expand Down
8 changes: 7 additions & 1 deletion src/account/AccountPickScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,13 @@ class AccountPickScreen extends PureComponent<Props> {
const { accounts, dispatch } = this.props;

return (
<Screen title="Pick account" centerContent padding canGoBack={this.canGoBack}>
<Screen
title="Pick account"
centerContent
padding
canGoBack={this.canGoBack}
shouldShowLoadingBanner={false}
>
<Centerer>
{accounts.length === 0 && <Logo />}
<AccountList
Expand Down
81 changes: 81 additions & 0 deletions src/common/LoadingBanner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* @flow strict-local */

import React, { PureComponent } from 'react';
import { StyleSheet, View } from 'react-native';

import type { Dispatch } from '../types';
import { connect } from '../react-redux';
import { getLoading } from '../selectors';
import { Label, LoadingIndicator } from '.';
import type { ThemeColors } from '../styles';
import { ThemeContext } from '../styles';

const key = 'LoadingBanner';

const styles = StyleSheet.create({
block: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'hsl(6, 98%, 57%)',
},
none: { display: 'none' },
});

type SelectorProps = $ReadOnly<{|
loading: boolean,
|}>;

type Props = $ReadOnly<{|
spinnerColor?: 'black' | 'white' | 'default',
textColor?: string,
backgroundColor?: string,

dispatch: Dispatch,
...SelectorProps,
|}>;

/**
* Display a notice that the app is connecting to the server, when appropriate.
*/
class LoadingBanner extends PureComponent<Props> {
static contextType = ThemeContext;
context: ThemeColors;

render() {
if (!this.props.loading) {
return <View key={key} style={styles.none} />;
}
const {
spinnerColor = 'default',
textColor = this.context.color,
backgroundColor = this.context.backgroundColor,
} = this.props;
const style = {
width: '100%',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor,
};
return (
<View key={key} style={style}>
<View>
<LoadingIndicator size={14} color={spinnerColor} />
</View>
<Label
style={{
fontSize: 14,
margin: 2,
color: textColor,
}}
text="Connecting..."
/>
</View>
);
}
}

export default connect<SelectorProps, _, _>(state => ({
loading: getLoading(state),
}))(LoadingBanner);
6 changes: 3 additions & 3 deletions src/common/LoadingIndicator.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ const styles = StyleSheet.create({
});

type Props = $ReadOnly<{|
color: string,
color: 'default' | 'black' | 'white',
showLogo: boolean,
size: number,
|}>;

/**
* Renders a loading indicator - light circle and a darker
* Renders a loading indicator - a faint circle and a bold
* quarter of a circle spinning around it. Optionally,
* a Zulip logo in the center.
*
Expand All @@ -37,7 +37,7 @@ type Props = $ReadOnly<{|
*/
export default class LoadingIndicator extends PureComponent<Props> {
static defaultProps = {
color: '82, 194, 175',
color: 'default',
showLogo: false,
size: 40,
};
Expand Down
5 changes: 5 additions & 0 deletions src/common/Screen.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { Context, Dimensions, LocalizableText, Dispatch } from '../types';
import { connect } from '../react-redux';
import KeyboardAvoider from './KeyboardAvoider';
import OfflineNotice from './OfflineNotice';
import LoadingBanner from './LoadingBanner';
import ZulipStatusBar from './ZulipStatusBar';
import { getSession } from '../selectors';
import ModalNavBar from '../nav/ModalNavBar';
Expand Down Expand Up @@ -43,6 +44,7 @@ type Props = $ReadOnly<{|
search: boolean,
autoFocus: boolean,
searchBarOnChange: (text: string) => void,
shouldShowLoadingBanner: boolean,

canGoBack: boolean,
+title: LocalizableText,
Expand Down Expand Up @@ -85,6 +87,7 @@ class Screen extends PureComponent<Props> {
search: false,
autoFocus: false,
searchBarOnChange: (text: string) => {},
shouldShowLoadingBanner: true,
gnprice marked this conversation as resolved.
Show resolved Hide resolved

canGoBack: true,
title: '',
Expand All @@ -104,6 +107,7 @@ class Screen extends PureComponent<Props> {
searchBarOnChange,
style,
title,
shouldShowLoadingBanner,
} = this.props;
const { styles: contextStyles } = this.context;

Expand All @@ -116,6 +120,7 @@ class Screen extends PureComponent<Props> {
<ModalNavBar canGoBack={canGoBack} title={title} />
)}
<OfflineNotice />
{shouldShowLoadingBanner && <LoadingBanner />}
<KeyboardAvoider
behavior="padding"
style={[componentStyles.wrapper, padding && styles.padding]}
Expand Down
16 changes: 13 additions & 3 deletions src/common/SpinningProgress.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { Image } from 'react-native';
import AnimatedRotateComponent from '../animation/AnimatedRotateComponent';
import spinningProgressImg from '../../static/img/spinning-progress.png';
import spinningProgressBlackImg from '../../static/img/spinning-progress-black.png';
import spinningProgressWhiteImg from '../../static/img/spinning-progress-white.png';

type Props = $ReadOnly<{|
color: string,
color: 'default' | 'black' | 'white',
size: number,
|}>;

Expand All @@ -17,14 +18,23 @@ type Props = $ReadOnly<{|
*
* This is a temporary replacement of the ART-based SpinningProgress.
*
* @prop color - The color of the circle. Works only for 'black' and 'default'.
* @prop color - The color of the circle.
* @prop size - Diameter of the circle in pixels.
*/
export default class SpinningProgress extends React.PureComponent<Props> {
render() {
const { color, size } = this.props;
const style = { width: size, height: size };
const source = color === '0, 0, 0' ? spinningProgressBlackImg : spinningProgressImg;
const source = (() => {
switch (color) {
case 'white':
return spinningProgressWhiteImg;
case 'black':
return spinningProgressBlackImg;
default:
return spinningProgressImg;
}
})();

return (
<AnimatedRotateComponent>
Expand Down
1 change: 1 addition & 0 deletions src/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { default as KeyboardAvoider } from './KeyboardAvoider';
export { default as Label } from './Label';
export { default as LineSeparator } from './LineSeparator';
export { default as LoadingIndicator } from './LoadingIndicator';
export { default as LoadingBanner } from './LoadingBanner';
gnprice marked this conversation as resolved.
Show resolved Hide resolved
export { default as Logo } from './Logo';
export { default as OfflineNotice } from './OfflineNotice';
export { default as OptionButton } from './OptionButton';
Expand Down
2 changes: 2 additions & 0 deletions src/main/HomeTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import UnreadCards from '../unread/UnreadCards';
import { doNarrow, navigateToSearch } from '../actions';
import IconUnreadMentions from '../nav/IconUnreadMentions';
import { BRAND_COLOR } from '../styles';
import { LoadingBanner } from '../common';

const styles = StyleSheet.create({
wrapper: {
Expand Down Expand Up @@ -61,6 +62,7 @@ class HomeTab extends PureComponent<Props> {
}}
/>
</View>
<LoadingBanner />
<UnreadCards />
</View>
);
Expand Down
48 changes: 37 additions & 11 deletions src/nav/ChatNavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import React, { PureComponent } from 'react';
import { View } from 'react-native';

import type { Dispatch, Narrow } from '../types';
import { LoadingBanner } from '../common';
import { connect } from '../react-redux';
import styles, { BRAND_COLOR } from '../styles';
import { BRAND_COLOR, NAVBAR_SIZE } from '../styles';
import Title from '../title/Title';
import NavButton from './NavButton';
import { DEFAULT_TITLE_BACKGROUND_COLOR, getTitleBackgroundColor } from '../title/titleSelectors';
Expand All @@ -31,19 +32,44 @@ class ChatNavBar extends PureComponent<Props> {
backgroundColor === DEFAULT_TITLE_BACKGROUND_COLOR
? BRAND_COLOR
: foregroundColorFromBackground(backgroundColor);
const spinnerColor =
backgroundColor === DEFAULT_TITLE_BACKGROUND_COLOR
? 'default'
: foregroundColorFromBackground(backgroundColor);

return (
<View style={[styles.navBar, { backgroundColor }]}>
<NavButton
name="arrow-left"
color={color}
onPress={() => {
dispatch(navigateBack());
}}
<View
style={{
borderColor: 'hsla(0, 0%, 50%, 0.25)',
borderBottomWidth: 1,
}}
>
<View
style={[
{
flexDirection: 'row',
height: NAVBAR_SIZE,
alignItems: 'center',
},
{ backgroundColor },
]}
>
<NavButton
name="arrow-left"
color={color}
onPress={() => {
dispatch(navigateBack());
}}
/>
<Title color={color} narrow={narrow} />
<ExtraButton color={color} narrow={narrow} />
<InfoButton color={color} narrow={narrow} />
</View>
<LoadingBanner
spinnerColor={spinnerColor}
backgroundColor={backgroundColor}
textColor={color}
/>
<Title color={color} narrow={narrow} />
<ExtraButton color={color} narrow={narrow} />
<InfoButton color={color} narrow={narrow} />
</View>
);
}
Expand Down
27 changes: 18 additions & 9 deletions src/nav/ModalNavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import React, { PureComponent } from 'react';
import { View } from 'react-native';

import type { Dispatch, Context, LocalizableText } from '../types';
import type { Dispatch, LocalizableText } from '../types';
import type { ThemeColors } from '../styles';
import styles, { ThemeContext, NAVBAR_SIZE } from '../styles';
import { connect } from '../react-redux';
import styles, { NAVBAR_SIZE } from '../styles';

import Label from '../common/Label';
import NavButton from './NavButton';
import { navigateBack } from '../actions';
Expand All @@ -17,22 +19,29 @@ type Props = $ReadOnly<{|
|}>;

class ModalNavBar extends PureComponent<Props> {
context: Context;

static contextTypes = {
styles: () => null,
};
static contextType = ThemeContext;
context: ThemeColors;

render() {
const { styles: contextStyles } = this.context;
const { dispatch, canGoBack, title } = this.props;
const textStyle = [
styles.navTitle,
canGoBack ? { marginRight: NAVBAR_SIZE } : { marginLeft: 16 },
];

return (
<View style={[contextStyles.navBar]}>
<View
style={[
{
borderColor: 'hsla(0, 0%, 50%, 0.25)',
flexDirection: 'row',
height: NAVBAR_SIZE,
alignItems: 'center',
borderBottomWidth: 1,
backgroundColor: this.context.backgroundColor,
},
]}
>
{canGoBack && (
<NavButton
name="arrow-left"
Expand Down
23 changes: 15 additions & 8 deletions src/nav/ModalSearchNavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import React, { PureComponent } from 'react';
import { View } from 'react-native';

import type { Dispatch, Context } from '../types';
import type { Dispatch } from '../types';
import type { ThemeColors } from '../styles';
import { ThemeContext, NAVBAR_SIZE } from '../styles';
import { connect } from '../react-redux';
import SearchInput from '../common/SearchInput';
import NavButton from './NavButton';
Expand All @@ -15,17 +17,22 @@ type Props = $ReadOnly<{|
|}>;

class ModalSearchNavBar extends PureComponent<Props> {
context: Context;

static contextTypes = {
styles: () => null,
};
static contextType = ThemeContext;
context: ThemeColors;

render() {
const { styles: contextStyles } = this.context;
const { dispatch, autoFocus, searchBarOnChange } = this.props;
return (
<View style={contextStyles.navBar}>
<View
style={{
borderColor: 'hsla(0, 0%, 50%, 0.25)',
flexDirection: 'row',
height: NAVBAR_SIZE,
alignItems: 'center',
borderBottomWidth: 1,
backgroundColor: this.context.backgroundColor,
}}
>
<NavButton
name="arrow-left"
onPress={() => {
Expand Down
Loading