[IMPROVEMENT] Add loading message on long running tasks (#1798)
Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
parent
ea4f3797ff
commit
b67d1dd73d
|
@ -1,10 +1,11 @@
|
||||||
import * as types from '../constants/types';
|
import * as types from '../constants/types';
|
||||||
import { APP } from './actionsTypes';
|
import { APP } from './actionsTypes';
|
||||||
|
|
||||||
export function appStart(root) {
|
export function appStart(root, text) {
|
||||||
return {
|
return {
|
||||||
type: APP.START,
|
type: APP.START,
|
||||||
root
|
root,
|
||||||
|
text
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,7 @@ export default {
|
||||||
Click_to_join: 'Click to Join!',
|
Click_to_join: 'Click to Join!',
|
||||||
Close: 'Close',
|
Close: 'Close',
|
||||||
Close_emoji_selector: 'Close emoji selector',
|
Close_emoji_selector: 'Close emoji selector',
|
||||||
|
Change_language_loading: 'Changing language.',
|
||||||
Choose: 'Choose',
|
Choose: 'Choose',
|
||||||
Choose_from_library: 'Choose from library',
|
Choose_from_library: 'Choose from library',
|
||||||
Choose_file: 'Choose file',
|
Choose_file: 'Choose file',
|
||||||
|
@ -150,6 +151,7 @@ export default {
|
||||||
Permalink: 'Permalink',
|
Permalink: 'Permalink',
|
||||||
Certificate_password: 'Certificate Password',
|
Certificate_password: 'Certificate Password',
|
||||||
Clear_cache: 'Clear local server cache',
|
Clear_cache: 'Clear local server cache',
|
||||||
|
Clear_cache_loading: 'Clearing cache.',
|
||||||
Whats_the_password_for_your_certificate: 'What\'s the password for your certificate?',
|
Whats_the_password_for_your_certificate: 'What\'s the password for your certificate?',
|
||||||
Create_account: 'Create an account',
|
Create_account: 'Create an account',
|
||||||
Create_Channel: 'Create Channel',
|
Create_Channel: 'Create Channel',
|
||||||
|
@ -235,6 +237,7 @@ export default {
|
||||||
Login: 'Login',
|
Login: 'Login',
|
||||||
Login_error: 'Your credentials were rejected! Please try again.',
|
Login_error: 'Your credentials were rejected! Please try again.',
|
||||||
Login_with: 'Login with',
|
Login_with: 'Login with',
|
||||||
|
Logging_out: 'Logging out.',
|
||||||
Logout: 'Logout',
|
Logout: 'Logout',
|
||||||
Max_number_of_uses: 'Max number of uses',
|
Max_number_of_uses: 'Max number of uses',
|
||||||
members: 'members',
|
members: 'members',
|
||||||
|
@ -301,6 +304,7 @@ export default {
|
||||||
pinned: 'pinned',
|
pinned: 'pinned',
|
||||||
Pinned: 'Pinned',
|
Pinned: 'Pinned',
|
||||||
Please_enter_your_password: 'Please enter your password',
|
Please_enter_your_password: 'Please enter your password',
|
||||||
|
Please_wait: 'Please wait.',
|
||||||
Preferences: 'Preferences',
|
Preferences: 'Preferences',
|
||||||
Preferences_saved: 'Preferences saved!',
|
Preferences_saved: 'Preferences saved!',
|
||||||
Privacy_Policy: ' Privacy Policy',
|
Privacy_Policy: ' Privacy Policy',
|
||||||
|
|
|
@ -128,7 +128,9 @@ export default {
|
||||||
Channel_Name: 'Nome do Canal',
|
Channel_Name: 'Nome do Canal',
|
||||||
Channels: 'Canais',
|
Channels: 'Canais',
|
||||||
Chats: 'Conversas',
|
Chats: 'Conversas',
|
||||||
|
Change_language_loading: 'Alterando idioma.',
|
||||||
Call_already_ended: 'A chamada já terminou!',
|
Call_already_ended: 'A chamada já terminou!',
|
||||||
|
Clear_cache_loading: 'Limpando cache.',
|
||||||
Click_to_join: 'Clique para participar!',
|
Click_to_join: 'Clique para participar!',
|
||||||
Close: 'Fechar',
|
Close: 'Fechar',
|
||||||
Close_emoji_selector: 'Fechar seletor de emojis',
|
Close_emoji_selector: 'Fechar seletor de emojis',
|
||||||
|
@ -222,6 +224,7 @@ export default {
|
||||||
Login_error: 'Suas credenciais foram rejeitadas. Tente novamente por favor!',
|
Login_error: 'Suas credenciais foram rejeitadas. Tente novamente por favor!',
|
||||||
Login_with: 'Login with',
|
Login_with: 'Login with',
|
||||||
Logout: 'Sair',
|
Logout: 'Sair',
|
||||||
|
Logging_out: 'Saindo.',
|
||||||
Max_number_of_uses: 'Número máximo de usos',
|
Max_number_of_uses: 'Número máximo de usos',
|
||||||
Members: 'Membros',
|
Members: 'Membros',
|
||||||
Mentioned_Messages: 'Mensagens mencionadas',
|
Mentioned_Messages: 'Mensagens mencionadas',
|
||||||
|
@ -276,6 +279,7 @@ export default {
|
||||||
Pinned_Messages: 'Mensagens Fixadas',
|
Pinned_Messages: 'Mensagens Fixadas',
|
||||||
pinned: 'fixada',
|
pinned: 'fixada',
|
||||||
Pinned: 'Mensagens Fixadas',
|
Pinned: 'Mensagens Fixadas',
|
||||||
|
Please_wait: 'Por favor, aguarde.',
|
||||||
Please_enter_your_password: 'Por favor, digite sua senha',
|
Please_enter_your_password: 'Por favor, digite sua senha',
|
||||||
Preferences: 'Preferências',
|
Preferences: 'Preferências',
|
||||||
Preferences_saved: 'Preferências salvas!',
|
Preferences_saved: 'Preferências salvas!',
|
||||||
|
|
|
@ -110,7 +110,7 @@ const restore = function* restore() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const start = function* start({ root }) {
|
const start = function* start({ root, text }) {
|
||||||
if (root === 'inside') {
|
if (root === 'inside') {
|
||||||
yield Navigation.navigate('InsideStack');
|
yield Navigation.navigate('InsideStack');
|
||||||
} else if (root === 'setUsername') {
|
} else if (root === 'setUsername') {
|
||||||
|
@ -118,7 +118,7 @@ const start = function* start({ root }) {
|
||||||
} else if (root === 'outside') {
|
} else if (root === 'outside') {
|
||||||
yield Navigation.navigate('OutsideStack');
|
yield Navigation.navigate('OutsideStack');
|
||||||
} else if (root === 'loading') {
|
} else if (root === 'loading') {
|
||||||
yield Navigation.navigate('AuthLoading');
|
yield Navigation.navigate('AuthLoading', { text });
|
||||||
}
|
}
|
||||||
RNBootSplash.hide();
|
RNBootSplash.hide();
|
||||||
};
|
};
|
||||||
|
|
|
@ -147,7 +147,7 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLogout = function* handleLogout({ forcedByServer }) {
|
const handleLogout = function* handleLogout({ forcedByServer }) {
|
||||||
yield put(appStart('loading'));
|
yield put(appStart('loading', I18n.t('Logging_out')));
|
||||||
const server = yield select(getServer);
|
const server = yield select(getServer);
|
||||||
if (server) {
|
if (server) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,10 +1,40 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
View, Text, StyleSheet, ActivityIndicator
|
||||||
|
} from 'react-native';
|
||||||
|
|
||||||
|
import I18n from '../i18n';
|
||||||
import StatusBar from '../containers/StatusBar';
|
import StatusBar from '../containers/StatusBar';
|
||||||
import { withTheme } from '../theme';
|
import { withTheme } from '../theme';
|
||||||
|
import { themes } from '../constants/colors';
|
||||||
|
|
||||||
export default React.memo(withTheme(({ 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} />
|
<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>
|
||||||
|
);
|
||||||
|
}));
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { SafeAreaView } from 'react-navigation';
|
||||||
|
|
||||||
import RocketChat from '../../lib/rocketchat';
|
import RocketChat from '../../lib/rocketchat';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import Loading from '../../containers/Loading';
|
|
||||||
import { showErrorAlert } from '../../utils/info';
|
import { showErrorAlert } from '../../utils/info';
|
||||||
import log from '../../utils/log';
|
import log from '../../utils/log';
|
||||||
import { setUser as setUserAction } from '../../actions/login';
|
import { setUser as setUserAction } from '../../actions/login';
|
||||||
|
@ -75,13 +74,12 @@ class LanguageView extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
language: props.user ? props.user.language : 'en',
|
language: props.user ? props.user.language : 'en'
|
||||||
saving: false
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
const { language, saving } = this.state;
|
const { language } = this.state;
|
||||||
const { user, theme } = this.props;
|
const { user, theme } = this.props;
|
||||||
if (nextProps.theme !== theme) {
|
if (nextProps.theme !== theme) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -89,9 +87,6 @@ class LanguageView extends React.Component {
|
||||||
if (nextState.language !== language) {
|
if (nextState.language !== language) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (nextState.saving !== saving) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (nextProps.user.language !== user.language) {
|
if (nextProps.user.language !== user.language) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -108,9 +103,18 @@ class LanguageView extends React.Component {
|
||||||
return;
|
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 = {};
|
const params = {};
|
||||||
|
|
||||||
|
@ -135,15 +139,10 @@ class LanguageView extends React.Component {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await appStart('loading');
|
|
||||||
await appStart('inside');
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t('saving_preferences') }));
|
showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t('saving_preferences') }));
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ saving: false });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSeparator = () => {
|
renderSeparator = () => {
|
||||||
|
@ -174,7 +173,6 @@ class LanguageView extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { saving } = this.state;
|
|
||||||
const { theme } = this.props;
|
const { theme } = this.props;
|
||||||
return (
|
return (
|
||||||
<SafeAreaView
|
<SafeAreaView
|
||||||
|
@ -196,7 +194,6 @@ class LanguageView extends React.Component {
|
||||||
renderItem={this.renderItem}
|
renderItem={this.renderItem}
|
||||||
ItemSeparatorComponent={this.renderSeparator}
|
ItemSeparatorComponent={this.renderSeparator}
|
||||||
/>
|
/>
|
||||||
<Loading visible={saving} />
|
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +205,7 @@ const mapStateToProps = state => ({
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
setUser: params => dispatch(setUserAction(params)),
|
setUser: params => dispatch(setUserAction(params)),
|
||||||
appStart: params => dispatch(appStartAction(params))
|
appStart: (...params) => dispatch(appStartAction(...params))
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(LanguageView));
|
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(LanguageView));
|
||||||
|
|
|
@ -108,7 +108,7 @@ class SettingsView extends React.Component {
|
||||||
const {
|
const {
|
||||||
server: { server }, loginRequest, token, appStart
|
server: { server }, loginRequest, token, appStart
|
||||||
} = this.props;
|
} = this.props;
|
||||||
await appStart('loading');
|
await appStart('loading', I18n.t('Clear_cache_loading'));
|
||||||
await RocketChat.clearCache({ server });
|
await RocketChat.clearCache({ server });
|
||||||
await loginRequest({ resume: token }, true);
|
await loginRequest({ resume: token }, true);
|
||||||
}
|
}
|
||||||
|
@ -350,7 +350,7 @@ const mapDispatchToProps = dispatch => ({
|
||||||
logout: () => dispatch(logoutAction()),
|
logout: () => dispatch(logoutAction()),
|
||||||
loginRequest: (...params) => dispatch(loginRequestAction(...params)),
|
loginRequest: (...params) => dispatch(loginRequestAction(...params)),
|
||||||
toggleCrashReport: params => dispatch(toggleCrashReportAction(params)),
|
toggleCrashReport: params => dispatch(toggleCrashReportAction(params)),
|
||||||
appStart: params => dispatch(appStartAction(params))
|
appStart: (...params) => dispatch(appStartAction(...params))
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(withSplit(SettingsView)));
|
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(withSplit(SettingsView)));
|
||||||
|
|
Loading…
Reference in New Issue