From e48d55c3e5d1491d1f181843d2d98ca7469ea3e1 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Thu, 1 Jun 2023 16:48:02 +0100 Subject: [PATCH] Mobile: Auto-detect language on start --- packages/app-mobile/ios/Podfile.lock | 6 +++++ packages/app-mobile/package.json | 1 + packages/app-mobile/root.tsx | 11 +++++---- packages/app-mobile/utils/shim-init-react.js | 26 ++++++++++++++++++++ yarn.lock | 15 +++++++++++ 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/packages/app-mobile/ios/Podfile.lock b/packages/app-mobile/ios/Podfile.lock index 72277712e..c4f8ec003 100644 --- a/packages/app-mobile/ios/Podfile.lock +++ b/packages/app-mobile/ios/Podfile.lock @@ -412,6 +412,8 @@ PODS: - React-Core - RNGestureHandler (2.9.0): - React-Core + - RNLocalize (3.0.0): + - React-Core - RNQuickAction (0.3.13): - React - RNReanimated (3.1.0): @@ -534,6 +536,7 @@ DEPENDENCIES: - RNFileViewer (from `../node_modules/react-native-file-viewer`) - RNFS (from `../node_modules/react-native-fs`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) + - RNLocalize (from `../node_modules/react-native-localize`) - RNQuickAction (from `../node_modules/react-native-quick-actions`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNSecureRandom (from `../node_modules/react-native-securerandom`) @@ -674,6 +677,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-fs" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" + RNLocalize: + :path: "../node_modules/react-native-localize" RNQuickAction: :path: "../node_modules/react-native-quick-actions" RNReanimated: @@ -758,6 +763,7 @@ SPEC CHECKSUMS: RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592 RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39 + RNLocalize: 5944c97d2fe8150913a51ddd5eab4e23a82bd80d RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93 RNReanimated: 47df570b2e2b9eba34e78a299dd6d44596ff7bb6 RNSecureRandom: 07efbdf2cd99efe13497433668e54acd7df49fef diff --git a/packages/app-mobile/package.json b/packages/app-mobile/package.json index 171bd403e..4a08b6a3d 100644 --- a/packages/app-mobile/package.json +++ b/packages/app-mobile/package.json @@ -55,6 +55,7 @@ "react-native-get-random-values": "1.8.0", "react-native-image-picker": "5.3.1", "react-native-image-resizer": "1.4.5", + "react-native-localize": "3.0.0", "react-native-modal-datetime-picker": "14.0.1", "react-native-paper": "5.8.0", "react-native-popup-menu": "0.16.1", diff --git a/packages/app-mobile/root.tsx b/packages/app-mobile/root.tsx index c74fbe32c..00f982ecb 100644 --- a/packages/app-mobile/root.tsx +++ b/packages/app-mobile/root.tsx @@ -22,13 +22,13 @@ import handleShared from './utils/shareHandler'; import uuid from '@joplin/lib/uuid'; import { loadKeychainServiceAndSettings } from '@joplin/lib/services/SettingUtils'; import KeychainServiceDriverMobile from '@joplin/lib/services/keychain/KeychainServiceDriver.mobile'; -import { setLocale, closestSupportedLocale, defaultLocale } from '@joplin/lib/locale'; +import { setLocale } from '@joplin/lib/locale'; import SyncTargetJoplinServer from '@joplin/lib/SyncTargetJoplinServer'; import SyncTargetJoplinCloud from '@joplin/lib/SyncTargetJoplinCloud'; import SyncTargetOneDrive from '@joplin/lib/SyncTargetOneDrive'; import initProfile from '@joplin/lib/services/profileConfig/initProfile'; const VersionInfo = require('react-native-version-info').default; -const { Keyboard, NativeModules, BackHandler, View, StatusBar, Platform, Dimensions } = require('react-native'); +const { Keyboard, BackHandler, View, StatusBar, Platform, Dimensions } = require('react-native'); import { AppState as RNAppState, EmitterSubscription, Linking, NativeEventSubscription } from 'react-native'; import getResponsiveValue from './components/getResponsiveValue'; import NetInfo from '@react-native-community/netinfo'; @@ -516,10 +516,11 @@ async function initialize(dispatch: Function) { if (!Setting.value('clientId')) Setting.setValue('clientId', uuid.create()); reg.logger().info(`Client ID: ${Setting.value('clientId')}`); + if (Setting.value('firstStart')) { - let locale = NativeModules.I18nManager.localeIdentifier; - if (!locale) locale = defaultLocale(); - Setting.setValue('locale', closestSupportedLocale(locale)); + const detectedLocale = shim.detectAndSetLocale(Setting); + reg.logger().info(`First start: detected locale as ${detectedLocale}`); + Setting.skipDefaultMigrations(); Setting.setValue('firstStart', 0); } else { diff --git a/packages/app-mobile/utils/shim-init-react.js b/packages/app-mobile/utils/shim-init-react.js index b7dc9bb9f..68f336898 100644 --- a/packages/app-mobile/utils/shim-init-react.js +++ b/packages/app-mobile/utils/shim-init-react.js @@ -10,6 +10,8 @@ const mimeUtils = require('@joplin/lib/mime-utils.js').mime; const { basename, fileExtension } = require('@joplin/lib/path-utils'); const uuid = require('@joplin/lib/uuid').default; const Resource = require('@joplin/lib/models/Resource').default; +const { getLocales } = require('react-native-localize'); +const { setLocale, defaultLocale, closestSupportedLocale } = require('@joplin/lib/locale'); const injectedJs = { webviewLib: require('@joplin/lib/rnInjectedJs/webviewLib'), @@ -85,6 +87,30 @@ function shimInit() { /* eslint-enable */ + shim.detectAndSetLocale = (Setting) => { + // [ + // { + // "countryCode": "US", + // "isRTL": false, + // "languageCode": "fr", + // "languageTag": "fr-US" + // }, + // { + // "countryCode": "US", + // "isRTL": false, + // "languageCode": "en", + // "languageTag": "en-US" + // } + // ] + + const locales = getLocales(); + let locale = locales.length ? locales[0].languageTag : defaultLocale(); + locale = closestSupportedLocale(locale); + Setting.setValue('locale', locale); + setLocale(locale); + return locale; + }; + shim.fetch = async function(url, options = null) { // The native fetch() throws an uncatchable error that crashes the // app if calling it with an invalid URL such as '//.resource' or diff --git a/yarn.lock b/yarn.lock index ca23d6f2e..73a923324 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5072,6 +5072,7 @@ __metadata: react-native-get-random-values: 1.8.0 react-native-image-picker: 5.3.1 react-native-image-resizer: 1.4.5 + react-native-localize: 3.0.0 react-native-modal-datetime-picker: 14.0.1 react-native-paper: 5.8.0 react-native-popup-menu: 0.16.1 @@ -27751,6 +27752,20 @@ __metadata: languageName: node linkType: hard +"react-native-localize@npm:3.0.0": + version: 3.0.0 + resolution: "react-native-localize@npm:3.0.0" + peerDependencies: + react: ">=18.1.0" + react-native: ">=0.70.0" + react-native-macos: ">=0.70.0" + peerDependenciesMeta: + react-native-macos: + optional: true + checksum: c03bacddc05c02b7bac70aceb23f65cbf93d48c0630c7a460fcb6c247379970b3e75c4689b4c281763d425a2272f0f563c0b47c38be8efbfa231e502c0f06480 + languageName: node + linkType: hard + "react-native-modal-datetime-picker@npm:14.0.1": version: 14.0.1 resolution: "react-native-modal-datetime-picker@npm:14.0.1"