Skip to content

Commit

Permalink
feat(i18n): added he, ja, pl, ru, tr, uk + rtl support
Browse files Browse the repository at this point in the history
  • Loading branch information
Guillaume Louvigny committed Jan 2, 2019
1 parent 3008215 commit c265ca1
Show file tree
Hide file tree
Showing 16 changed files with 927 additions and 31 deletions.
2 changes: 2 additions & 0 deletions client/react-native/common/components/Library/Header.js
Expand Up @@ -3,6 +3,7 @@ import React, { PureComponent } from 'react'
import { Button, Flex, Text, SearchBar } from '.'
import { colors } from '../../constants'
import { padding, borderBottom, paddingBottom } from '../../styles'
import { isRTL } from '../../i18n'

const [defaultTextColor, defaultBackColor] = [colors.black, colors.white]

Expand Down Expand Up @@ -74,6 +75,7 @@ export default class Header extends PureComponent {
}
navigation.goBack(null)
}}
flip={isRTL()}
justify='start'
middle
/>
Expand Down
7 changes: 4 additions & 3 deletions client/react-native/common/components/Library/Icon.js
Expand Up @@ -6,7 +6,7 @@ import React from 'react'

import { colors } from '../../constants'

const Icon = ({ name, color, rotate, src, style, ...props }) => {
const Icon = ({ name, color, rotate, src, style, flip, ...props }) => {
if (name == null) return null
const [type, iconName] = [
name.split('-', 1)[0],
Expand All @@ -19,9 +19,10 @@ const Icon = ({ name, color, rotate, src, style, ...props }) => {
name: iconName,
color: color || colors.textGrey,
style: [
rotate && {
{
transform: [
{ rotate: typeof rotate === 'boolean' ? '90deg' : `${rotate}deg` },
{ scaleX: typeof flip === 'boolean' && flip ? -1 : 1 },
{ rotate: typeof rotate === 'boolean' && rotate ? '90deg' : `${rotate || 0}deg` },
],
},
style,
Expand Down
2 changes: 2 additions & 0 deletions client/react-native/common/components/Library/Menu.js
Expand Up @@ -8,6 +8,7 @@ import {
padding,
} from '../../styles'
import { colors } from '../../constants'
import { isRTL } from '../../i18n'

export default class Menu extends Component {
static Header = ({ icon, title, description }) => (
Expand Down Expand Up @@ -138,6 +139,7 @@ export default class Menu extends Component {
right
bold={boldRight ? true : null}
justify='end'
flip={isRTL()}
/>
)}
{textRight && (
Expand Down
4 changes: 2 additions & 2 deletions client/react-native/common/components/Library/Text.js
Expand Up @@ -352,14 +352,14 @@ export class ForegroundText extends PureComponent {
}

render () {
const { icon, input, children, multiline, onSubmit } = this.props
const { icon, input, children, multiline, onSubmit, flip } = this.props
const numberOfLines = typeof multiline === 'number' ? multiline : undefined

const styles = ForegroundText.getStyles(this.props)
return (
<Fragment>
{icon && typeof icon === 'string' ? (
<Icon name={icon} style={styles.icon} />
<Icon name={icon} style={styles.icon} flip={flip} />
) : (
icon && <Flex.Rows style={styles.iconView}>{icon}</Flex.Rows>
)}
Expand Down
7 changes: 2 additions & 5 deletions client/react-native/common/components/Screens/Main.js
@@ -1,9 +1,7 @@
import { Animated, Easing, Platform } from 'react-native'
import { createStackNavigator } from 'react-navigation'
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation'
import React from 'react'

import createTabNavigator from 'react-navigation-deprecated-tab-navigator/src/createTabNavigator'

import { EventListFilterModal } from './Settings/Devtools/EventList'
import { Icon } from '../Library'
import { colors } from '../../constants'
Expand Down Expand Up @@ -31,7 +29,7 @@ const TabBarIcon = (tintColor, routeName, badgeValue) => {
)
}

export const tabs = createTabNavigator(
export const tabs = createBottomTabNavigator(
{
contacts: {
screen: Contacts,
Expand All @@ -56,7 +54,6 @@ export const tabs = createTabNavigator(
initialRouteName: 'chats',
swipeEnabled: false,
animationEnabled: true,
tabBarPosition: 'bottom',
navigationOptions: ({ navigation, screenProps }) => {
let badge = null

Expand Down
Expand Up @@ -20,7 +20,7 @@ class Language extends PureComponent {
<Menu.Section customMarginTop={1}>
{Object.entries(languages).map(([k, v]) => <Menu.Item
icon={this.props.lng === k ? 'check-circle' : 'circle'}
title={v}
title={`${v.localName} - ${v.englishName}`}
key={k}
onPress={() => this.setLanguage(k)}
/>
Expand Down
2 changes: 1 addition & 1 deletion client/react-native/common/i18n/en/messages.json
Expand Up @@ -123,7 +123,7 @@
"sent": "Sent",
"unknown": "Unknown"
},
"setting-up": "Setting up berty :)",
"setting-up": "Setting up Berty :)",
"qrcode": "QR Code",
"public-key": "Public Key",
"fingerprint": "Fingerprint",
Expand Down
139 changes: 139 additions & 0 deletions client/react-native/common/i18n/he/messages.json
@@ -0,0 +1,139 @@
{
"core": {
"initializing": "אתחול ליבה",
"account-listing": "משחזר משתמשים"
},
"daemon": {
"initializing": "מפעיל דימון"
},
"auth": {
"nickname-placeholder": "הכנס שם תצוגה",
"welcome-to-berty": "ברוך הבא לברטי",
"get-started": "כדי להתחיל, רק צריך שם",
"lets-chat": "בוא נתכתב!"
},
"settings": {
"title": "הגדרות",
"updates-check": "בדוק עבור עדכונים",
"my-account": "החשבון שלי",
"my-account-share": "שתף את החשבון שלי",
"dev-tools": "כלי מפתח",
"security-privacy": "אבטחה ופרטיות -לא מיושם",
"messages": "הגדרות הודעה -לא מיושם",
"notifications": "התראות",
"about": "אודות ברטי",
"news": "חדשות -לא מיושם",
"help": "עזרה",
"legal": "תנאים משפטיים",
"changelog": "דוח שינויים",
"version": "גרסת האפליקציה",
"learn-more": "גלה עוד אודות ברטי",
"contact-us": "צור אתנו קשר",
"faq": "שאלות נפוצות",
"app-credits": "ספריות צד שלישי",
"terms-of-service": "תנאי שירות",
"privacy-policy": "מדיניות הפרטיות",
"software-license": "רישוי תוכנה",
"update-build-date": "תאריך יסוד",
"update-branch": "סניף",
"update-version-hash": "גרסת האש",
"update-install": "התקן עדכון",
"update-latest-version-label": "גרסה אחרונה",
"update-installed-version-label": "גרסה מותקנת ({{channel}})",
"updates-no-available": "אין עדכון זמין",
"update-downloading": "מוריד עדכון אפליקציה",
"update-write-fail": "לא מצליח להוריד את האפליקציה, אי אפשר לרשום את הקובץ",
"update-write-perm": "שמור על דיסק חיצוני",
"update-write-perm-desc": "האישור הזה נדרש כדי להוריד את עדכון האפליקציה"
},
"chats": {
"title": "צ'טים",
"no-new-messages": "אין הודעות חדשות",
"new-conversation": "שיחה חדשה",
"new-message": "הודעה חדשה",
"add-members": "הוסף חברים",
"write-message": "רשום הודעה מאובטחת...",
"details": "פרטי השיחה",
"name": "שם",
"message-retention": "שימור הודעה -לא מיושם",
"notifications": "התראות",
"notifications-sound": "סאונד",
"notifications-enabled": "מאופשר",
"notifications-mute": "השתק שיחה",
"notifications-override": "התעלם מהתראות האפליקציה",
"notifications-preview": "צפייה ראשונית בהודעה",
"link-invite": "הזמן לקבוצה עם קישור -לא מיושם",
"delete": "Delete this conversation -לא מיושם"
},
"contacts": {
"title": "אנשי קשר",
"details": "פרטי אנשי קשר",
"add": {
"title": "הוסף איש קשר",
"pub-key-paste-here": "הדבק את המפתח הציבורי של משתמש ברטי כאן",
"pub-key-paste": "הדבק מפתח",
"pub-key-add": "הוסף את המפתח הזה",
"qrcode-not-from-berty": "זה לא קוד QR של ברטי",
"nearby": "קרוב",
"invite": "הזמן",
"invalid-public-key": "המפתח הציבור הזה לא נכון",
"invite-text": "הוסף {{displayName}} בברטי",
"invite-text-link": "השתמש בלינק הזה כדי להוסיף {{displayName}} בברטי {{url}}",
"invite-text-self": "הוסף אותי בברטי",
"invite-text-link-self": "השתמש בלינק הזה כדי להוסיף אותי בברטי {{url}}"
},
"statuses": {
"Unknown": "לא ידוע",
"IsFriend": "חבר",
"IsTrustedFriend": "חבר אמין",
"IsRequested": "בקשה נשלחה",
"RequestedMe": "בקשה התקבלה",
"IsBlocked": "חסום",
"Myself": "אני"
},
"first-name": "שם פרטי",
"last-name": "שם משפחה",
"add-action": "הוסף איש קשר",
"add-action-feedback": "בקשה נשלחה לחשבון הזה",
"accept-action": "קבל",
"accept-action-feedback": "בקשת איש קשר התקבלה",
"decline-action": "הסר",
"decline-action-feedback": "בקשת איש קשר נדחתה",
"resend-action": "שלח שוב",
"resend-action-feedback": "בקשת איש קשר נשלחה שוב",
"cancel-request-action": "הסר",
"cancel-request-action-feedback": "הזמנת משתמש הוסרה",
"block-confirm-question": "אתה בטוח שאתה רוצה לחסום את המשתמש הזה?",
"block-confirm-action": "חסום את המשתמש הזה",
"share-action": "שתף",
"save-qrcode-action": "שמור את קוד QR",
"copy-link-action": "העתק קישור",
"copy-pubkey-action": "העתק מפתח ציבורי",
"save-qrcode-action-feedback": "קוד ה-QR נוסף לגליל המצלמה שלך",
"copy-link-action-feedback": "קישור ההזמנה הועתק",
"copy-pubkey-action-feedback": "מפתח ציבורי הועתק",
"send-message": "שלח הודעה -לא מיושם",
"call": "צלצל -לא מיושם",
"view-pub-key": "צפה במפתח ציבורי",
"block": "חסום את המשתמש הזה",
"delete": "מחק את המשתמש הזה",
"all": "הכל",
"received": "התקבל",
"sent": "נשלח"
},
"setting-up": "מתחיל את ברטי (:",
"qrcode": "קוד QR",
"public-key": "מפתח ציבורי",
"fingerprint": "טביעת אצבע",
"cancel": "בטל",
"confirm": "אשר",
"search-placeholder": "חפש...",
"select-picture": "בחר תמונה",
"unexpected-error": "שגיאה לא צפויה התרחשה",
"restart": "איתחול",
"fatal-unexpected-error": "שגיאה לא צפויה התרחשה, בבקשה אתחל את האפליקציה",
"my-account": {
"title": "החשבון שלי",
"delete-my-account": "מחק את החשבון שלי -לא מיושם"
}
}
20 changes: 11 additions & 9 deletions client/react-native/common/i18n/index.js
@@ -1,19 +1,17 @@
import i18n from 'i18next'
import { reactI18nextModule } from 'react-i18next'
import ReactNativeLanguages from 'react-native-languages'
import { AsyncStorage } from 'react-native'

import en from './en/messages.json'
import fr from './fr/messages.json'
import { I18nManager, AsyncStorage } from 'react-native'

import { languages } from './languages'

I18nManager.allowRTL(true)

const isRTL = () => i18n.dir(i18n.language) === 'rtl'

const options = {
fallbackLng: 'en',
resources: {
en: { translation: en },
fr: { translation: fr },
},
resources: languages,
lng: ReactNativeLanguages.language,
interpolation: { escapeValue: false }, // not needed for react
react: {
Expand All @@ -25,6 +23,8 @@ const options = {
i18n
.use(reactI18nextModule) // passes i18n down to react-i18next
.init(options, () => {
I18nManager.forceRTL(isRTL())

AsyncStorage.getItem('@BertyApp:i18n-language', (err, language) => {
if (err) {
return
Expand All @@ -43,6 +43,8 @@ i18n.on('languageChanged', language => {
return
}

I18nManager.forceRTL(isRTL())

AsyncStorage.getItem('@BertyApp:i18n-language', (_, oldLanguage) => {
if (oldLanguage === language) {
return
Expand All @@ -53,4 +55,4 @@ i18n.on('languageChanged', language => {
})

export default i18n
export { languages }
export { languages, isRTL }
27 changes: 19 additions & 8 deletions client/react-native/common/i18n/index.web.js
@@ -1,18 +1,16 @@
import i18n from 'i18next'
import { reactI18nextModule } from 'react-i18next'
import LanguageDetector from 'i18next-browser-languagedetector'
import { languages } from './languages'
import { I18nManager } from 'react-native'

import en from './en/messages.json'
import fr from './fr/messages.json'
I18nManager.allowRTL(true)

export { languages } from './languages'
const isRTL = () => i18n.dir(i18n.language) === 'rtl'

const options = {
fallbackLng: 'en',
resources: {
en: { translation: en },
fr: { translation: fr },
},
resources: languages,
interpolation: { escapeValue: false }, // not needed for react
react: {
wait: true,
Expand All @@ -23,6 +21,19 @@ const options = {
i18n
.use(LanguageDetector)
.use(reactI18nextModule) // passes i18n down to react-i18next
.init(options)
.init(options, () => {
I18nManager.forceRTL(isRTL())
})

i18n.on('languageChanged', language => {
if (!languages.hasOwnProperty(language)) {
return
}

console.log(i18n.language)
console.log(i18n.dir(i18n.language))
I18nManager.forceRTL(isRTL())
})

export default i18n
export { languages, isRTL }

0 comments on commit c265ca1

Please sign in to comment.