Browse Source

locale app

merge-requests/1/head
Eduard Makarov 2 years ago
parent
commit
944854cb95
  1. 1
      App.tsx
  2. 106
      package-lock.json
  3. 3
      package.json
  4. 25
      src/i18n/index.ts
  5. 1
      src/i18n/locales/en/index.ts
  6. 26
      src/i18n/locales/en/stepLocale.ts
  7. 2
      src/i18n/locales/index.ts
  8. 1
      src/i18n/locales/ua/index.ts
  9. 23
      src/i18n/locales/ua/stepLocaleUa.ts
  10. 5
      src/i18n/types/index.ts
  11. 11
      src/i18n/types/onBoarding.ts
  12. 2
      src/module/root/atoms/premiumGroupBtn.tsx
  13. 13
      src/module/root/components/contentOnboarding.tsx
  14. 21
      src/module/root/config/dataOnboarding.ts
  15. 13
      src/module/root/screens/languageSelect.tsx

1
App.tsx

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
import React, {useEffect} from 'react';
import SplashScreen from 'react-native-splash-screen';
import {Navigation} from './src/module/root';
import './src/i18n/index';
const App = () => {
useEffect(() => {
SplashScreen.hide();

106
package-lock.json generated

@ -10,7 +10,10 @@ @@ -10,7 +10,10 @@
"dependencies": {
"@react-navigation/native": "^6.0.11",
"@react-navigation/native-stack": "^6.7.0",
"i18next": "^21.8.14",
"i18next-react-native-async-storage": "^1.0.4",
"react": "17.0.2",
"react-i18next": "^11.18.1",
"react-native": "0.67.4",
"react-native-gesture-handler": "^2.5.0",
"react-native-safe-area-context": "^4.3.1",
@ -8264,6 +8267,14 @@ @@ -8264,6 +8267,14 @@
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
},
"node_modules/html-parse-stringify": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
"dependencies": {
"void-elements": "3.1.0"
}
},
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@ -8338,6 +8349,36 @@ @@ -8338,6 +8349,36 @@
"node": ">=8.12.0"
}
},
"node_modules/i18next": {
"version": "21.8.14",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-21.8.14.tgz",
"integrity": "sha512-4Yi+DtexvMm/Yw3Q9fllzY12SgLk+Mcmar+rCAccsOPul/2UmnBzoHbTGn/L48IPkFcmrNaH7xTLboBWIbH6pw==",
"funding": [
{
"type": "individual",
"url": "https://locize.com"
},
{
"type": "individual",
"url": "https://locize.com/i18next.html"
},
{
"type": "individual",
"url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
}
],
"dependencies": {
"@babel/runtime": "^7.17.2"
}
},
"node_modules/i18next-react-native-async-storage": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/i18next-react-native-async-storage/-/i18next-react-native-async-storage-1.0.4.tgz",
"integrity": "sha512-udxag0zffOTy6aCaeEh+886wrIGdbpXjt+j9WdPMpXMN48u+rz/Ux9N9jonUA+r3viURK3Hg2aR7MS2jZ+lN2A==",
"peerDependencies": {
"i18next": ">=13.0.1"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -12799,6 +12840,27 @@ @@ -12799,6 +12840,27 @@
"react": "^17.0.0"
}
},
"node_modules/react-i18next": {
"version": "11.18.1",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.18.1.tgz",
"integrity": "sha512-S8cl4mvIOSA7OQCE5jNy2yhv705Vwi+7PinpqKIYcBmX/trJtHKqrf6CL67WJSA8crr2JU+oxE9jn9DQIrQezg==",
"dependencies": {
"@babel/runtime": "^7.14.5",
"html-parse-stringify": "^3.0.1"
},
"peerDependencies": {
"i18next": ">= 19.0.0",
"react": ">= 16.8.0"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@ -15778,6 +15840,14 @@ @@ -15778,6 +15840,14 @@
"resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w=="
},
"node_modules/void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/w3c-hr-time": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
@ -22139,6 +22209,14 @@ @@ -22139,6 +22209,14 @@
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
},
"html-parse-stringify": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
"requires": {
"void-elements": "3.1.0"
}
},
"http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@ -22196,6 +22274,20 @@ @@ -22196,6 +22274,20 @@
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
"dev": true
},
"i18next": {
"version": "21.8.14",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-21.8.14.tgz",
"integrity": "sha512-4Yi+DtexvMm/Yw3Q9fllzY12SgLk+Mcmar+rCAccsOPul/2UmnBzoHbTGn/L48IPkFcmrNaH7xTLboBWIbH6pw==",
"requires": {
"@babel/runtime": "^7.17.2"
}
},
"i18next-react-native-async-storage": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/i18next-react-native-async-storage/-/i18next-react-native-async-storage-1.0.4.tgz",
"integrity": "sha512-udxag0zffOTy6aCaeEh+886wrIGdbpXjt+j9WdPMpXMN48u+rz/Ux9N9jonUA+r3viURK3Hg2aR7MS2jZ+lN2A==",
"requires": {}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -25598,6 +25690,15 @@ @@ -25598,6 +25690,15 @@
"integrity": "sha512-yQaiOqDmoKqks56LN9MTgY06O0qQHgV4FUrikH357DydArSZHQhl0BJFqGKIZoTqi8JizF9Dxhuk1FIZD6qCaw==",
"requires": {}
},
"react-i18next": {
"version": "11.18.1",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.18.1.tgz",
"integrity": "sha512-S8cl4mvIOSA7OQCE5jNy2yhv705Vwi+7PinpqKIYcBmX/trJtHKqrf6CL67WJSA8crr2JU+oxE9jn9DQIrQezg==",
"requires": {
"@babel/runtime": "^7.14.5",
"html-parse-stringify": "^3.0.1"
}
},
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@ -27915,6 +28016,11 @@ @@ -27915,6 +28016,11 @@
"resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w=="
},
"void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w=="
},
"w3c-hr-time": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",

