diff --git a/apps/mobile/src/store/constants.ts b/apps/mobile/src/store/constants.ts index 0646a9476c..82e5eec3df 100644 --- a/apps/mobile/src/store/constants.ts +++ b/apps/mobile/src/store/constants.ts @@ -278,3 +278,47 @@ export const mockedChains = [ transactionService: 'https://safe-transaction-arbitrum.safe.global', }, ] + +export const STORAGE_IDS = { + SAFE: 'safe', + NOTIFICATIONS: 'notifications', + GLOBAL_PUSH_NOTIFICATION_SETTINGS: 'globalNotificationSettings', + SAFE_FCM_TOKEN: 'safeFcmToken', + PUSH_NOTIFICATIONS_PROMPT_COUNT: 'pushNotificationsPromptCount', + PUSH_NOTIFICATIONS_PROMPT_TIME: 'pushNotificationsPromptTime', + DEVICE_ID_STORAGE_KEY: 'pns:deviceId', + DEFAULT_NOTIFICATION_CHANNEL_ID: 'DEFAULT_NOTIFICATION_CHANNEL_ID', + ANNOUNCEMENT_NOTIFICATION_CHANNEL_ID: 'ANNOUNCEMENT_NOTIFICATION_CHANNEL_ID', + DEFAULT_PUSH_NOTIFICATION_CHANNEL_PRIORITY: 'high', + REQUEST_PERMISSION_ASKED: 'REQUEST_PERMISSION_ASKED', + REQUEST_PERMISSION_GRANTED: 'REQUEST_PERMISSION_GRANTED', + NOTIFICATION_DATE_FORMAT: 'DD/MM/YYYY HH:mm:ss', + NOTIFICATIONS_SETTINGS: 'notifications-settings', + PN_USER_STORAGE: 'safePnUserStorage', +} + +export const STORAGE_TYPES = { + STRING: 'string', + BOOLEAN: 'boolean', + NUMBER: 'number', + OBJECT: 'object', +} + +// Map all non string storage ids to their respective types +export const mapStorageTypeToIds = (id: string) => { + switch (id) { + case STORAGE_IDS.NOTIFICATIONS: + case STORAGE_IDS.GLOBAL_PUSH_NOTIFICATION_SETTINGS: + case STORAGE_IDS.SAFE_FCM_TOKEN: + case STORAGE_IDS.NOTIFICATIONS_SETTINGS: + case STORAGE_IDS.PN_USER_STORAGE: + return STORAGE_TYPES.OBJECT + case STORAGE_IDS.PUSH_NOTIFICATIONS_PROMPT_COUNT: + return STORAGE_TYPES.NUMBER + case STORAGE_IDS.REQUEST_PERMISSION_ASKED: + case STORAGE_IDS.REQUEST_PERMISSION_GRANTED: + return STORAGE_TYPES.BOOLEAN + default: + return STORAGE_TYPES.STRING + } +} diff --git a/apps/mobile/src/store/storage.ts b/apps/mobile/src/store/storage.ts index 1d8f617e75..9093f5c2ba 100644 --- a/apps/mobile/src/store/storage.ts +++ b/apps/mobile/src/store/storage.ts @@ -1,19 +1,69 @@ +/* eslint-disable @typescript-eslint/no-extraneous-class */ import { Storage } from 'redux-persist' import { MMKV } from 'react-native-mmkv' +import { mapStorageTypeToIds, STORAGE_IDS, STORAGE_TYPES } from './constants' -const storage = new MMKV() +const safeStorage = new MMKV({ + id: STORAGE_IDS.SAFE, +}) export const reduxStorage: Storage = { setItem: (key, value) => { - storage.set(key, value) + safeStorage.set(key, value) return Promise.resolve(true) }, getItem: (key) => { - const value = storage.getString(key) + const value = safeStorage.getString(key) return Promise.resolve(value) }, removeItem: (key) => { - storage.delete(key) + safeStorage.delete(key) return Promise.resolve() }, } + +export class safeMMKVStorage { + static getLocal(key: string) { + if (!key) { + return + } + + const keyType = mapStorageTypeToIds(key) + + switch (keyType) { + case STORAGE_TYPES.STRING: + return safeStorage.getString(key) + case STORAGE_TYPES.NUMBER: + return safeStorage.getNumber(key) + case STORAGE_TYPES.BOOLEAN: + return safeStorage.getBoolean(key) + case STORAGE_TYPES.OBJECT: + return JSON.parse(safeStorage.getString(key) || '{}') + default: + return safeStorage.getString(key) + } + } + + static saveLocal(key: string, value: string | number | boolean | ArrayBuffer) { + if (!key) { + return + } + const valueType = typeof value + + if (valueType === 'object') { + return safeStorage.set(key, JSON.stringify(value)) + } + + return safeStorage.set(key, value) + } + + static clearAllStorages() { + Object.keys(STORAGE_IDS).forEach((id) => { + const storage = new MMKV({ id }) + storage.clearAll() + }) + + const defaultStorage = new MMKV() + defaultStorage.clearAll() + } +}