import React from 'react'; import { FlatList } from 'react-native'; import RNRestart from 'react-native-restart'; import { connect } from 'react-redux'; import { appStart } from '../../actions/app'; import { setUser } from '../../actions/login'; import { themes } from '../../lib/constants'; import * as List from '../../containers/List'; import SafeAreaView from '../../containers/SafeAreaView'; import StatusBar from '../../containers/StatusBar'; import { IApplicationState, IBaseScreen, IUser, RootEnum } from '../../definitions'; import I18n, { isRTL, LANGUAGES } from '../../i18n'; import database from '../../lib/database'; import { getUserSelector } from '../../selectors/login'; import { SettingsStackParamList } from '../../stacks/types'; import { withTheme } from '../../theme'; import { showErrorAlert } from '../../lib/methods/helpers/info'; import log, { events, logEvent } from '../../lib/methods/helpers/log'; import { Services } from '../../lib/services'; interface ILanguageViewProps extends IBaseScreen { user: IUser; } interface ILanguageViewState { language: string; } class LanguageView extends React.Component { static navigationOptions = () => ({ title: I18n.t('Change_Language') }); constructor(props: ILanguageViewProps) { super(props); this.state = { language: props.user ? (props.user.language as string) : 'en' }; } shouldComponentUpdate(nextProps: ILanguageViewProps, nextState: ILanguageViewState) { const { language } = this.state; const { user, theme } = this.props; if (nextProps.theme !== theme) { return true; } if (nextState.language !== language) { return true; } if (nextProps.user.language !== user.language) { return true; } return false; } formIsChanged = (language: string) => { const { user } = this.props; return user.language !== language; }; submit = async (language: string) => { if (!this.formIsChanged(language)) { return; } const { dispatch, user } = this.props; const shouldRestart = isRTL(language) || isRTL(user.language); dispatch(appStart({ root: RootEnum.ROOT_LOADING, text: I18n.t('Change_language_loading') })); // shows loading for at least 300ms await Promise.all([this.changeLanguage(language), new Promise(resolve => setTimeout(resolve, 300))]); if (shouldRestart) { await RNRestart.Restart(); } else { dispatch(appStart({ root: RootEnum.ROOT_INSIDE })); } }; changeLanguage = async (language: string) => { logEvent(events.LANG_SET_LANGUAGE); const { user, dispatch } = this.props; const params: { language?: string } = {}; // language if (user.language !== language) { params.language = language; } try { await Services.saveUserPreferences(params); dispatch(setUser({ language: params.language })); const serversDB = database.servers; const usersCollection = serversDB.get('users'); await serversDB.write(async () => { try { const userRecord = await usersCollection.find(user.id); await userRecord.update(record => { record.language = params.language; }); } catch (e) { logEvent(events.LANG_SET_LANGUAGE_F); } }); } catch (e) { logEvent(events.LANG_SET_LANGUAGE_F); showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t('saving_preferences') })); log(e); } }; renderIcon = () => { const { theme } = this.props; return ; }; renderItem = ({ item }: { item: { value: string; label: string } }) => { const { value, label } = item; const { language } = this.state; const isSelected = language === value; return ( this.submit(value)} testID={`language-view-${value}`} right={() => (isSelected ? this.renderIcon() : null)} translateTitle={false} /> ); }; render() { return ( item.value} ListHeaderComponent={List.Separator} ListFooterComponent={List.Separator} contentContainerStyle={List.styles.contentContainerStyleFlatList} renderItem={this.renderItem} ItemSeparatorComponent={List.Separator} /> ); } } const mapStateToProps = (state: IApplicationState) => ({ user: getUserSelector(state) }); export default connect(mapStateToProps)(withTheme(LanguageView));