[IMPROVEMENT] Add loading message on long running tasks (#1798)

Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Djorkaeff Alexandre 2020-02-28 17:11:08 -03:00 committed by GitHub
parent ea4f3797ff
commit b67d1dd73d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 65 additions and 29 deletions

View File

@ -1,10 +1,11 @@
import * as types from '../constants/types';
import { APP } from './actionsTypes';
export function appStart(root) {
export function appStart(root, text) {
return {
type: APP.START,
root
root,
text
};
}

View File

@ -130,6 +130,7 @@ export default {
Click_to_join: 'Click to Join!',
Close: 'Close',
Close_emoji_selector: 'Close emoji selector',
Change_language_loading: 'Changing language.',
Choose: 'Choose',
Choose_from_library: 'Choose from library',
Choose_file: 'Choose file',
@ -150,6 +151,7 @@ export default {
Permalink: 'Permalink',
Certificate_password: 'Certificate Password',
Clear_cache: 'Clear local server cache',
Clear_cache_loading: 'Clearing cache.',
Whats_the_password_for_your_certificate: 'What\'s the password for your certificate?',
Create_account: 'Create an account',
Create_Channel: 'Create Channel',
@ -235,6 +237,7 @@ export default {
Login: 'Login',
Login_error: 'Your credentials were rejected! Please try again.',
Login_with: 'Login with',
Logging_out: 'Logging out.',
Logout: 'Logout',
Max_number_of_uses: 'Max number of uses',
members: 'members',
@ -301,6 +304,7 @@ export default {
pinned: 'pinned',
Pinned: 'Pinned',
Please_enter_your_password: 'Please enter your password',
Please_wait: 'Please wait.',
Preferences: 'Preferences',
Preferences_saved: 'Preferences saved!',
Privacy_Policy: ' Privacy Policy',

View File

@ -128,7 +128,9 @@ export default {
Channel_Name: 'Nome do Canal',
Channels: 'Canais',
Chats: 'Conversas',
Change_language_loading: 'Alterando idioma.',
Call_already_ended: 'A chamada já terminou!',
Clear_cache_loading: 'Limpando cache.',
Click_to_join: 'Clique para participar!',
Close: 'Fechar',
Close_emoji_selector: 'Fechar seletor de emojis',
@ -222,6 +224,7 @@ export default {
Login_error: 'Suas credenciais foram rejeitadas. Tente novamente por favor!',
Login_with: 'Login with',
Logout: 'Sair',
Logging_out: 'Saindo.',
Max_number_of_uses: 'Número máximo de usos',
Members: 'Membros',
Mentioned_Messages: 'Mensagens mencionadas',
@ -276,6 +279,7 @@ export default {
Pinned_Messages: 'Mensagens Fixadas',
pinned: 'fixada',
Pinned: 'Mensagens Fixadas',
Please_wait: 'Por favor, aguarde.',
Please_enter_your_password: 'Por favor, digite sua senha',
Preferences: 'Preferências',
Preferences_saved: 'Preferências salvas!',

View File

@ -110,7 +110,7 @@ const restore = function* restore() {
}
};
const start = function* start({ root }) {
const start = function* start({ root, text }) {
if (root === 'inside') {
yield Navigation.navigate('InsideStack');
} else if (root === 'setUsername') {
@ -118,7 +118,7 @@ const start = function* start({ root }) {
} else if (root === 'outside') {
yield Navigation.navigate('OutsideStack');
} else if (root === 'loading') {
yield Navigation.navigate('AuthLoading');
yield Navigation.navigate('AuthLoading', { text });
}
RNBootSplash.hide();
};

View File

@ -147,7 +147,7 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
};
const handleLogout = function* handleLogout({ forcedByServer }) {
yield put(appStart('loading'));
yield put(appStart('loading', I18n.t('Logging_out')));
const server = yield select(getServer);
if (server) {
try {

View File

@ -1,10 +1,40 @@
import React from 'react';
import {
View, Text, StyleSheet, ActivityIndicator
} from 'react-native';
import I18n from '../i18n';
import StatusBar from '../containers/StatusBar';
import { withTheme } from '../theme';
import { themes } from '../constants/colors';
export default React.memo(withTheme(({ theme }) => (
<>
<StatusBar theme={theme} />
</>
)));
import sharedStyles from './Styles';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
text: {
fontSize: 16,
paddingTop: 10,
...sharedStyles.textRegular,
...sharedStyles.textAlignCenter
}
});
export default React.memo(withTheme(({ theme, navigation }) => {
const text = navigation.getParam('text');
return (
<View style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]}>
<StatusBar theme={theme} />
{text && (
<>
<ActivityIndicator color={themes[theme].auxiliaryText} size='large' />
<Text style={[styles.text, { color: themes[theme].bodyText }]}>{`${ text }.\n${ I18n.t('Please_wait') }`}</Text>
</>
)}
</View>
);
}));

View File

@ -6,7 +6,6 @@ import { SafeAreaView } from 'react-navigation';
import RocketChat from '../../lib/rocketchat';
import I18n from '../../i18n';
import Loading from '../../containers/Loading';
import { showErrorAlert } from '../../utils/info';
import log from '../../utils/log';
import { setUser as setUserAction } from '../../actions/login';
@ -75,13 +74,12 @@ class LanguageView extends React.Component {
constructor(props) {
super(props);
this.state = {
language: props.user ? props.user.language : 'en',
saving: false
language: props.user ? props.user.language : 'en'
};
}
shouldComponentUpdate(nextProps, nextState) {
const { language, saving } = this.state;
const { language } = this.state;
const { user, theme } = this.props;
if (nextProps.theme !== theme) {
return true;
@ -89,9 +87,6 @@ class LanguageView extends React.Component {
if (nextState.language !== language) {
return true;
}
if (nextState.saving !== saving) {
return true;
}
if (nextProps.user.language !== user.language) {
return true;
}
@ -108,9 +103,18 @@ class LanguageView extends React.Component {
return;
}
this.setState({ saving: true });
const { appStart } = this.props;
const { user, setUser, appStart } = this.props;
await appStart('loading', I18n.t('Change_language_loading'));
// shows loading for at least 300ms
await Promise.all([this.changeLanguage(language), new Promise(resolve => setTimeout(resolve, 300))]);
await appStart('inside');
}
changeLanguage = async(language) => {
const { user, setUser } = this.props;
const params = {};
@ -135,15 +139,10 @@ class LanguageView extends React.Component {
// do nothing
}
});
await appStart('loading');
await appStart('inside');
} catch (e) {
showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t('saving_preferences') }));
log(e);
}
this.setState({ saving: false });
}
renderSeparator = () => {
@ -174,7 +173,6 @@ class LanguageView extends React.Component {
}
render() {
const { saving } = this.state;
const { theme } = this.props;
return (
<SafeAreaView
@ -196,7 +194,6 @@ class LanguageView extends React.Component {
renderItem={this.renderItem}
ItemSeparatorComponent={this.renderSeparator}
/>
<Loading visible={saving} />
</SafeAreaView>
);
}
@ -208,7 +205,7 @@ const mapStateToProps = state => ({
const mapDispatchToProps = dispatch => ({
setUser: params => dispatch(setUserAction(params)),
appStart: params => dispatch(appStartAction(params))
appStart: (...params) => dispatch(appStartAction(...params))
});
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(LanguageView));

View File

@ -108,7 +108,7 @@ class SettingsView extends React.Component {
const {
server: { server }, loginRequest, token, appStart
} = this.props;
await appStart('loading');
await appStart('loading', I18n.t('Clear_cache_loading'));
await RocketChat.clearCache({ server });
await loginRequest({ resume: token }, true);
}
@ -350,7 +350,7 @@ const mapDispatchToProps = dispatch => ({
logout: () => dispatch(logoutAction()),
loginRequest: (...params) => dispatch(loginRequestAction(...params)),
toggleCrashReport: params => dispatch(toggleCrashReportAction(params)),
appStart: params => dispatch(appStartAction(params))
appStart: (...params) => dispatch(appStartAction(...params))
});
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(withSplit(SettingsView)));