3
package.json

@ -12,7 +12,10 @@ @@ -12,7 +12,10 @@
"dependencies": {
"@react-navigation/native": "^6.0.11",
"@react-navigation/native-stack": "^6.7.0",
"i18next": "^21.8.14",
"i18next-react-native-async-storage": "^1.0.4",
"react": "17.0.2",
"react-i18next": "^11.18.1",
"react-native": "0.67.4",
"react-native-gesture-handler": "^2.5.0",
"react-native-safe-area-context": "^4.3.1",

25
src/i18n/index.ts

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
import i18n from 'i18next';
import {initReactI18next} from 'react-i18next';
import AsyncStoragePlugin from 'i18next-react-native-async-storage';
import * as locales from './locales';
export enum LangKeys {
EN = 'en',
UA = 'ua',
}
i18n
.use(initReactI18next)
.use(AsyncStoragePlugin())
.init({
fallbackLng: 'en',
debug: true,
interpolation: {
escapeValue: false,
},
resources: {
[LangKeys.EN]: {translation: locales.en},
[LangKeys.UA]: {translation: locales.ua},
},
});

1
src/i18n/locales/en/index.ts

@ -0,0 +1 @@ @@ -0,0 +1 @@
export * from './stepLocale';

26
src/i18n/locales/en/stepLocale.ts

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
import {MainLocaleModule} from '../../types';
import {OnBoardingLocale} from './../../types/onBoarding';
export const onBoardingTranslation: OnBoardingLocale.OnboardingSteps = {
step1: {
title: 'Welcome!',
description:
'Thank you for downloading. Now you are \n in the best game for the company \n or to play with your loved one',
textButton: 'Skip',
},
step2: {
title: 'Relax and enjoy \n the game!',
description:
'This game features 5 levels of "spiciness",\n some of which are divided into games for a \n couple or a company. All you have to do is \n add players and you can start playing.\n P.S. You can always create your own \n questions and tasks.',
textButton: 'Skip',
},
step3: {
title: 'Premium version!',
description:
'Provides unlimited access to Hard and \n Extreme packages. Enjoy intriguing questions \n and exciting action.',
textButton: 'Open now',
},
};
export const en: MainLocaleModule = {
stepTranslation: onBoardingTranslation,
};

2
src/i18n/locales/index.ts

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
export * from './en';
export * from './ua';

1
src/i18n/locales/ua/index.ts

@ -0,0 +1 @@ @@ -0,0 +1 @@
export * from './stepLocaleUa';

23
src/i18n/locales/ua/stepLocaleUa.ts

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
import {MainLocaleModule} from '../../types';
export const onBoardingTranslationUa = {
step1: {
title: 'Ласкаво просимо!',
description:
'Дякуємо за завантаження. Тепер ви \n в найкращій грі для компанії або \n пограти з коханою людиною',
},
step2: {
title: 'Розслабтеся та насолоджуйтеся \n грою',
description:
'У цій грі є 5 рівнів "пікантності",\n деякі з яких розділені на ігри для пари \n або компанії. Все, що вам потрібно зробити, це \n додати гравців, і ви можете почати грати.\n P.S. Ви завжди можете створити власні \n питання та завдання',
},
step3: {
title: 'Преміум версія!',
description:
'Надає необмежений доступ до пакетів Hard і \nНасолоджуйтеся інтригуючими запитаннями та\nзахоплюючими діями',
},
};
export const ua: MainLocaleModule = {
stepTranslation: onBoardingTranslationUa,
};

5
src/i18n/types/index.ts

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
import {OnBoardingLocale} from './onBoarding';
export interface MainLocaleModule {
stepTranslation: OnBoardingLocale.OnboardingSteps;
}

11
src/i18n/types/onBoarding.ts

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
export namespace OnBoardingLocale {
export interface IStep {
title: string;
description: string;
}
export interface OnboardingSteps {
step1: IStep;
step2: IStep;
step3: IStep;
}
}

2
src/module/root/atoms/premiumGroupBtn.tsx

@ -22,7 +22,7 @@ export const GroupBtn: FC<IProps> = ({currentIndex, data, onPressItem}) => { @@ -22,7 +22,7 @@ export const GroupBtn: FC<IProps> = ({currentIndex, data, onPressItem}) => {
<View style={{alignItems: 'center'}}>
<PrimaryBtn
onPress={() => {}}
children={<Text style={styles.text}>Open now / $4.99</Text>}
children={<Text style={styles.text}>{`Open now / $4.99`}</Text>}
width={190}
/>
<TouchableOpacity style={styles.laterBtn}>

13
src/module/root/components/contentOnboarding.tsx

@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
import React, {FC} from 'react';
import {useTranslation} from 'react-i18next';
import {View, Text, StyleSheet} from 'react-native';
import {LangKeys} from '../../../i18n';
import {colors, heightPicture} from '../../shared';
import {GroupBtn} from '../atoms/premiumGroupBtn';
import {OnBoardData} from '../config/dataOnboarding';
@ -8,14 +10,20 @@ interface IProps { @@ -8,14 +10,20 @@ interface IProps {
onPressItem: (data: any) => void;
}
export const ContentOnBoarding: FC<IProps> = ({currentIndex, onPressItem}) => {
const {t, i18n} = useTranslation();
console.log('i18', i18n.language);
const Picture = OnBoardData[currentIndex].image;
const changeFontSize = () => (i18n.language === LangKeys.UA ? 30 : 32);
return (
<>
<Picture width={'100%'} height={heightPicture()} />
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={styles.title}>{OnBoardData[currentIndex].title}</Text>
<Text style={[styles.title, {fontSize: changeFontSize()}]}>
{t(OnBoardData[currentIndex].title)}
</Text>
<Text style={styles.description}>
{OnBoardData[currentIndex].description}
{t(OnBoardData[currentIndex].description)}
</Text>
</View>
<View style={{alignItems: 'center', marginBottom: 30}}>
@ -51,7 +59,6 @@ const styles = StyleSheet.create({ @@ -51,7 +59,6 @@ const styles = StyleSheet.create({
title: {
color: colors.prymaryText,
marginBottom: 25,
fontSize: 32,
fontWeight: '700',
textAlign: 'center',
},

21
src/module/root/config/dataOnboarding.ts

@ -1,23 +1,26 @@ @@ -1,23 +1,26 @@
import ImageHearts from '../../../assets/image/hearts.svg';
import ImageGlass from '../../../assets/image/glass.svg';
import ImageCup from '../../../assets/image/winnersCup.svg';
import {OnBoardingLocale} from '../../../i18n/types/onBoarding';
const translatePath = (
itemKey: keyof OnBoardingLocale.OnboardingSteps,
key: keyof OnBoardingLocale.IStep,
) => `stepTranslation.${itemKey}.${key}`;
export const OnBoardData = [
{
title: 'Welcome!',
description:
'Thank you for downloading. Now you are \n in the best game for the company \n or to play with your loved one',
title: translatePath('step1', 'title'),
description: translatePath('step1', 'description'),
image: ImageHearts,
},
{
title: 'Relax and enjoy \n the game!',
description:
'This game features 5 levels of "spiciness",\n some of which are divided into games for a \n couple or a company. All you have to do is \n add players and you can start playing.\n P.S. You can always create your own \n questions and tasks.',
title: translatePath('step2', 'title'),
description: translatePath('step2', 'description'),
image: ImageGlass,
},
{
title: 'Premium version!',
description:
'Provides unlimited access to Hard and \n Extreme packages. Enjoy intriguing questions \n and exciting action.',
title: translatePath('step3', 'title'),
description: translatePath('step3', 'description'),
image: ImageCup,
},
];

13
src/module/root/screens/languageSelect.tsx

@ -1,20 +1,26 @@ @@ -1,20 +1,26 @@
import React, {FC} from 'react';
import {Image, StyleSheet, Text, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {Button, Image, StyleSheet, Text, View} from 'react-native';
import FlagEng from '../../../assets/icons/ENG.svg';
import {LangKeys} from '../../../i18n';
import {IRouteParams, RouteKey, colors, ScreenLayout} from '../../shared/';
import {LanguageItem} from '../components';
const languageArr = [
{
name: 'Українська',
icon: <Image source={require('../../../assets/icons/UKR.png')} />,
key: LangKeys.UA,
},
{
name: 'English',
icon: <FlagEng />,
key: LangKeys.EN,
},
];
interface IProps extends IRouteParams {}
export const LanguageSelect: FC<IProps> = ({navigation}) => {
const {t, i18n} = useTranslation();
return (
<ScreenLayout
backgroundColor={colors.primaryColor}
@ -24,7 +30,10 @@ export const LanguageSelect: FC<IProps> = ({navigation}) => { @@ -24,7 +30,10 @@ export const LanguageSelect: FC<IProps> = ({navigation}) => {
{languageArr.map(el => (
<LanguageItem
key={el.name}
onPress={() => navigation.navigate(RouteKey.Onboarding)}
onPress={() => {
navigation.navigate(RouteKey.Onboarding);
i18n.changeLanguage(el.key);
}}
icon={el.icon}
name={el.name}
/>

Loading…
Cancel
Save