diff --git a/package-lock.json b/package-lock.json index 9862386..5d1d31d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "fintunes", - "version": "2.4.0", + "version": "2.4.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "fintunes", - "version": "2.4.0", + "version": "2.4.1", "hasInstallScript": true, "dependencies": { "@react-native-async-storage/async-storage": "^1.21.0", diff --git a/package.json b/package.json index 5197c9b..7390b1f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fintunes", - "version": "2.4.0", + "version": "2.4.1", "main": "src/index.js", "private": true, "scripts": { diff --git a/src/store/index.ts b/src/store/index.ts index 67ffbe8..ec87c46 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,6 +1,5 @@ import { configureStore, combineReducers } from '@reduxjs/toolkit'; import { useSelector, TypedUseSelectorHook, useDispatch } from 'react-redux'; -import AsyncStorage from '@react-native-async-storage/async-storage'; import { persistStore, persistReducer, PersistConfig, createMigrate, PersistState } from 'redux-persist'; import autoMergeLevel2 from 'redux-persist/es/stateReconciler/autoMergeLevel2'; @@ -9,10 +8,11 @@ import music, { initialState as musicInitialState } from './music'; import downloads, { initialState as downloadsInitialState } from './downloads'; import sleepTimer from './sleep-timer'; import { ColorScheme } from './settings/types'; +import MigratedStorage from '@/utility/MigratedStorage'; const persistConfig: PersistConfig> = { key: 'root', - storage: AsyncStorage, + storage: MigratedStorage, version: 2, stateReconciler: autoMergeLevel2, migrate: createMigrate({ @@ -80,7 +80,7 @@ const persistConfig: PersistConfig> = { credentials, }, }; - } + }, }) }; diff --git a/src/utility/MigratedStorage.ts b/src/utility/MigratedStorage.ts new file mode 100644 index 0000000..38ea13f --- /dev/null +++ b/src/utility/MigratedStorage.ts @@ -0,0 +1,51 @@ +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { DocumentDirectoryPath, exists, readFile, writeFile, unlink, mkdir } from 'react-native-fs'; +import { Storage } from 'redux-persist'; + +const STORAGE_BASE_PATH = DocumentDirectoryPath + '/store/'; + +/** Retrieve the path of a store file for a given key */ +function getFileByKey(key: string) { + return STORAGE_BASE_PATH + encodeURIComponent(key) + '.json'; +} + +/** Ensure that the store directory exists on the local filesystem */ +async function ensureDirectoryExists() { + if (!(await exists(STORAGE_BASE_PATH))) { + await mkdir(STORAGE_BASE_PATH); + } +} + +/** + * Migrates the Redux store from AsyncStorage to react-native-fs. + */ +const MigratedStorage: Storage = { + async getItem(key) { + const path = getFileByKey(key); + + // GUARD: Check whether a store already exists on the filesystem + if (await exists(path)) { + // In which case, we'll read it from disk + return readFile(path); + } else { + // If not, attempt to read the previous store from AsyncStorage + const oldStore = await AsyncStorage.getItem(key); + + // GUARD: If it exists, migrate it to a file on the filesystem + if (oldStore) { + await ensureDirectoryExists(); + await writeFile(path, oldStore); + return oldStore; + } + } + }, + removeItem(key) { + return unlink(getFileByKey(key)); + }, + async setItem(key, value) { + await ensureDirectoryExists(); + return writeFile(getFileByKey(key), value); + }, +}; + +export default MigratedStorage; \ No newline at end of file