Skip to content

Commit c361687

Browse files
authored
feat: introduce createLanguageDetector (#29)
Introduce createLanguageDetector to provide greater flexibility with language detection. This change means the current detector (ReactNativeLanguageDetector) will be deprecated in favor of the more adaptable option.
1 parent 4c9fb22 commit c361687

File tree

3 files changed

+89
-20
lines changed

3 files changed

+89
-20
lines changed

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,19 +129,32 @@ setLanguage("en-US");
129129
## i18next
130130

131131
This library is fully compatible with [i18next](https://www.i18next.com/).
132-
To use it with i18next, you need to use `ReactNativeLanguageDetector` before init function:
133132

133+
To use it with i18next, create a language detector by using `createLanguageDetector` with the specified `options`:
134134
```ts
135-
import { ReactNativeLanguageDetector } from 'react-native-localization-settings';
135+
import { createLanguageDetector } from 'react-native-localization-settings';
136+
137+
const languageDetector = createLanguageDetector({});
136138

137139
i18next
138-
.use(ReactNativeLanguageDetector)
140+
.use(languageDetector)
139141
.use(initReactI18next)
140142
.init({
141143
// ...
142144
});
143145
```
144146

147+
### Options
148+
149+
```ts
150+
type LanguageDetectorOptions = {
151+
cacheCurrentLanguage?: boolean; // default: false - sets current detected language
152+
async?: boolean; // default: false - uses getLanguageAsync (set to true on old architecture)
153+
};
154+
```
155+
156+
### Changing language
157+
145158
Then, if you want to create custom in-app language selector, you should be able to change the language (along with the
146159
settings per-app language) using standard i18next function:
147160

example/App.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import { StyleSheet, View, Text, Button } from 'react-native';
33
import i18next from 'i18next';
44
import { initReactI18next, useTranslation } from 'react-i18next';
55
import {
6+
createLanguageDetector,
67
getLanguage,
78
getLanguageAsync,
8-
ReactNativeLanguageDetector,
99
} from 'react-native-localization-settings';
1010

11+
const languageDetector = createLanguageDetector();
12+
1113
i18next
12-
.use(ReactNativeLanguageDetector)
14+
.use(languageDetector)
1315
.use(initReactI18next)
1416
.init({
1517
resources: {

src/languageDetector.ts

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,79 @@
1-
import { getLanguage, setLanguage } from './api';
1+
import { getLanguage, getLanguageAsync, setLanguage } from './api';
2+
3+
interface I18nLanguageDetectorModule {
4+
type: 'languageDetector';
5+
init?(): void;
6+
detect(): string | readonly string[] | undefined;
7+
cacheUserLanguage?(lang: string): void;
8+
}
9+
interface I18nLanguageDetectorAsyncModule {
10+
type: 'languageDetector';
11+
async: true;
12+
init?(): void;
13+
detect(
14+
callback: (lng: string | readonly string[] | undefined) => void | undefined
15+
): void | Promise<string | readonly string[] | undefined>;
16+
cacheUserLanguage?(lng: string): void | Promise<void>;
17+
}
18+
19+
type LanguageDetectorOptions = {
20+
cacheCurrentLanguage?: boolean;
21+
async?: boolean;
22+
};
23+
24+
/**
25+
* @deprecated Use createLanguageDetector instead
26+
*/
27+
export const ReactNativeLanguageDetector: I18nLanguageDetectorModule = {
28+
type: 'languageDetector',
29+
init: () => {},
30+
detect: () => getLanguage(),
31+
cacheUserLanguage: (lang: string) => setLanguage(lang),
32+
};
233

334
/**
4-
* i18next language detector
35+
* I18next language detector generator
36+
* @param options - detector options
37+
* @returns I18nLanguageDetectorModule | I18nLanguageDetectorAsyncModule
538
* @example
639
* Usage:
40+
* const languageDetector = createLanguageDetector(options);
741
* i18next
8-
* .use(ReactNativeLanguageDetector)
42+
* .use(languageDetector)
943
* .init({
1044
* ...
1145
* });
1246
*/
13-
export const ReactNativeLanguageDetector: I18nLanguageDetectorModule = {
14-
type: 'languageDetector',
15-
init: () => {},
16-
detect: () => getLanguage(),
17-
cacheUserLanguage: (lng: string) => setLanguage(lng),
18-
};
47+
export const createLanguageDetector = (
48+
options?: LanguageDetectorOptions
49+
): I18nLanguageDetectorModule | I18nLanguageDetectorAsyncModule => {
50+
const { cacheCurrentLanguage = false } = options || {};
51+
let skipNextCache = false;
1952

20-
interface I18nLanguageDetectorModule {
21-
type: 'languageDetector';
22-
init?(): void;
23-
detect(): string | readonly string[] | undefined;
24-
cacheUserLanguage?(lng: string): void;
25-
}
53+
let languageDetector:
54+
| I18nLanguageDetectorModule
55+
| I18nLanguageDetectorAsyncModule = {
56+
type: 'languageDetector',
57+
init: () => {
58+
skipNextCache = true;
59+
},
60+
detect: () => getLanguage(),
61+
cacheUserLanguage: (lang: string) => {
62+
if (cacheCurrentLanguage === false && skipNextCache) {
63+
skipNextCache = false;
64+
return;
65+
}
66+
setLanguage(lang);
67+
},
68+
};
69+
if (options?.async) {
70+
languageDetector = {
71+
...languageDetector,
72+
async: true,
73+
detect: (callback) => {
74+
getLanguageAsync().then(callback);
75+
},
76+
};
77+
}
78+
return languageDetector;
79+
};

0 commit comments

Comments
 (0)