Skip to content

Commit

Permalink
feat: introduce createLanguageDetector (#29)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jakex7 authored Nov 11, 2024
1 parent 4c9fb22 commit c361687
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 20 deletions.
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,19 +129,32 @@ setLanguage("en-US");
## i18next

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

To use it with i18next, create a language detector by using `createLanguageDetector` with the specified `options`:
```ts
import { ReactNativeLanguageDetector } from 'react-native-localization-settings';
import { createLanguageDetector } from 'react-native-localization-settings';

const languageDetector = createLanguageDetector({});

i18next
.use(ReactNativeLanguageDetector)
.use(languageDetector)
.use(initReactI18next)
.init({
// ...
});
```

### Options

```ts
type LanguageDetectorOptions = {
cacheCurrentLanguage?: boolean; // default: false - sets current detected language
async?: boolean; // default: false - uses getLanguageAsync (set to true on old architecture)
};
```

### Changing language

Then, if you want to create custom in-app language selector, you should be able to change the language (along with the
settings per-app language) using standard i18next function:

Expand Down
6 changes: 4 additions & 2 deletions example/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { StyleSheet, View, Text, Button } from 'react-native';
import i18next from 'i18next';
import { initReactI18next, useTranslation } from 'react-i18next';
import {
createLanguageDetector,
getLanguage,
getLanguageAsync,
ReactNativeLanguageDetector,
} from 'react-native-localization-settings';

const languageDetector = createLanguageDetector();

i18next
.use(ReactNativeLanguageDetector)
.use(languageDetector)
.use(initReactI18next)
.init({
resources: {
Expand Down
84 changes: 69 additions & 15 deletions src/languageDetector.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,79 @@
import { getLanguage, setLanguage } from './api';
import { getLanguage, getLanguageAsync, setLanguage } from './api';

interface I18nLanguageDetectorModule {
type: 'languageDetector';
init?(): void;
detect(): string | readonly string[] | undefined;
cacheUserLanguage?(lang: string): void;
}
interface I18nLanguageDetectorAsyncModule {
type: 'languageDetector';
async: true;
init?(): void;
detect(
callback: (lng: string | readonly string[] | undefined) => void | undefined
): void | Promise<string | readonly string[] | undefined>;
cacheUserLanguage?(lng: string): void | Promise<void>;
}

type LanguageDetectorOptions = {
cacheCurrentLanguage?: boolean;
async?: boolean;
};

/**
* @deprecated Use createLanguageDetector instead
*/
export const ReactNativeLanguageDetector: I18nLanguageDetectorModule = {
type: 'languageDetector',
init: () => {},
detect: () => getLanguage(),
cacheUserLanguage: (lang: string) => setLanguage(lang),
};

/**
* i18next language detector
* I18next language detector generator
* @param options - detector options
* @returns I18nLanguageDetectorModule | I18nLanguageDetectorAsyncModule
* @example
* Usage:
* const languageDetector = createLanguageDetector(options);
* i18next
* .use(ReactNativeLanguageDetector)
* .use(languageDetector)
* .init({
* ...
* });
*/
export const ReactNativeLanguageDetector: I18nLanguageDetectorModule = {
type: 'languageDetector',
init: () => {},
detect: () => getLanguage(),
cacheUserLanguage: (lng: string) => setLanguage(lng),
};
export const createLanguageDetector = (
options?: LanguageDetectorOptions
): I18nLanguageDetectorModule | I18nLanguageDetectorAsyncModule => {
const { cacheCurrentLanguage = false } = options || {};
let skipNextCache = false;

interface I18nLanguageDetectorModule {
type: 'languageDetector';
init?(): void;
detect(): string | readonly string[] | undefined;
cacheUserLanguage?(lng: string): void;
}
let languageDetector:
| I18nLanguageDetectorModule
| I18nLanguageDetectorAsyncModule = {
type: 'languageDetector',
init: () => {
skipNextCache = true;
},
detect: () => getLanguage(),
cacheUserLanguage: (lang: string) => {
if (cacheCurrentLanguage === false && skipNextCache) {
skipNextCache = false;
return;
}
setLanguage(lang);
},
};
if (options?.async) {
languageDetector = {
...languageDetector,
async: true,
detect: (callback) => {
getLanguageAsync().then(callback);
},
};
}
return languageDetector;
};

0 comments on commit c361687

Please sign in to comment.