From a2d0f0dcf8534e52f3b411ee207a54cd25fb625e Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 2 Dec 2019 17:20:46 +0100 Subject: [PATCH] load language on startup --- src/component/drawerContent/view.js | 2 +- src/constants.js | 22 ++++++------ src/page/discover/view.js | 2 +- src/page/firstRun/index.js | 4 ++- src/page/firstRun/view.js | 52 ++++++++++++++++++++--------- src/page/settings/view.js | 4 +-- src/page/splash/index.js | 2 +- src/page/splash/view.js | 3 +- src/styles/channelSelector.js | 4 +++ src/styles/settings.js | 20 +++++++++-- 10 files changed, 80 insertions(+), 35 deletions(-) diff --git a/src/component/drawerContent/view.js b/src/component/drawerContent/view.js index ad655e4..959515e 100644 --- a/src/component/drawerContent/view.js +++ b/src/component/drawerContent/view.js @@ -138,7 +138,7 @@ class DrawerContent extends React.PureComponent { {groupNames[3] !== groupName && ( - {groupName} + {__(groupName)} )} {menuItems.map(item => { diff --git a/src/constants.js b/src/constants.js index 6cbd629..27f963e 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,3 +1,5 @@ +import { __ } from 'i18n'; + const SORT_BY_NEW = 'new'; const SORT_BY_HOT = 'hot'; const SORT_BY_TOP = 'top'; @@ -94,8 +96,8 @@ const Constants = { ROUTE_FILE: 'File', - ITEM_CREATE_A_CHANNEL: 'Create a channel...', - ITEM_ANONYMOUS: 'Publish anonymously', + ITEM_CREATE_A_CHANNEL: __('Create a channel...'), + ITEM_ANONYMOUS: __('Publish anonymously'), SUBSCRIPTIONS_VIEW_ALL: 'view_all', SUBSCRIPTIONS_VIEW_LATEST_FIRST: 'view_latest_first', @@ -114,17 +116,17 @@ const Constants = { TIME_ALL, CLAIM_SEARCH_SORT_BY_ITEMS: [ - { icon: 'fire-alt', name: SORT_BY_HOT, label: 'Trending content' }, - { icon: 'certificate', name: SORT_BY_NEW, label: 'New content' }, - { icon: 'chart-line', name: SORT_BY_TOP, label: 'Top content' }, + { icon: 'fire-alt', name: SORT_BY_HOT, label: __('Trending content') }, + { icon: 'certificate', name: SORT_BY_NEW, label: __('New content') }, + { icon: 'chart-line', name: SORT_BY_TOP, label: __('Top content') }, ], CLAIM_SEARCH_TIME_ITEMS: [ - { name: TIME_DAY, label: 'Past 24 hours' }, - { name: TIME_WEEK, label: 'Past week' }, - { name: TIME_MONTH, label: 'Past month' }, - { name: TIME_YEAR, label: 'Past year' }, - { name: TIME_ALL, label: 'All time' }, + { name: TIME_DAY, label: __('Past 24 hours') }, + { name: TIME_WEEK, label: __('Past week') }, + { name: TIME_MONTH, label: __('Past month') }, + { name: TIME_YEAR, label: __('Past year') }, + { name: TIME_ALL, label: __('All time') }, ], DEFAULT_ORDER_BY: ['trending_global', 'trending_mixed'], diff --git a/src/page/discover/view.js b/src/page/discover/view.js index ea47894..fe8b14a 100644 --- a/src/page/discover/view.js +++ b/src/page/discover/view.js @@ -256,7 +256,7 @@ class DiscoverPage extends React.PureComponent { return ( - Your tags + {__('Your Tags')} diff --git a/src/page/firstRun/index.js b/src/page/firstRun/index.js index e3ff6ac..819b68e 100644 --- a/src/page/firstRun/index.js +++ b/src/page/firstRun/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { doToast } from 'lbry-redux'; +import { SETTINGS, doToast } from 'lbry-redux'; import { doAuthenticate, doCheckSync, @@ -21,6 +21,7 @@ import { selectUser, } from 'lbryinc'; import { doSetClientSetting } from 'redux/actions/settings'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; import FirstRun from './view'; const select = state => ({ @@ -31,6 +32,7 @@ const select = state => ({ emailNewPending: selectEmailNewIsPending(state), hasSyncedWallet: selectHasSyncedWallet(state), getSyncIsPending: selectGetSyncIsPending(state), + language: makeSelectClientSetting(SETTINGS.LANGUAGE)(state), syncApplyErrorMessage: selectSyncApplyErrorMessage(state), syncApplyIsPending: selectSyncApplyIsPending(state), syncHash: selectSyncHash(state), diff --git a/src/page/firstRun/view.js b/src/page/firstRun/view.js index 7e2b15b..bb28897 100644 --- a/src/page/firstRun/view.js +++ b/src/page/firstRun/view.js @@ -11,6 +11,7 @@ import EmailCollectPage from './internal/email-collect-page'; import EmailVerifyPage from './internal/email-verify-page'; import SkipAccountPage from './internal/skip-account-page'; import firstRunStyle from 'styles/firstRun'; +import RNFS from 'react-native-fs'; class FirstRunScreen extends React.PureComponent { static pages = [ @@ -35,6 +36,7 @@ class FirstRunScreen extends React.PureComponent { showBottomContainer: false, walletPassword: '', syncApplyStarted: false, + languageLoaded: false, }; componentDidMount() { @@ -43,27 +45,46 @@ class FirstRunScreen extends React.PureComponent { this.setState({ launchUrl: url }); } }); + } - if (NativeModules.FirstRun) { - NativeModules.FirstRun.isFirstRun().then(firstRun => { - AsyncStorage.removeItem(Constants.KEY_FIRST_RUN_EMAIL); - AsyncStorage.removeItem(Constants.KEY_EMAIL_VERIFY_PENDING); - this.setState({ isFirstRun: firstRun }); + componentDidUpdate() { + const { language } = this.props; - if (firstRun) { - NativeModules.Firebase.setCurrentScreen('First Run'); - this.setState({ currentPage: FirstRunScreen.pages[0] }); - } else { - // Not the first run. Navigate to the splash screen right away - this.launchSplashScreen(); - } + if (language && !this.state.languageLoaded) { + this.setState({ languageLoaded: true }, () => { + // Load the current language setting before doing anything + const languageFile = RNFS.ExternalDirectoryPath + '/' + language + '.json'; + RNFS.readFile(languageFile, 'utf8') + .then(fileContents => { + const json = JSON.parse(fileContents); + window.language = language; + window.i18n_messages[language] = json; + this.checkFirstRun(); + }) + .catch(err => { + // language file doesn't exist? maintain the default language + this.checkFirstRun(); + }); }); - } else { - // The first run module was not detected. Go straight to the splash screen. - this.launchSplashScreen(); } } + checkFirstRun = () => { + NativeModules.FirstRun.isFirstRun().then(firstRun => { + AsyncStorage.removeItem(Constants.KEY_FIRST_RUN_EMAIL); + AsyncStorage.removeItem(Constants.KEY_EMAIL_VERIFY_PENDING); + this.setState({ isFirstRun: firstRun }); + + if (firstRun) { + NativeModules.Firebase.setCurrentScreen('First Run'); + this.setState({ currentPage: FirstRunScreen.pages[0] }); + } else { + // Not the first run. Navigate to the splash screen right away + this.launchSplashScreen(); + } + }); + }; + componentWillReceiveProps(nextProps) { const { emailNewErrorMessage, emailNewPending, syncApplyErrorMessage, syncApplyIsPending, user } = nextProps; const { notify, isApplyingSync, setClientSetting } = this.props; @@ -325,6 +346,7 @@ class FirstRunScreen extends React.PureComponent { emailNewErrorMessage, emailNewPending, emailToVerify, + language, notify, hasSyncedWallet, getSyncIsPending, diff --git a/src/page/settings/view.js b/src/page/settings/view.js index cf62aa6..c9069f0 100644 --- a/src/page/settings/view.js +++ b/src/page/settings/view.js @@ -96,8 +96,6 @@ class SettingsPage extends React.PureComponent { .then(j => { window.i18n_messages[language] = j; - console.log(window.i18n_messages); - // write the language file to the filesystem const langFilePath = RNFS.ExternalDirectoryPath + '/' + language + '.json'; RNFS.writeFile(langFilePath, JSON.stringify(j), 'utf8'); @@ -168,7 +166,7 @@ class SettingsPage extends React.PureComponent { {__('Language')} - + {__('Choose language')} diff --git a/src/page/splash/index.js b/src/page/splash/index.js index d402a70..f055135 100644 --- a/src/page/splash/index.js +++ b/src/page/splash/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { doBalanceSubscribe, doUpdateBlockHeight, doPopulateSharedUserState, doToast } from 'lbry-redux'; +import { SETTINGS, doBalanceSubscribe, doUpdateBlockHeight, doPopulateSharedUserState, doToast } from 'lbry-redux'; import { doAuthenticate, doBlackListedOutpointsSubscribe, diff --git a/src/page/splash/view.js b/src/page/splash/view.js index 48025ec..1fec63f 100644 --- a/src/page/splash/view.js +++ b/src/page/splash/view.js @@ -5,6 +5,7 @@ import { ActivityIndicator, DeviceEventEmitter, Linking, NativeModules, Platform import { NavigationActions, StackActions } from 'react-navigation'; import { decode as atob } from 'base-64'; import { navigateToUri, transformUrl } from 'utils/helper'; +import { __ } from 'i18n'; import moment from 'moment'; import AsyncStorage from '@react-native-community/async-storage'; import Button from 'component/button'; @@ -13,7 +14,7 @@ import PropTypes from 'prop-types'; import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import splashStyle from 'styles/splash'; -import { __ } from 'i18n'; +import RNFS from 'react-native-fs'; const BLOCK_HEIGHT_INTERVAL = 1000 * 60 * 2.5; // every 2.5 minutes diff --git a/src/styles/channelSelector.js b/src/styles/channelSelector.js index 92cfb54..86804a0 100644 --- a/src/styles/channelSelector.js +++ b/src/styles/channelSelector.js @@ -11,6 +11,10 @@ const channelSelectorStyle = StyleSheet.create({ height: 52, width: '100%', }, + channelPickerItem: { + fontFamily: 'Inter-UI-Regular', + fontSize: 16, + }, bidRow: { flex: 1, flexDirection: 'row', diff --git a/src/styles/settings.js b/src/styles/settings.js index bec203e..1ea6c81 100644 --- a/src/styles/settings.js +++ b/src/styles/settings.js @@ -29,10 +29,12 @@ const settingsStyle = StyleSheet.create({ justifyContent: 'center', }, pickerText: { - width: '50%', + width: '40%', }, pickerContainer: { - width: '50%', + width: '60%', + flexDirection: 'row', + justifyContent: 'flex-end', }, label: { fontSize: 14, @@ -60,6 +62,20 @@ const settingsStyle = StyleSheet.create({ sectionDivider: { marginTop: 24, }, + languagePicker: { + width: '85%', + }, + languagePickerItem: { + fontFamily: 'Inter-UI-Regular', + fontSize: 14, + }, + pickerRow: { + marginBottom: 24, + flex: 1, + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, }); export default settingsStyle;