Add i18next integration
parent
363b88fd92
commit
48877cbf0f
|
|
@ -1,11 +1,11 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
import FontAwesome from "@expo/vector-icons/FontAwesome";
|
||||||
import { Link, Tabs } from 'expo-router';
|
import { Link, Tabs } from "expo-router";
|
||||||
import { Pressable } from 'react-native';
|
import { Pressable } from "react-native";
|
||||||
|
import Colors from "@/constants/Colors";
|
||||||
import Colors from '@/constants/Colors';
|
import { useColorScheme } from "@/components/useColorScheme";
|
||||||
import { useColorScheme } from '@/components/useColorScheme';
|
import { useClientOnlyValue } from "@/components/useClientOnlyValue";
|
||||||
import { useClientOnlyValue } from '@/components/useClientOnlyValue';
|
import { TAB_CONFIG } from "@/constants/config";
|
||||||
|
|
||||||
// You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
|
// You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
|
||||||
function TabBarIcon(props: {
|
function TabBarIcon(props: {
|
||||||
|
|
@ -21,9 +21,7 @@ export default function TabLayout() {
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<Tabs
|
||||||
screenOptions={{
|
screenOptions={{
|
||||||
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
tabBarActiveTintColor: Colors[colorScheme ?? "light"].tint,
|
||||||
// Disable the static render of the header on web
|
|
||||||
// to prevent a hydration error in React Navigation v6.
|
|
||||||
headerShown: useClientOnlyValue(false, true),
|
headerShown: useClientOnlyValue(false, true),
|
||||||
}}>
|
}}>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,27 @@
|
||||||
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
import i18next, { getLanguage } from "../services/i18n/index";
|
||||||
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
|
import FontAwesome from "@expo/vector-icons/FontAwesome";
|
||||||
import { useFonts } from 'expo-font';
|
import {
|
||||||
import { Stack } from 'expo-router';
|
DarkTheme,
|
||||||
import * as SplashScreen from 'expo-splash-screen';
|
DefaultTheme,
|
||||||
import { useEffect } from 'react';
|
ThemeProvider,
|
||||||
import 'react-native-reanimated';
|
} from "@react-navigation/native";
|
||||||
|
import { useFonts } from "expo-font";
|
||||||
|
import { Stack, useRouter } from "expo-router";
|
||||||
|
import * as SplashScreen from "expo-splash-screen";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import "react-native-reanimated";
|
||||||
|
import { I18nextProvider } from "react-i18next"; //I18nextProvider
|
||||||
|
|
||||||
import { useColorScheme } from '@/components/useColorScheme';
|
import { useColorScheme } from "@/components/useColorScheme";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
// Catch any errors thrown by the Layout component.
|
// Catch any errors thrown by the Layout component.
|
||||||
ErrorBoundary,
|
ErrorBoundary,
|
||||||
} from 'expo-router';
|
} from "expo-router";
|
||||||
|
|
||||||
export const unstable_settings = {
|
export const unstable_settings = {
|
||||||
// Ensure that reloading on `/modal` keeps a back button present.
|
// Ensure that reloading on `/modal` keeps a back button present.
|
||||||
initialRouteName: '(tabs)',
|
initialRouteName: "(tabs)",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
||||||
|
|
@ -23,7 +29,7 @@ SplashScreen.preventAutoHideAsync();
|
||||||
|
|
||||||
export default function RootLayout() {
|
export default function RootLayout() {
|
||||||
const [loaded, error] = useFonts({
|
const [loaded, error] = useFonts({
|
||||||
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
|
||||||
...FontAwesome.font,
|
...FontAwesome.font,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -49,11 +55,13 @@ function RootLayoutNav() {
|
||||||
const colorScheme = useColorScheme();
|
const colorScheme = useColorScheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
<I18nextProvider i18n={i18next}>
|
||||||
|
<ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
|
<Stack.Screen name="modal" options={{ presentation: "modal" }} />
|
||||||
</Stack>
|
</Stack>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
</I18nextProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
import i18next from "i18next";
|
||||||
|
import { initReactI18next } from "react-i18next";
|
||||||
|
import en from "../i18n/locals/en.json";
|
||||||
|
import hi from "../i18n/locals/hi.json";
|
||||||
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||||
|
import { STORAGE_KEYS } from "../../constants/config";
|
||||||
|
|
||||||
|
export const languageResources = {
|
||||||
|
en: { translation: en },
|
||||||
|
hi: { translation: hi },
|
||||||
|
};
|
||||||
|
|
||||||
|
i18next.use(initReactI18next).init({
|
||||||
|
compatibilityJSON: "v4",
|
||||||
|
lng: "hi",
|
||||||
|
fallbackLng: "en",
|
||||||
|
resources: languageResources,
|
||||||
|
debug: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
i18next.on("initialized", () => {
|
||||||
|
console.log("✅ i18next initialized with language:", i18next.language);
|
||||||
|
console.log("Translation test (welcome):", i18next.t("welcome"));
|
||||||
|
});
|
||||||
|
|
||||||
|
export const setLanguage = async (language: string) => {
|
||||||
|
await AsyncStorage.setItem(STORAGE_KEYS.LANGUAGE, language);
|
||||||
|
i18next.changeLanguage(language);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getLanguage = async () => {
|
||||||
|
const lang = await AsyncStorage.getItem(STORAGE_KEYS.LANGUAGE);
|
||||||
|
if (lang) {
|
||||||
|
i18next.changeLanguage(lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lang;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default i18next;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"en": {
|
||||||
|
"name": "English"
|
||||||
|
},
|
||||||
|
"hi": {
|
||||||
|
"name": "हिंदी"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"change-language": "Change language",
|
||||||
|
"welcome": "Welcome to Driver Saathi"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"change-language": "भाषा बदलें",
|
||||||
|
"welcome": "ड्राइवर साथी में आपका स्वागत है"
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue