diff --git a/src/index.ts b/src/index.ts index 85a872ee5..6ada09cd7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,13 +15,13 @@ import {getBackgroundI18n} from 'locale'; import {name as appName} from '../app.json'; -import {useStorageService} from './services/StorageService'; +import {createStorageService} from './services/StorageService'; import App from './App'; AppRegistry.registerComponent(appName, () => App); BackgroundScheduler.registerAndroidHeadlessPeriodicTask(async () => { - const storageService = useStorageService(); + const storageService = await createStorageService(); const backendService = new BackendService(RETRIEVE_URL, SUBMIT_URL, HMAC_KEY, storageService?.region); const i18n = await getBackgroundI18n(); const exposureNotificationService = new ExposureNotificationService( diff --git a/src/locale/i18n.ts b/src/locale/i18n.ts index dafb2d8bb..5bcb89cf0 100644 --- a/src/locale/i18n.ts +++ b/src/locale/i18n.ts @@ -1,26 +1,19 @@ import {I18n, I18nManager} from '@shopify/react-i18n'; -import {StorageService} from 'services/StorageService'; +import {createStorageService} from 'services/StorageService'; import LOCALES from './translations'; export const getBackgroundI18n = async (forceLocale?: string) => { - const storageService = new StorageService(); - return new Promise(resolve => { - storageService.ready.observe(ready => { - if (!ready) { - return; - } - const locale = forceLocale || storageService.locale.get(); - const i18nManager = new I18nManager({ - locale, - onError(error) { - console.log('>>> i18N', error); - }, - }); - const translations = (locale: string) => LOCALES[locale]; - i18nManager.register({id: 'global', translations, fallback: LOCALES[locale]}); - const i18n = new I18n(LOCALES[locale], {...i18nManager.details}); - resolve(i18n); - }); + const storageService = await createStorageService(); + const locale = forceLocale || storageService.locale.get(); + const i18nManager = new I18nManager({ + locale, + onError(error) { + console.log('>>> i18N', error); + }, }); + const translations = (locale: string) => LOCALES[locale]; + i18nManager.register({id: 'global', translations, fallback: LOCALES[locale]}); + const i18n = new I18n(LOCALES[locale], {...i18nManager.details}); + return i18n; }; diff --git a/src/services/StorageService/StorageService.ts b/src/services/StorageService/StorageService.ts index 4f1e87745..17b31b537 100644 --- a/src/services/StorageService/StorageService.ts +++ b/src/services/StorageService/StorageService.ts @@ -20,17 +20,13 @@ export class StorageService { forceScreen: Observable; skipAllSet: Observable; - ready: Observable; - constructor() { this.isOnboarding = new Observable(true); this.locale = new Observable(getSystemLocale()); - this.ready = new Observable(false); this.region = new Observable(undefined); this.onboardedDatetime = new Observable(undefined); this.forceScreen = new Observable(undefined); this.skipAllSet = new Observable(false); - this.init(); } setOnboarded = async (value: boolean) => { @@ -63,7 +59,7 @@ export class StorageService { this.skipAllSet.set(value); }; - private init = async () => { + init = async () => { const isOnboarded = (await AsyncStorage.getItem(Key.IsOnboarded)) === '1'; this.isOnboarding.set(!isOnboarded); @@ -83,7 +79,11 @@ export class StorageService { const skipAllSet = (await AsyncStorage.getItem(Key.SkipAllSet)) === '1'; this.skipAllSet.set(skipAllSet); - - this.ready.set(true); }; } + +export const createStorageService = async () => { + const storageService = new StorageService(); + await storageService.init(); + return storageService; +}; diff --git a/src/services/StorageService/StorageServiceProvider.tsx b/src/services/StorageService/StorageServiceProvider.tsx index d71d0972d..ea1bb9573 100644 --- a/src/services/StorageService/StorageServiceProvider.tsx +++ b/src/services/StorageService/StorageServiceProvider.tsx @@ -3,8 +3,9 @@ import AsyncStorage from '@react-native-community/async-storage'; import {I18nContext} from '@shopify/react-i18n'; import {getSystemLocale} from 'locale'; import {DevSettings} from 'react-native'; +import {createCancellableCallbackPromise} from 'shared/cancellablePromise'; -import {StorageService} from './StorageService'; +import {StorageService, createStorageService} from './StorageService'; const StorageServiceContext = createContext(undefined); @@ -13,12 +14,17 @@ export interface StorageServiceProviderProps { } export const StorageServiceProvider = ({children}: StorageServiceProviderProps) => { - const storageService = useMemo(() => new StorageService(), []); - const [ready, setReady] = useState(false); + const [storageService, setStorageService] = useState(); - useEffect(() => storageService.ready.observe(setReady), [storageService]); + useEffect(() => { + const {callable, cancelable} = createCancellableCallbackPromise(() => createStorageService(), setStorageService); + callable(); + return cancelable; + }, []); - return {ready && children}; + return ( + {storageService && children} + ); }; export const useStorageService = () => {