refactor: replace secure storage with app storage across components and hooks
This commit is contained in:
@@ -4,7 +4,7 @@ import { useAppEvent } from '@repo/core-events';
|
|||||||
import { useTranslation } from '@repo/core-i18n';
|
import { useTranslation } from '@repo/core-i18n';
|
||||||
import { Bookmark, Trash2 } from 'lucide-react';
|
import { Bookmark, Trash2 } from 'lucide-react';
|
||||||
import { LAYOUT_EVENTS } from '../../../../../core/constants/events';
|
import { LAYOUT_EVENTS } from '../../../../../core/constants/events';
|
||||||
import { secureIndexedDB, AppStorageKey } from '../../../../../core/storage/local';
|
import { appDatabase, AppDatabaseKey } from '../../../../../core/storage/local';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||||
@@ -25,7 +25,7 @@ export function BookmarkDrawer() {
|
|||||||
|
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
try {
|
try {
|
||||||
const data = await secureIndexedDB.getItem<SavedPageItem[]>(AppStorageKey.BOOKMARK_PAGE);
|
const data = await appDatabase.getItem<SavedPageItem[]>(AppDatabaseKey.BOOKMARK_PAGE);
|
||||||
setItems(data || []);
|
setItems(data || []);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to load bookmark items', e);
|
console.error('Failed to load bookmark items', e);
|
||||||
@@ -44,7 +44,7 @@ export function BookmarkDrawer() {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
try {
|
try {
|
||||||
const newItems = items.filter((item) => item.id !== id);
|
const newItems = items.filter((item) => item.id !== id);
|
||||||
await secureIndexedDB.setItem(AppStorageKey.BOOKMARK_PAGE, newItems);
|
await appDatabase.setItem(AppDatabaseKey.BOOKMARK_PAGE, newItems);
|
||||||
setItems(newItems);
|
setItems(newItems);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to remove bookmark item', err);
|
console.error('Failed to remove bookmark item', err);
|
||||||
@@ -53,7 +53,7 @@ export function BookmarkDrawer() {
|
|||||||
|
|
||||||
const handleClearAll = async () => {
|
const handleClearAll = async () => {
|
||||||
try {
|
try {
|
||||||
await secureIndexedDB.removeItem(AppStorageKey.BOOKMARK_PAGE);
|
await appDatabase.removeItem(AppDatabaseKey.BOOKMARK_PAGE);
|
||||||
setItems([]);
|
setItems([]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to clear bookmarks', err);
|
console.error('Failed to clear bookmarks', err);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
} from '@repo/ui/components';
|
} from '@repo/ui/components';
|
||||||
import { Globe, Bell, HelpCircle, Settings, User, Briefcase, LogOut, ChevronDown, Sun, Moon } from 'lucide-react';
|
import { Globe, Bell, HelpCircle, Settings, User, Briefcase, LogOut, ChevronDown, Sun, Moon } from 'lucide-react';
|
||||||
import { AppStorageKey, secureStorage } from '../../../../core/storage/local';
|
import { AppStorageKey, appStorage } from '../../../../core/storage/local';
|
||||||
import { useThemeStore } from '../../../../core/stores/theme.store';
|
import { useThemeStore } from '../../../../core/stores/theme.store';
|
||||||
import { NotificationDropdown } from './notifications/notification-dropdown';
|
import { NotificationDropdown } from './notifications/notification-dropdown';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
@@ -131,7 +131,7 @@ export default function HeaderLayout() {
|
|||||||
onChange={async (val) => {
|
onChange={async (val) => {
|
||||||
if (!val) return;
|
if (!val) return;
|
||||||
await i18n.changeLanguage(val);
|
await i18n.changeLanguage(val);
|
||||||
await secureStorage.setItem(AppStorageKey.LANGUAGE, val);
|
await appStorage.setItem(AppStorageKey.LANGUAGE, val);
|
||||||
}}
|
}}
|
||||||
styles={{
|
styles={{
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { useAppEvent } from '@repo/core-events';
|
|||||||
import { useTranslation } from '@repo/core-i18n';
|
import { useTranslation } from '@repo/core-i18n';
|
||||||
import { History, Clock, Trash2 } from 'lucide-react';
|
import { History, Clock, Trash2 } from 'lucide-react';
|
||||||
import { LAYOUT_EVENTS } from '../../../../../core/constants/events';
|
import { LAYOUT_EVENTS } from '../../../../../core/constants/events';
|
||||||
import { secureIndexedDB, AppStorageKey } from '../../../../../core/storage/local';
|
import { appDatabase, AppDatabaseKey } from '../../../../../core/storage/local';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||||
@@ -38,9 +38,9 @@ export function HistoryDrawer() {
|
|||||||
|
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
try {
|
try {
|
||||||
const data = await secureIndexedDB.getItem<SavedPageItem[]>(AppStorageKey.HISTORY_PAGE);
|
const data = await appDatabase.getItem<SavedPageItem[]>(AppDatabaseKey.HISTORY_PAGE);
|
||||||
const settings =
|
const settings =
|
||||||
(await secureIndexedDB.getItem<SystemSettings>(AppStorageKey.SYSTEM_SETTINGS)) || DEFAULT_SYSTEM_SETTINGS;
|
(await appDatabase.getItem<SystemSettings>(AppDatabaseKey.SYSTEM_SETTINGS)) || DEFAULT_SYSTEM_SETTINGS;
|
||||||
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const unitMs = {
|
const unitMs = {
|
||||||
@@ -55,7 +55,7 @@ export function HistoryDrawer() {
|
|||||||
|
|
||||||
// Save back if we purged some items
|
// Save back if we purged some items
|
||||||
if (data && validItems.length !== data.length) {
|
if (data && validItems.length !== data.length) {
|
||||||
await secureIndexedDB.setItem(AppStorageKey.HISTORY_PAGE, validItems);
|
await appDatabase.setItem(AppDatabaseKey.HISTORY_PAGE, validItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
setItems(validItems);
|
setItems(validItems);
|
||||||
@@ -74,7 +74,7 @@ export function HistoryDrawer() {
|
|||||||
const handleClearRange = async (range: 'lastHour' | 'today' | 'allTime') => {
|
const handleClearRange = async (range: 'lastHour' | 'today' | 'allTime') => {
|
||||||
try {
|
try {
|
||||||
if (range === 'allTime') {
|
if (range === 'allTime') {
|
||||||
await secureIndexedDB.removeItem(AppStorageKey.HISTORY_PAGE);
|
await appDatabase.removeItem(AppDatabaseKey.HISTORY_PAGE);
|
||||||
setItems([]);
|
setItems([]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ export function HistoryDrawer() {
|
|||||||
const cutoff = range === 'lastHour' ? now - 60 * 60 * 1000 : new Date().setHours(0, 0, 0, 0); // start of today
|
const cutoff = range === 'lastHour' ? now - 60 * 60 * 1000 : new Date().setHours(0, 0, 0, 0); // start of today
|
||||||
|
|
||||||
const newItems = items.filter((item) => item.timestamp < cutoff);
|
const newItems = items.filter((item) => item.timestamp < cutoff);
|
||||||
await secureIndexedDB.setItem(AppStorageKey.HISTORY_PAGE, newItems);
|
await appDatabase.setItem(AppDatabaseKey.HISTORY_PAGE, newItems);
|
||||||
setItems(newItems);
|
setItems(newItems);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to clear history items', e);
|
console.error('Failed to clear history items', e);
|
||||||
@@ -95,7 +95,7 @@ export function HistoryDrawer() {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
try {
|
try {
|
||||||
const newItems = items.filter((item) => item.id !== id);
|
const newItems = items.filter((item) => item.id !== id);
|
||||||
await secureIndexedDB.setItem(AppStorageKey.HISTORY_PAGE, newItems);
|
await appDatabase.setItem(AppDatabaseKey.HISTORY_PAGE, newItems);
|
||||||
setItems(newItems);
|
setItems(newItems);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to remove history item', err);
|
console.error('Failed to remove history item', err);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { secureIndexedDB, AppStorageKey } from '../../../../core/storage/local';
|
import { appDatabase, AppDatabaseKey } from '../../../../core/storage/local';
|
||||||
import type { SavedPageItem } from '../types/saved-page.types';
|
import type { SavedPageItem } from '../types/saved-page.types';
|
||||||
import type { SystemSettings } from '../../system/setting/types/setting.types';
|
import type { SystemSettings } from '../../system/setting/types/setting.types';
|
||||||
import { DEFAULT_SYSTEM_SETTINGS } from '../../system/setting/types/setting.types';
|
import { DEFAULT_SYSTEM_SETTINGS } from '../../system/setting/types/setting.types';
|
||||||
@@ -34,7 +34,7 @@ export async function initializeAndPurgeHistoryBackground() {
|
|||||||
if (isHistoryReady) return;
|
if (isHistoryReady) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = (await secureIndexedDB.getItem<SavedPageItem[]>(AppStorageKey.HISTORY_PAGE)) || [];
|
const data = (await appDatabase.getItem<SavedPageItem[]>(AppDatabaseKey.HISTORY_PAGE)) || [];
|
||||||
|
|
||||||
if (data.length === 0) {
|
if (data.length === 0) {
|
||||||
isHistoryReady = true;
|
isHistoryReady = true;
|
||||||
@@ -42,7 +42,7 @@ export async function initializeAndPurgeHistoryBackground() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const settings =
|
const settings =
|
||||||
(await secureIndexedDB.getItem<SystemSettings>(AppStorageKey.SYSTEM_SETTINGS)) || DEFAULT_SYSTEM_SETTINGS;
|
(await appDatabase.getItem<SystemSettings>(AppDatabaseKey.SYSTEM_SETTINGS)) || DEFAULT_SYSTEM_SETTINGS;
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const unitMs: Record<string, number> = {
|
const unitMs: Record<string, number> = {
|
||||||
seconds: 1000,
|
seconds: 1000,
|
||||||
@@ -58,7 +58,7 @@ export async function initializeAndPurgeHistoryBackground() {
|
|||||||
isHistoryReady = true;
|
isHistoryReady = true;
|
||||||
|
|
||||||
if (validItems.length !== data.length) {
|
if (validItems.length !== data.length) {
|
||||||
await secureIndexedDB.setItem(AppStorageKey.HISTORY_PAGE, validItems);
|
await appDatabase.setItem(AppDatabaseKey.HISTORY_PAGE, validItems);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[HistoryManager] Failed to init history', err);
|
console.error('[HistoryManager] Failed to init history', err);
|
||||||
@@ -100,7 +100,7 @@ export function useHistoryTracker() {
|
|||||||
historyChannel?.postMessage(newItem);
|
historyChannel?.postMessage(newItem);
|
||||||
|
|
||||||
// 3. Save to IndexedDB in the background (Asynchronous)
|
// 3. Save to IndexedDB in the background (Asynchronous)
|
||||||
secureIndexedDB.setItem(AppStorageKey.HISTORY_PAGE, memoryHistoryCache).catch((err) => {
|
appDatabase.setItem(AppDatabaseKey.HISTORY_PAGE, memoryHistoryCache).catch((err) => {
|
||||||
console.error('[HistoryManager] Failed to track history', err);
|
console.error('[HistoryManager] Failed to track history', err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useForm } from 'react-hook-form';
|
|||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { FieldNumberInput, FieldSelect } from '@repo/ui/form';
|
import { FieldNumberInput, FieldSelect } from '@repo/ui/form';
|
||||||
import { secureIndexedDB, AppStorageKey } from '../../../../../core/storage/local';
|
import { appDatabase, AppDatabaseKey } from '../../../../../core/storage/local';
|
||||||
import type { SystemSettings, RetentionUnit } from '../types/setting.types';
|
import type { SystemSettings, RetentionUnit } from '../types/setting.types';
|
||||||
import { DEFAULT_SYSTEM_SETTINGS } from '../types/setting.types';
|
import { DEFAULT_SYSTEM_SETTINGS } from '../types/setting.types';
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ export function HistorySetting({ onDirtyChange }: { onDirtyChange: (isDirty: boo
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadSettings = async () => {
|
const loadSettings = async () => {
|
||||||
try {
|
try {
|
||||||
const settings = await secureIndexedDB.getItem<SystemSettings>(AppStorageKey.SYSTEM_SETTINGS);
|
const settings = await appDatabase.getItem<SystemSettings>(AppDatabaseKey.SYSTEM_SETTINGS);
|
||||||
if (settings) {
|
if (settings) {
|
||||||
reset({
|
reset({
|
||||||
historyRetentionValue: settings.historyRetentionValue,
|
historyRetentionValue: settings.historyRetentionValue,
|
||||||
@@ -61,7 +61,7 @@ export function HistorySetting({ onDirtyChange }: { onDirtyChange: (isDirty: boo
|
|||||||
|
|
||||||
const handleReset = async () => {
|
const handleReset = async () => {
|
||||||
try {
|
try {
|
||||||
const settings = await secureIndexedDB.getItem<SystemSettings>(AppStorageKey.SYSTEM_SETTINGS);
|
const settings = await appDatabase.getItem<SystemSettings>(AppDatabaseKey.SYSTEM_SETTINGS);
|
||||||
if (settings) {
|
if (settings) {
|
||||||
reset({
|
reset({
|
||||||
historyRetentionValue: settings.historyRetentionValue,
|
historyRetentionValue: settings.historyRetentionValue,
|
||||||
@@ -82,13 +82,13 @@ export function HistorySetting({ onDirtyChange }: { onDirtyChange: (isDirty: boo
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const currentSettings =
|
const currentSettings =
|
||||||
(await secureIndexedDB.getItem<SystemSettings>(AppStorageKey.SYSTEM_SETTINGS)) || DEFAULT_SYSTEM_SETTINGS;
|
(await appDatabase.getItem<SystemSettings>(AppDatabaseKey.SYSTEM_SETTINGS)) || DEFAULT_SYSTEM_SETTINGS;
|
||||||
const newSettings = {
|
const newSettings = {
|
||||||
...currentSettings,
|
...currentSettings,
|
||||||
historyRetentionValue: data.historyRetentionValue,
|
historyRetentionValue: data.historyRetentionValue,
|
||||||
historyRetentionUnit: data.historyRetentionUnit as RetentionUnit,
|
historyRetentionUnit: data.historyRetentionUnit as RetentionUnit,
|
||||||
};
|
};
|
||||||
await secureIndexedDB.setItem(AppStorageKey.SYSTEM_SETTINGS, newSettings);
|
await appDatabase.setItem(AppDatabaseKey.SYSTEM_SETTINGS, newSettings);
|
||||||
|
|
||||||
reset(data); // Reset form to clear dirty state
|
reset(data); // Reset form to clear dirty state
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createHttpClient } from '@repo/core-api/http-client';
|
import { createHttpClient } from '@repo/core-api/http-client';
|
||||||
import { faroAdapter } from '@repo/core-api/observability';
|
import { faroAdapter } from '@repo/core-api/observability';
|
||||||
import { ENV } from '../environment';
|
import { ENV } from '../environment';
|
||||||
import { AppStorageKey, secureStorage } from '../storage/local';
|
import { AppStorageKey, appStorage } from '../storage/local';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enterprise HTTP client for `apps/web`.
|
* Enterprise HTTP client for `apps/web`.
|
||||||
@@ -29,7 +29,7 @@ export const apiClient = createHttpClient(
|
|||||||
config.headers['ex-timezone-offset-minutes'] = new Date().getTimezoneOffset();
|
config.headers['ex-timezone-offset-minutes'] = new Date().getTimezoneOffset();
|
||||||
config.headers['ex-timezone-offset-hours'] = Math.floor(new Date().getTimezoneOffset() / 60);
|
config.headers['ex-timezone-offset-hours'] = Math.floor(new Date().getTimezoneOffset() / 60);
|
||||||
|
|
||||||
const language = await secureStorage.getItem<string>(AppStorageKey.LANGUAGE);
|
const language = await appStorage.getItem<string>(AppStorageKey.LANGUAGE);
|
||||||
config.headers['ex-language'] = language ?? ENV.DEFAULT_LANGUAGE;
|
config.headers['ex-language'] = language ?? ENV.DEFAULT_LANGUAGE;
|
||||||
|
|
||||||
const token = localStorage.getItem('access_token');
|
const token = localStorage.getItem('access_token');
|
||||||
|
|||||||
@@ -6,39 +6,47 @@ export const AppStorageKey = {
|
|||||||
THEME: 'app_theme',
|
THEME: 'app_theme',
|
||||||
ACCESS_TOKEN: 'access_token',
|
ACCESS_TOKEN: 'access_token',
|
||||||
REFRESH_TOKEN: 'refresh_token',
|
REFRESH_TOKEN: 'refresh_token',
|
||||||
MOCK_DB_COMPANY_A: 'mock_db_company_a',
|
} as const;
|
||||||
|
|
||||||
|
export type AppStorageKeyValue = (typeof AppStorageKey)[keyof typeof AppStorageKey];
|
||||||
|
|
||||||
|
export const AppDatabaseKey = {
|
||||||
OFFLINE_DRAFT: 'offline_draft',
|
OFFLINE_DRAFT: 'offline_draft',
|
||||||
SYSTEM_SETTINGS: 'system_settings',
|
SYSTEM_SETTINGS: 'system_settings',
|
||||||
HISTORY_PAGE: 'history_page',
|
HISTORY_PAGE: 'history_page',
|
||||||
BOOKMARK_PAGE: 'bookmark_page',
|
BOOKMARK_PAGE: 'bookmark_page',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type AppStorageKeyValue = (typeof AppStorageKey)[keyof typeof AppStorageKey];
|
export type AppDatabaseKeyValue = (typeof AppDatabaseKey)[keyof typeof AppDatabaseKey];
|
||||||
|
|
||||||
export const ENCRYPTED_KEYS = new Set<AppStorageKeyValue>([
|
export const APP_STORAGE_ENCRYPTED_KEYS = new Set<AppStorageKeyValue>([
|
||||||
AppStorageKey.USER_PROFILE,
|
AppStorageKey.USER_PROFILE,
|
||||||
AppStorageKey.ACCESS_TOKEN,
|
AppStorageKey.ACCESS_TOKEN,
|
||||||
AppStorageKey.REFRESH_TOKEN,
|
AppStorageKey.REFRESH_TOKEN,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const PLAIN_KEYS = new Set<AppStorageKeyValue>([
|
export const APP_STORAGE_PLAIN_KEYS = new Set<AppStorageKeyValue>([
|
||||||
AppStorageKey.LANGUAGE,
|
AppStorageKey.LANGUAGE,
|
||||||
AppStorageKey.THEME,
|
AppStorageKey.THEME,
|
||||||
AppStorageKey.MOCK_DB_COMPANY_A,
|
|
||||||
AppStorageKey.OFFLINE_DRAFT,
|
|
||||||
AppStorageKey.SYSTEM_SETTINGS,
|
|
||||||
AppStorageKey.HISTORY_PAGE,
|
|
||||||
AppStorageKey.BOOKMARK_PAGE,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const secureStorage = createLocalStorage<AppStorageKeyValue>({
|
export const APP_DATABASE_ENCRYPTED_KEYS = new Set<AppDatabaseKeyValue>([]);
|
||||||
encryptedKeys: ENCRYPTED_KEYS,
|
|
||||||
plainTextKeys: PLAIN_KEYS,
|
export const APP_DATABASE_PLAIN_KEYS = new Set<AppDatabaseKeyValue>([
|
||||||
|
AppDatabaseKey.OFFLINE_DRAFT,
|
||||||
|
AppDatabaseKey.SYSTEM_SETTINGS,
|
||||||
|
AppDatabaseKey.HISTORY_PAGE,
|
||||||
|
AppDatabaseKey.BOOKMARK_PAGE,
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const appStorage = createLocalStorage<AppStorageKeyValue>({
|
||||||
|
encryptedKeys: APP_STORAGE_ENCRYPTED_KEYS,
|
||||||
|
plainTextKeys: APP_STORAGE_PLAIN_KEYS,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const secureIndexedDB = createIndexedDB<AppStorageKeyValue>({
|
export const appDatabase = createIndexedDB<AppDatabaseKeyValue>({
|
||||||
dbName: 'e_apps_db',
|
dbName: 'e_apps_db',
|
||||||
storeName: 'web_store',
|
storeName: 'web_store',
|
||||||
encryptedKeys: ENCRYPTED_KEYS,
|
encryptedKeys: APP_DATABASE_ENCRYPTED_KEYS,
|
||||||
plainTextKeys: PLAIN_KEYS,
|
plainTextKeys: APP_DATABASE_PLAIN_KEYS,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,21 +16,21 @@ import './main.css';
|
|||||||
import { lazy, StrictMode } from 'react';
|
import { lazy, StrictMode } from 'react';
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
import { setupI18n } from '@repo/core-i18n';
|
import { setupI18n } from '@repo/core-i18n';
|
||||||
import { secureStorage, AppStorageKey } from './core/storage/local';
|
import { appStorage, AppStorageKey } from './core/storage/local';
|
||||||
import { ENV } from './core/environment';
|
import { ENV } from './core/environment';
|
||||||
|
|
||||||
const App = lazy(() => import('./apps'));
|
const App = lazy(() => import('./apps'));
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
// Initialize i18next and load language from secureStorage
|
// Initialize i18next and load language from appStorage
|
||||||
await setupI18n(
|
await setupI18n(
|
||||||
{
|
{
|
||||||
storageAdapter: {
|
storageAdapter: {
|
||||||
getLanguage: async () => {
|
getLanguage: async () => {
|
||||||
return secureStorage.getItem<string>(AppStorageKey.LANGUAGE);
|
return appStorage.getItem<string>(AppStorageKey.LANGUAGE);
|
||||||
},
|
},
|
||||||
setLanguage: async (lng: string) => {
|
setLanguage: async (lng: string) => {
|
||||||
await secureStorage.setItem(AppStorageKey.LANGUAGE, lng);
|
await appStorage.setItem(AppStorageKey.LANGUAGE, lng);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user