Newer
Older
import { debugMessage } from '@helper/debug'
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'
// ---------------- thunk types ----------------
* Only one subscription per category is allowed.
* New subscription will unsubscribe and overwrite the old one
/**
* This Wrapper holds the actual thunk information
* as well as additional information
*/
interface ThunkWrapper extends ThunkEntityDTO {
id?: number
locked: boolean
// ---------------- reducer types ----------------
export interface ReducerState {
thunks: { [key in keyof typeof CATEGORIES]: ThunkWrapper | null }
}
const RoutineSlice = createSlice({
name: 'routine',
addRoutine: (state: any, { payload }: PayloadAction<ThunkEntityDTO>) => {
if (state.thunks[CATEGORIES[payload.category]]?.locked) {
}
const newThunk: ThunkWrapper = { ...payload, locked: true }
state.thunks[CATEGORIES[payload.category]] = newThunk
setThunkId: (state, { payload }: PayloadAction<{ id: number; category: CATEGORIES }>) => {
const thunk = state.thunks[CATEGORIES[payload.category] as any]
debugMessage("Desired thunk of category " + payload.category + " is not available")
return
state.thunks[CATEGORIES[payload.category] as any] = { ...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())
// TODO -> thunk does not have the thunk function object due to its coming from the store that ignores the value.
// at this point we have to figure out how to get the thunk function out of the "string" name
// 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) {
// continue
// }
// const dto: ThunkEntityDTO = thunk
// listenerApi.dispatch(addRoutine(dto))
// }
// },
// })
/**
* Add new routine
*
* This listener handles the connection between the RoutingManager that
* stores the non persistable thunk object and the peristable thunk information.
* The persistable information are stored in this reducer
*/
predicate: (action) => addRoutine.match(action),
const { thunk } = action.payload as ThunkWrapper
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 })
)
// unsubscribe old routine
startListening({
predicate: (action) => addRoutine.match(action),
effect: async (action, listenerApi) => {
const { routine } = listenerApi.getOriginalState() as RootState
const lastThunk = routine.thunks[CATEGORIES[action.payload.category] as any]
if (!lastThunk.id) {
throw new Error()
// TODO
}
RoutineManager.unsubscribe(lastThunk.id)
}
},
})