1import { Picker } from '@react-native-picker/picker'; 2import * as Localization from 'expo-localization'; 3import i18n from 'i18n-js'; 4import chunk from 'lodash/chunk'; 5import React from 'react'; 6import { ScrollView, StyleSheet, Text, View } from 'react-native'; 7 8import HeadingText from '../components/HeadingText'; 9import ListButton from '../components/ListButton'; 10import MonoText from '../components/MonoText'; 11 12i18n.fallbacks = true; 13i18n.locale = Localization.locale; 14i18n.translations = { 15 en: { 16 phrase: 'Hello my friend', 17 default: 'English language only', 18 }, 19 ru: { 20 phrase: 'Привет мой друг', 21 }, 22}; 23 24interface State { 25 isoCurrencyCodes: any; 26 currentLocale: any; 27 preferredLocales: any; 28 locale?: string; 29} 30 31// See: https://github.com/expo/expo/pull/10229#discussion_r490961694 32// eslint-disable-next-line @typescript-eslint/ban-types 33export default class LocalizationScreen extends React.Component<{}, State> { 34 static navigationOptions = { 35 title: 'Localization', 36 }; 37 38 readonly state: State = { 39 currentLocale: Localization.locale, 40 preferredLocales: Localization.locales, 41 isoCurrencyCodes: Localization.isoCurrencyCodes, 42 }; 43 44 queryPreferredLocales = async () => { 45 const preferredLocales = Localization.locales; 46 const currentLocale = Localization.locale; 47 this.setState({ preferredLocales, currentLocale }); 48 }; 49 50 queryCurrencyCodes = async () => { 51 if (this.state.isoCurrencyCodes.length === 0) { 52 const isoCurrencyCodes = Localization.isoCurrencyCodes; 53 this.setState({ isoCurrencyCodes }); 54 } 55 }; 56 57 prettyFormatCurrency = () => { 58 let buffer = ''; 59 let seenCount = 0; 60 const sample = this.state.isoCurrencyCodes.slice(0, 100); 61 const grouped = chunk(sample, 10); 62 let drilldownIndex = 0; 63 let currentColumn = 0; 64 while (true) { 65 while (true) { 66 if (seenCount === sample.length) return buffer; 67 if (currentColumn === grouped.length) { 68 currentColumn = 0; 69 buffer += '\n'; 70 drilldownIndex++; 71 continue; 72 } 73 buffer += `${grouped[currentColumn][drilldownIndex]}\t`; 74 seenCount++; 75 currentColumn++; 76 } 77 } 78 }; 79 80 changeLocale = (locale: string) => { 81 i18n.locale = locale; 82 this.setState({ locale }); 83 }; 84 85 render() { 86 return ( 87 <ScrollView> 88 <View style={styles.container}> 89 <HeadingText>Current Locale</HeadingText> 90 <MonoText>{JSON.stringify(this.state.currentLocale, null, 2)}</MonoText> 91 92 <HeadingText>Locales in Preference Order</HeadingText> 93 <ListButton title="Show preferred Locales" onPress={this.queryPreferredLocales} /> 94 {this.state.preferredLocales && this.state.preferredLocales.length > 0 && ( 95 <MonoText>{JSON.stringify(this.state.preferredLocales, null, 2)}</MonoText> 96 )} 97 98 <HeadingText>Currency Codes</HeadingText> 99 <ListButton title="Show first 100 currency codes" onPress={this.queryCurrencyCodes} /> 100 {this.state.isoCurrencyCodes && this.state.isoCurrencyCodes.length > 0 && ( 101 <MonoText>{this.prettyFormatCurrency()}</MonoText> 102 )} 103 104 <HeadingText>Localization Table</HeadingText> 105 <Picker 106 style={styles.picker} 107 selectedValue={this.state.locale} 108 onValueChange={(value) => this.changeLocale(`${value}`)}> 109 <Picker.Item label=" English" value="en" /> 110 <Picker.Item label=" Russian" value="ru" /> 111 </Picker> 112 113 <MonoText>{JSON.stringify(Localization, null, 2)}</MonoText> 114 115 <View style={styles.languageBox}> 116 <View style={styles.row}> 117 <Text>Exists in Both: </Text> 118 <Text>{this.state.currentLocale ? i18n.t('phrase') : ''}</Text> 119 </View> 120 <View style={styles.row}> 121 <Text>Default Case Only: </Text> 122 <Text>{this.state.currentLocale ? i18n.t('default') : ''}</Text> 123 </View> 124 </View> 125 </View> 126 </ScrollView> 127 ); 128 } 129} 130const styles = StyleSheet.create({ 131 row: { 132 flexDirection: 'row', 133 justifyContent: 'space-between', 134 }, 135 languageBox: { 136 padding: 10, 137 borderWidth: 1, 138 }, 139 picker: { 140 borderWidth: 1, 141 padding: 0, 142 margin: 0, 143 }, 144 container: { 145 padding: 10, 146 }, 147}); 148