fix: save store file to filesystem

AsyncStorage can only save 2MB on Android. This might not be enough for large libraries. Hence, we'll save the file to disk, where space is (virtually) unlimited
This commit is contained in:
Lei Nelissen
2025-01-27 17:21:44 +01:00
parent 4e30fa0a40
commit b1c86f2142
4 changed files with 57 additions and 6 deletions

4
package-lock.json generated
View File

@@ -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",

View File

@@ -1,6 +1,6 @@
{
"name": "fintunes",
"version": "2.4.0",
"version": "2.4.1",
"main": "src/index.js",
"private": true,
"scripts": {

View File

@@ -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<Omit<AppState, '_persist'>> = {
key: 'root',
storage: AsyncStorage,
storage: MigratedStorage,
version: 2,
stateReconciler: autoMergeLevel2,
migrate: createMigrate({
@@ -80,7 +80,7 @@ const persistConfig: PersistConfig<Omit<AppState, '_persist'>> = {
credentials,
},
};
}
},
})
};

View File

@@ -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;