From 65815745f314d76dd164ba7d69c58ff3296b75b4 Mon Sep 17 00:00:00 2001 From: Manbeartrain Date: Tue, 29 Nov 2022 19:16:54 -0700 Subject: [PATCH 1/3] Added localization --- template/App.js | 8 +++++ template/ios/Podfile.lock | 6 ++++ template/package.json | 4 +++ template/src/hooks/useLocalize.js | 36 +++++++++++++++++++ .../src/navigation/BottomTabNavigation.js | 33 +++++++++++------ template/src/screens/HomeScreen.js | 17 +++++++-- template/src/utils/translations/en.json | 4 +++ template/src/utils/translations/es.json | 4 +++ .../src/utils/translations/translations.js | 4 +++ template/yarn.lock | 15 ++++++++ 10 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 template/src/hooks/useLocalize.js create mode 100644 template/src/utils/translations/en.json create mode 100644 template/src/utils/translations/es.json create mode 100644 template/src/utils/translations/translations.js diff --git a/template/App.js b/template/App.js index 9b39d3e..e292891 100644 --- a/template/App.js +++ b/template/App.js @@ -8,10 +8,18 @@ import { persistStore } from "redux-persist"; import Navigation from "./src/navigation/Navigation"; import store from "./src/redux/store"; +import useLocalize from "./src/hooks/useLocalize"; +import { useEffect } from "react"; const persistor = persistStore(store); const App = () => { + const { setI18nConfig } = useLocalize(); + + useEffect(() => { + setI18nConfig(); + }, [setI18nConfig]); + return ( diff --git a/template/ios/Podfile.lock b/template/ios/Podfile.lock index cc5bfc3..f72f744 100644 --- a/template/ios/Podfile.lock +++ b/template/ios/Podfile.lock @@ -364,6 +364,8 @@ PODS: - React-Core - RNGestureHandler (2.6.0): - React-Core + - RNLocalize (2.2.4): + - React-Core - RNReanimated (2.10.0): - DoubleConversion - FBLazyVector @@ -461,6 +463,7 @@ DEPENDENCIES: - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) + - RNLocalize (from `../node_modules/react-native-localize`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`) @@ -556,6 +559,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-async-storage/async-storage" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" + RNLocalize: + :path: "../node_modules/react-native-localize" RNReanimated: :path: "../node_modules/react-native-reanimated" RNScreens: @@ -615,6 +620,7 @@ SPEC CHECKSUMS: ReactCommon: 8f67bd7e0a6afade0f20718f859dc8c2275f2e83 RNCAsyncStorage: 0c357f3156fcb16c8589ede67cc036330b6698ca RNGestureHandler: 920eb17f5b1e15dae6e5ed1904045f8f90e0b11e + RNLocalize: 0df7970cfc60389f00eb62fd7c097dc75af3fb4f RNReanimated: 7faa787e8d4493fbc95fab2ad331fa7625828cfa RNScreens: 0df01424e9e0ed7827200d6ed1087ddd06c493f9 RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8 diff --git a/template/package.json b/template/package.json index a66d564..5a881f8 100644 --- a/template/package.json +++ b/template/package.json @@ -29,12 +29,16 @@ "@reduxjs/toolkit": "^1.8.5", "add": "^2.0.6", "axios": "^0.27.2", + "i18n-js": "3.9.2", + "lodash": "^4.17.21", + "lodash.memoize": "4.1.2", "lottie-react-native": "^5.1.4", "nativewind": "^2.0.10", "react": "18.0.0", "react-native": "0.69.4", "react-native-gesture-handler": "^2.6.0", "react-native-keyboard-aware-scroll-view": "^0.9.5", + "react-native-localize": "^2.2.4", "react-native-reanimated": "^2.10.0", "react-native-safe-area-context": "^4.3.3", "react-native-screens": "^3.16.0", diff --git a/template/src/hooks/useLocalize.js b/template/src/hooks/useLocalize.js new file mode 100644 index 0000000..d2e7cad --- /dev/null +++ b/template/src/hooks/useLocalize.js @@ -0,0 +1,36 @@ +import { I18nManager } from "react-native"; +import * as RNLocalize from "react-native-localize"; + +import i18n from "i18n-js"; +import memoize from "lodash.memoize"; + +const translationGetters = { + en: () => require("../utils/translations/en.json"), + es: () => require("../utils/translations/es.json") + // add lanugauges you want to support here +}; + +const translate = memoize( + (key, config) => i18n.t(key, config), + (key, config) => (config ? key + JSON.stringify(config) : key) +); + +export default function useLocalize() { + const setI18nConfig = () => { + const fallback = { languageTag: "en", isRTL: false }; + + const { languageTag, isRTL } = + RNLocalize.findBestAvailableLanguage(Object.keys(translationGetters)) || + fallback; + + translate.cache.clear(); + + I18nManager.forceRTL(isRTL); + + i18n.translations = { [languageTag]: translationGetters[languageTag]() }; + + i18n.locale = languageTag; + }; + + return { setI18nConfig, translate }; +} diff --git a/template/src/navigation/BottomTabNavigation.js b/template/src/navigation/BottomTabNavigation.js index 33b5fc5..e300d0e 100644 --- a/template/src/navigation/BottomTabNavigation.js +++ b/template/src/navigation/BottomTabNavigation.js @@ -2,20 +2,33 @@ import React from "react"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import PropTypes from "prop-types"; -import { BOTTOM_TAB_SCREENS } from "../utils/screens"; +import useLocalize from "../hooks/useLocalize"; import HomeScreen from "../screens/HomeScreen"; +import { BOTTOM_TAB_SCREENS } from "../utils/screens"; +import { TRANSLATIONS } from "../utils/translations/translations"; const Tab = createBottomTabNavigator(); -const BottomTabNavigation = () => ( - ({ - drawerPosition: "right", - headerLeft: false - })}> - - -); +const BottomTabNavigation = () => { + const { translate } = useLocalize(); + + return ( + ({ + drawerPosition: "right", + headerLeft: false + })} + > + + + ); +}; BottomTabNavigation.propTypes = { navigation: PropTypes.object diff --git a/template/src/screens/HomeScreen.js b/template/src/screens/HomeScreen.js index ec3bbbf..d01f290 100644 --- a/template/src/screens/HomeScreen.js +++ b/template/src/screens/HomeScreen.js @@ -1,15 +1,28 @@ import React from "react"; import { View } from "react-native"; - import { Button } from "@digital-art-dealers/react-native-component-lib"; + +import useLocalize from "../hooks/useLocalize"; +import { TRANSLATIONS } from "../utils/translations/translations"; +import { useLayoutEffect } from "react"; +import { useNavigation } from "@react-navigation/native"; + const HomeScreen = () => { + const navigation = useNavigation(); + const { translate } = useLocalize(); + + useLayoutEffect(() => { + navigation.setOptions({ + headerTitle: translate(TRANSLATIONS.MAIN) + }); + }, [navigation]); return (