From 098d9f296e4b15cd10f14b5ad93df2f891e41045 Mon Sep 17 00:00:00 2001 From: Madhushree Gupta Date: Fri, 11 Oct 2024 10:52:15 +0100 Subject: [PATCH 1/2] i18n added and used in drawer component --- app/(drawer)/index.tsx | 9 +++++--- app/_layout.tsx | 4 ++++ components/CustomDrawerContent.tsx | 33 +++++++++++++++++++++++++---- components/i18n/en.json | 13 ++++++++++++ components/i18n/es.json | 12 +++++++++++ components/i18n/fr.json | 12 +++++++++++ components/i18n/index.tsx | 34 ++++++++++++++++++++++++++++++ 7 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 components/i18n/en.json create mode 100644 components/i18n/es.json create mode 100644 components/i18n/fr.json create mode 100644 components/i18n/index.tsx diff --git a/app/(drawer)/index.tsx b/app/(drawer)/index.tsx index 08205bd..ee67297 100644 --- a/app/(drawer)/index.tsx +++ b/app/(drawer)/index.tsx @@ -7,6 +7,7 @@ import { SpatialNavigationFocusableView, SpatialNavigationRoot, SpatialNavigatio import { Direction } from '@bam.tech/lrud'; import { scaledPixels } from '@/hooks/useScale'; import { LinearGradient } from 'expo-linear-gradient'; +import { useTranslation } from 'react-i18next'; interface CardData { @@ -30,6 +31,8 @@ export default function IndexScreen() { const focusedItem = useMemo(() => moviesData[focusedIndex], [focusedIndex]); + const { t } = useTranslation(); + const renderHeader = useCallback(() => ( - {renderScrollableRow("Trending Movies", trendingRef)} - {renderScrollableRow("Classics", classicsRef)} - {renderScrollableRow("Hip and Modern", hipAndModernRef)} + {renderScrollableRow(t('categories.trending_movies'), trendingRef)} + {renderScrollableRow(t('categories.classics'), classicsRef)} + {renderScrollableRow(t('categories.hip_and_modern'), hipAndModernRef)} diff --git a/app/_layout.tsx b/app/_layout.tsx index ec6e8e3..ac7b8ab 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -6,6 +6,8 @@ import { useCallback, useEffect } from 'react'; import { MenuProvider } from '../components/MenuContext'; import { GoBackConfiguration } from './remote-control/GoBackConfiguration'; +import { I18nextProvider } from 'react-i18next'; +import i18n from '@/components/i18n'; // Initialize i18n import "./configureRemoteControl" @@ -33,6 +35,7 @@ export default function RootLayout() { return ( + @@ -42,6 +45,7 @@ export default function RootLayout() { + ); } diff --git a/components/CustomDrawerContent.tsx b/components/CustomDrawerContent.tsx index 31a34ba..46fd6d5 100644 --- a/components/CustomDrawerContent.tsx +++ b/components/CustomDrawerContent.tsx @@ -1,22 +1,27 @@ import { scaledPixels } from "@/hooks/useScale"; import { DrawerContentScrollView } from "@react-navigation/drawer"; import { View, StyleSheet, Image, Platform, Text } from "react-native"; +import { Picker } from '@react-native-picker/picker'; import { DefaultFocus, SpatialNavigationFocusableView, SpatialNavigationRoot } from "react-tv-space-navigation"; import { useRouter } from "expo-router"; import { useMenuContext } from "@/components/MenuContext"; import { useSafeAreaInsets } from "react-native-safe-area-context"; +import { useTranslation } from 'react-i18next'; export default function CustomDrawerContent(props: any) { const router = useRouter(); const { isOpen: isMenuOpen, toggleMenu } = useMenuContext(); const styles = useDrawerStyles(); const {top, right, bottom, left} = useSafeAreaInsets(); + const { t, i18n } = useTranslation(); const drawerItems = [ - { name: '/', label: 'Home' }, - { name: 'explore', label: 'Explore'}, - { name: 'tv', label: 'TV'}, + { name: '/', label: t('drawer.index') }, + { name: 'explore', label: t('drawer.explore')}, + { name: 'tv', label: t('drawer.tv')}, ]; - + const changeLanguage = (language: string) => { + i18n.changeLanguage(language); + }; return ( @@ -24,6 +29,16 @@ export default function CustomDrawerContent(props: any) { Pioneer Tom Switch account + Switch Language + changeLanguage(itemValue)} + style={styles.picker} + > + + + + {drawerItems.map((item, index) => ( index === 0 ? ( @@ -108,5 +123,15 @@ const useDrawerStyles = function () { menuTextFocused: { color: 'black', }, + switchLanguage: { + paddingTop: scaledPixels(10), + paddingBottom: scaledPixels(6), + color: 'white', + fontSize: scaledPixels(26), + }, + picker: { + height: 40, + width: '60%' + } }); }; \ No newline at end of file diff --git a/components/i18n/en.json b/components/i18n/en.json new file mode 100644 index 0000000..4f03734 --- /dev/null +++ b/components/i18n/en.json @@ -0,0 +1,13 @@ + +{ + "drawer": { + "index": "Home", + "explore": "Explore", + "tv": "TV" + }, + "categories": { + "trending_movies": "Trending Movies", + "classics": "Classics", + "hip_and_modern": "Hip and Modern" + } + } \ No newline at end of file diff --git a/components/i18n/es.json b/components/i18n/es.json new file mode 100644 index 0000000..90115ee --- /dev/null +++ b/components/i18n/es.json @@ -0,0 +1,12 @@ +{ + "drawer": { + "index": "Inicio", + "explore": "Explorar", + "tv": "Televisión" + }, + "categories": { + "trending_movies": "Películas de Tendencia", + "classics": "Clásicos", + "hip_and_modern": "Moderno y de moda" + } +} \ No newline at end of file diff --git a/components/i18n/fr.json b/components/i18n/fr.json new file mode 100644 index 0000000..a637790 --- /dev/null +++ b/components/i18n/fr.json @@ -0,0 +1,12 @@ +{ + "drawer": { + "index": "Accueil", + "explore": "Explorer", + "tv": "Télévision" + }, + "categories": { + "trending_movies": "Films Tendance", + "classics": "Classiques", + "hip_and_modern": "À la mode et moderne" + } + } \ No newline at end of file diff --git a/components/i18n/index.tsx b/components/i18n/index.tsx new file mode 100644 index 0000000..8c436c2 --- /dev/null +++ b/components/i18n/index.tsx @@ -0,0 +1,34 @@ +import i18next from 'i18next'; +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; +import LanguageDetector from 'i18next-browser-languagedetector'; + +// Import translation files +import en from './en.json'; +import es from './es.json'; +import fr from './fr.json'; + +i18next + .use(initReactI18next) + .use(LanguageDetector) + .init({ + compatibilityJSON: 'v3', // If you face any version-related warnings + resources: { + en: { + translation: en, + }, + es: { + translation: es, + }, + fr: { + translation: fr, + }, + }, + lng: 'en', // Default language + fallbackLng: 'en', // Fallback language in case of missing translations + interpolation: { + escapeValue: false, // React already escapes values, so this is safe + }, + }); + + export default i18n; \ No newline at end of file From ade74c3a0bce0943c8a0be6a09666c589652617f Mon Sep 17 00:00:00 2001 From: Madhushree Gupta Date: Mon, 14 Oct 2024 09:02:22 +0100 Subject: [PATCH 2/2] removed comments and added package.json --- app/_layout.tsx | 2 +- components/i18n/index.tsx | 9 ++++----- package.json | 11 ++++++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/app/_layout.tsx b/app/_layout.tsx index ac7b8ab..2662b5c 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -7,7 +7,7 @@ import { useCallback, useEffect } from 'react'; import { MenuProvider } from '../components/MenuContext'; import { GoBackConfiguration } from './remote-control/GoBackConfiguration'; import { I18nextProvider } from 'react-i18next'; -import i18n from '@/components/i18n'; // Initialize i18n +import i18n from '@/components/i18n'; import "./configureRemoteControl" diff --git a/components/i18n/index.tsx b/components/i18n/index.tsx index 8c436c2..9118ef8 100644 --- a/components/i18n/index.tsx +++ b/components/i18n/index.tsx @@ -3,7 +3,6 @@ import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import LanguageDetector from 'i18next-browser-languagedetector'; -// Import translation files import en from './en.json'; import es from './es.json'; import fr from './fr.json'; @@ -12,7 +11,7 @@ i18next .use(initReactI18next) .use(LanguageDetector) .init({ - compatibilityJSON: 'v3', // If you face any version-related warnings + compatibilityJSON: 'v3', resources: { en: { translation: en, @@ -24,10 +23,10 @@ i18next translation: fr, }, }, - lng: 'en', // Default language - fallbackLng: 'en', // Fallback language in case of missing translations + lng: 'en', + fallbackLng: 'en', interpolation: { - escapeValue: false, // React already escapes values, so this is safe + escapeValue: false, }, }); diff --git a/package.json b/package.json index d534d4c..fb0196a 100644 --- a/package.json +++ b/package.json @@ -17,20 +17,26 @@ "dependencies": { "@bam.tech/react-native-keyevent-expo-config-plugin": "^1.0.50", "@expo/vector-icons": "^14.0.0", + "@react-native-picker/picker": "^2.8.1", "@react-navigation/drawer": "^6.6.15", "@react-navigation/native": "^6.0.2", "expo": "~51.0.13", "expo-build-properties": "~0.12.3", "expo-constants": "~16.0.2", "expo-font": "~12.0.7", + "expo-linear-gradient": "~13.0.2", "expo-linking": "~6.3.1", "expo-router": "~3.5.16", "expo-splash-screen": "~0.27.5", "expo-status-bar": "~1.12.1", "expo-system-ui": "~3.0.6", "expo-web-browser": "~13.0.3", + "i18next": "^23.15.2", + "i18next-browser-languagedetector": "^3.0.0", + "package": "^1.0.1", "react": "18.2.0", "react-dom": "18.2.0", + "react-i18next": "^15.0.2", "react-native": "npm:react-native-tvos@~0.74.2-0", "react-native-gesture-handler": "~2.16.1", "react-native-keyevent": "^0.3.2", @@ -38,16 +44,15 @@ "react-native-safe-area-context": "4.10.1", "react-native-screens": "3.31.1", "react-native-web": "~0.19.10", - "react-tv-space-navigation": "^3.6.1", - "expo-linear-gradient": "~13.0.2" + "react-tv-space-navigation": "^3.6.1" }, "devDependencies": { "@babel/core": "^7.20.0", - "babel-plugin-module-resolver": "^4.1.0", "@react-native-tvos/config-tv": "^0.0.10", "@types/jest": "^29.5.12", "@types/react": "~18.2.45", "@types/react-test-renderer": "^18.0.7", + "babel-plugin-module-resolver": "^4.1.0", "jest": "^29.2.1", "jest-expo": "~51.0.1", "react-native-pixel-perfect": "^1.0.2",