2022-09-16 17:18:15 +00:00
|
|
|
import { combineReducers, configureStore } from '@reduxjs/toolkit';
|
2022-09-18 07:33:09 +00:00
|
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
|
|
import type { TypedUseSelectorHook } from 'react-redux';
|
|
|
|
|
2022-09-16 17:18:15 +00:00
|
|
|
import { persistReducer } from 'redux-persist';
|
|
|
|
import storage from 'redux-persist/lib/storage'; // defaults to localStorage for web
|
|
|
|
|
2022-09-20 13:17:31 +00:00
|
|
|
import optionsReducer from '../features/options/optionsSlice';
|
2022-09-16 17:18:15 +00:00
|
|
|
import galleryReducer from '../features/gallery/gallerySlice';
|
2022-10-03 16:15:26 +00:00
|
|
|
|
2022-09-16 17:18:15 +00:00
|
|
|
import systemReducer from '../features/system/systemSlice';
|
2022-09-18 07:33:09 +00:00
|
|
|
import { socketioMiddleware } from './socketio/middleware';
|
2022-09-16 17:18:15 +00:00
|
|
|
|
2022-09-18 07:33:09 +00:00
|
|
|
/**
|
|
|
|
* redux-persist provides an easy and reliable way to persist state across reloads.
|
|
|
|
*
|
|
|
|
* While we definitely want generation parameters to be persisted, there are a number
|
|
|
|
* of things we do *not* want to be persisted across reloads:
|
|
|
|
* - Gallery/selected image (user may add/delete images from disk between page loads)
|
|
|
|
* - Connection/processing status
|
|
|
|
* - Availability of external libraries like ESRGAN/GFPGAN
|
|
|
|
*
|
|
|
|
* These can be blacklisted in redux-persist.
|
|
|
|
*
|
|
|
|
* The necesssary nested persistors with blacklists are configured below.
|
|
|
|
*
|
|
|
|
* TODO: Do we blacklist initialImagePath? If the image is deleted from disk we get an
|
|
|
|
* ugly 404. But if we blacklist it, then this is a valuable parameter that is lost
|
|
|
|
* on reload. Need to figure out a good way to handle this.
|
|
|
|
*/
|
2022-09-16 17:18:15 +00:00
|
|
|
|
2022-09-18 07:33:09 +00:00
|
|
|
const rootPersistConfig = {
|
2022-09-16 17:18:15 +00:00
|
|
|
key: 'root',
|
|
|
|
storage,
|
2022-09-18 07:33:09 +00:00
|
|
|
blacklist: ['gallery', 'system'],
|
2022-09-16 17:18:15 +00:00
|
|
|
};
|
|
|
|
|
2022-09-18 07:33:09 +00:00
|
|
|
const systemPersistConfig = {
|
|
|
|
key: 'system',
|
|
|
|
storage,
|
|
|
|
blacklist: [
|
|
|
|
'isConnected',
|
|
|
|
'isProcessing',
|
|
|
|
'currentStep',
|
|
|
|
'socketId',
|
|
|
|
'isESRGANAvailable',
|
|
|
|
'isGFPGANAvailable',
|
|
|
|
'currentStep',
|
|
|
|
'totalSteps',
|
|
|
|
'currentIteration',
|
|
|
|
'totalIterations',
|
|
|
|
'currentStatus',
|
|
|
|
],
|
|
|
|
};
|
2022-09-16 17:18:15 +00:00
|
|
|
|
2022-09-18 07:33:09 +00:00
|
|
|
const reducers = combineReducers({
|
2022-09-20 13:17:31 +00:00
|
|
|
options: optionsReducer,
|
2022-09-18 07:33:09 +00:00
|
|
|
gallery: galleryReducer,
|
|
|
|
system: persistReducer(systemPersistConfig, systemReducer),
|
|
|
|
});
|
2022-09-16 17:18:15 +00:00
|
|
|
|
2022-09-18 07:33:09 +00:00
|
|
|
const persistedReducer = persistReducer(rootPersistConfig, reducers);
|
2022-09-16 17:18:15 +00:00
|
|
|
|
|
|
|
// Continue with store setup
|
|
|
|
export const store = configureStore({
|
|
|
|
reducer: persistedReducer,
|
|
|
|
middleware: (getDefaultMiddleware) =>
|
|
|
|
getDefaultMiddleware({
|
2022-09-18 07:33:09 +00:00
|
|
|
// redux-persist sometimes needs to temporarily put a function in redux state, need to disable this check
|
2022-09-16 17:18:15 +00:00
|
|
|
serializableCheck: false,
|
|
|
|
}).concat(socketioMiddleware()),
|
|
|
|
});
|
|
|
|
|
|
|
|
export type RootState = ReturnType<typeof store.getState>;
|
|
|
|
export type AppDispatch = typeof store.dispatch;
|
2022-09-18 07:33:09 +00:00
|
|
|
|
|
|
|
// Use throughout your app instead of plain `useDispatch` and `useSelector`
|
|
|
|
export const useAppDispatch: () => AppDispatch = useDispatch;
|
|
|
|
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|