wip: Make translation provider for native

This commit is contained in:
Zoe Roux 2025-02-21 22:32:21 +01:00
parent 557eaf97c2
commit 039e95c87b
No known key found for this signature in database
6 changed files with 55 additions and 4 deletions

View File

@ -12,6 +12,8 @@
"expo-build-properties": "^0.13.2",
"expo-localization": "^16.0.1",
"expo-updates": "~0.26.19",
"i18next-async-storage-backend": "^1.0.2",
"i18next-chained-backend": "^4.6.2",
"i18next-fs-backend": "^2.6.0",
"i18next-http-backend": "^3.0.2",
"jotai": "^2.12.0",
@ -543,6 +545,8 @@
"@radix-ui/react-slot": ["@radix-ui/react-slot@1.1.2", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ=="],
"@react-native-community/async-storage": ["@react-native-community/async-storage@1.12.1", "", { "dependencies": { "deep-assign": "^3.0.0" }, "peerDependencies": { "react": "^16.8", "react-native": ">=0.59" } }, "sha512-70WGaH3PKYASi4BThuEEKMkyAgE9k7VytBqmgPRx3MzJx9/MkspwqJGmn3QLCgHLIFUgF1pit2mWICbRJ3T3lg=="],
"@react-native-community/cli": ["@react-native-community/cli@15.1.3", "", { "dependencies": { "@react-native-community/cli-clean": "15.1.3", "@react-native-community/cli-config": "15.1.3", "@react-native-community/cli-debugger-ui": "15.1.3", "@react-native-community/cli-doctor": "15.1.3", "@react-native-community/cli-server-api": "15.1.3", "@react-native-community/cli-tools": "15.1.3", "@react-native-community/cli-types": "15.1.3", "chalk": "^4.1.2", "commander": "^9.4.1", "deepmerge": "^4.3.0", "execa": "^5.0.0", "find-up": "^5.0.0", "fs-extra": "^8.1.0", "graceful-fs": "^4.1.3", "prompts": "^2.4.2", "semver": "^7.5.2" }, "bin": { "rnc-cli": "build/bin.js" } }, "sha512-+ih/WYUkJsEV2CMAnOHvVoSIz/Ahg5UJk+sqSIOmY79mWAglQzfLP71o7b0neJCnJWLmWiO6G6/S+kmULefD5g=="],
"@react-native-community/cli-clean": ["@react-native-community/cli-clean@15.1.3", "", { "dependencies": { "@react-native-community/cli-tools": "15.1.3", "chalk": "^4.1.2", "execa": "^5.0.0", "fast-glob": "^3.3.2" } }, "sha512-3s9NGapIkONFoCUN2s77NYI987GPSCdr74rTf0TWyGIDf4vTYgKoWKKR+Ml3VTa1BCj51r4cYuHEKE1pjUSc0w=="],
@ -1061,6 +1065,8 @@
"decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="],
"deep-assign": ["deep-assign@3.0.0", "", { "dependencies": { "is-obj": "^1.0.0" } }, "sha512-YX2i9XjJ7h5q/aQ/IM9PEwEnDqETAIYbggmdDB3HLTlSgo1CxPsj6pvhPG68rq6SVE0+p+6Ywsm5fTYNrYtBWw=="],
"deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
@ -1327,6 +1333,10 @@
"i18next": ["i18next@24.2.2", "", { "dependencies": { "@babel/runtime": "^7.23.2" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-NE6i86lBCKRYZa5TaUDkU5S4HFgLIEJRLr3Whf2psgaxBleQ2LC1YW1Vc+SCgkAW7VEzndT6al6+CzegSUHcTQ=="],
"i18next-async-storage-backend": ["i18next-async-storage-backend@1.0.2", "", { "peerDependencies": { "@react-native-community/async-storage": "*" } }, "sha512-jINQ+upKNwP8aHRxC0XUdbYKtSldXzsl1LZae1N7837SyVnO7ffojZzU+4PulMys9bHss4ETMIjVSjXXUqCvdw=="],
"i18next-chained-backend": ["i18next-chained-backend@4.6.2", "", { "dependencies": { "@babel/runtime": "^7.23.2" } }, "sha512-2P092fR+nAPQlGzPUoIIxbwo7PTBqQYgLxwv1XhSTQUAUoelLo5LkX+FqRxxSDg9WEAsrc8+2WL6mJtMGIa6WQ=="],
"i18next-fs-backend": ["i18next-fs-backend@2.6.0", "", {}, "sha512-3ZlhNoF9yxnM8pa8bWp5120/Ob6t4lVl1l/tbLmkml/ei3ud8IWySCHt2lrY5xWRlSU5D9IV2sm5bEbGuTqwTw=="],
"i18next-http-backend": ["i18next-http-backend@3.0.2", "", { "dependencies": { "cross-fetch": "4.0.0" } }, "sha512-PdlvPnvIp4E1sYi46Ik4tBYh/v/NbYfFFgTjkwFl0is8A18s7/bx9aXqsrOax9WUbeNS6mD2oix7Z0yGGf6m5g=="],
@ -1387,6 +1397,8 @@
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
"is-obj": ["is-obj@1.0.1", "", {}, "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg=="],
"is-path-cwd": ["is-path-cwd@2.2.0", "", {}, "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ=="],
"is-path-inside": ["is-path-inside@3.0.3", "", {}, "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="],

View File

@ -24,6 +24,8 @@
"expo-build-properties": "^0.13.2",
"expo-localization": "^16.0.1",
"expo-updates": "~0.26.19",
"i18next-async-storage-backend": "^1.0.2",
"i18next-chained-backend": "^4.6.2",
"i18next-fs-backend": "^2.6.0",
"i18next-http-backend": "^3.0.2",
"jotai": "^2.12.0",

View File

@ -4,6 +4,7 @@ import { Platform } from "react-native";
import { z } from "zod";
import { AccountP, UserP } from "~/models";
import { useFetch } from "~/query";
import { AccountContext } from "./account-context";
import { removeAccounts, updateAccount } from "./account-store";
import { useSetError } from "./error-provider";
import { useStoreValue } from "./settings";

View File

@ -7,7 +7,7 @@ import { createQueryClient } from "~/query";
import { AccountProvider } from "./account-provider";
import { ErrorConsumer } from "./error-consumer";
import { ErrorProvider } from "./error-provider";
import { TranslationsProvider } from "./translations";
import { TranslationsProvider } from "./translations.web";
// const { TranslationsProvider } =
// typeof window === "undefined"

View File

@ -1,4 +1,8 @@
import i18next from "i18next";
import AsyncStorageBackend, {
type AsyncStorageBackendOptions,
} from "i18next-async-storage-backend";
import ChainedBackend, { type ChainedBackendOptions } from "i18next-chained-backend";
import HttpApi, { type HttpBackendOptions } from "i18next-http-backend";
import { getServerData } from "one";
import { type ReactNode, useMemo } from "react";
@ -7,8 +11,7 @@ import { I18nextProvider } from "react-i18next";
export const TranslationsProvider = ({ children }: { children: ReactNode }) => {
const val = useMemo(() => {
const i18n = i18next.createInstance();
// TODO: use https://github.com/i18next/i18next-browser-languageDetector
i18n.use(HttpApi).init<HttpBackendOptions>({
i18n.use(ChainedBackend).init<ChainedBackendOptions>({
interpolation: {
escapeValue: false,
},
@ -17,7 +20,12 @@ export const TranslationsProvider = ({ children }: { children: ReactNode }) => {
load: "currentOnly",
supportedLngs: getServerData("supportedLngs"),
backend: {
loadPath: "/translations/{{lng}}.json",
backends: [AsyncStorageBackend, HttpApi],
backendOptions: [
{
loadPath: "/translations/{{lng}}.json",
} satisfies HttpBackendOptions,
],
},
});
i18n.services.resourceStore.data = getServerData("translations");

View File

@ -0,0 +1,28 @@
import i18next from "i18next";
import HttpApi, { type HttpBackendOptions } from "i18next-http-backend";
import { getServerData } from "one";
import { type ReactNode, useMemo } from "react";
import { I18nextProvider } from "react-i18next";
export const TranslationsProvider = ({ children }: { children: ReactNode }) => {
const val = useMemo(() => {
const i18n = i18next.createInstance();
// TODO: use https://github.com/i18next/i18next-browser-languageDetector
i18n.use(HttpApi).init<HttpBackendOptions>({
interpolation: {
escapeValue: false,
},
returnEmptyString: false,
fallbackLng: "en",
load: "currentOnly",
supportedLngs: getServerData("supportedLngs"),
// we don't need to cache resources since we always get a fresh one from ssr
backend: {
loadPath: "/translations/{{lng}}.json",
},
});
i18n.services.resourceStore.data = getServerData("translations");
return i18n;
}, []);
return <I18nextProvider i18n={val}>{children}</I18nextProvider>;
};