Newer
Older
import { PayloadAction, createSlice } from '@reduxjs/toolkit';
import { RoutineManager } from '@utils/routine.manager';
import { RootState } from '../../stores';
import { startListening } from '../../stores/middleware/listener.middleware';
import { setToken } from './user.reducer';
payload: any
/**
* Only one subscription per category is allowed. New subscription will unsubscribe and overwrite the old one
*/
category: CATEGORIES,
}
interface ThunkEntity extends ThunkEntityDTO {
id?: number,
thunks: {[key in keyof typeof CATEGORIES]: ThunkEntity | null}
}
export enum CATEGORIES {
TABLE,
TAB
}
thunks: {
TABLE: null,
TAB: null
}
}
const RoutineSlice = createSlice({
name: 'routine',
addRoutine: (state, {payload}: PayloadAction<ThunkEntityDTO>) => {
const newThunk: ThunkEntity = {...payload, locked: true};
state.thunks[CATEGORIES[payload.category]] = newThunk;
},
setThunkId: (state, {payload}: PayloadAction<{id: number, category: CATEGORIES}>) => {
let thunk = state.thunks[CATEGORIES[payload.category]];
if (!thunk) {
// TODO
throw new Error('Thunk not found');
}
state.thunks[CATEGORIES[payload.category]] = {...thunk, id: payload.id, locked: false};
},
state.thunks = initialState.thunks;
},
},
})
export const { addRoutine } = RoutineSlice.actions
predicate: (action) => setToken.match(action) && action.payload === null,
listenerApi.dispatch(RoutineSlice.actions.removeAll());
// on rehydrate add all persistet routines
startListening({
predicate: ({type}) => type === REHYDRATE,
effect: async (_, listenerApi) => {
const {routine} = listenerApi.getState() as RootState;
for (const [_,thunk] of Object.entries<ThunkEntity>(routine.thunks)) {
if (!thunk) {
return;
}
const dto: ThunkEntityDTO = thunk;
listenerApi.dispatch(addRoutine(dto));
}
},
})
predicate: (action) => addRoutine.match(action),
const {routine} = listenerApi.getOriginalState() as RootState;
const lastThunk = routine.thunks[CATEGORIES[action.payload.category]];
if (lastThunk) {
RoutineManager.unsubscribe(lastThunk.id);
}
predicate: (action) => addRoutine.match(action),
const {thunk} = action.payload as ThunkEntity;
const subscription = await listenerApi.dispatch(thunk(action.payload.payload));
const thunkId = await RoutineManager.add(subscription.payload);
listenerApi.dispatch(RoutineSlice.actions.setThunkId({id: thunkId, category: action.payload.category}));