diff --git a/react-ui/src/stores/reducer/subscription.reducer.ts b/react-ui/src/stores/reducer/subscription.reducer.ts index a21024eab0d1f867d33edc479a15f72dfd1fdf85..344b42d2502bb6bcfc984f242f33c60e7763c5dd 100644 --- a/react-ui/src/stores/reducer/subscription.reducer.ts +++ b/react-ui/src/stores/reducer/subscription.reducer.ts @@ -1,8 +1,9 @@ -import { PayloadAction, createSlice, current } from '@reduxjs/toolkit'; +import { PayloadAction, createSlice } from '@reduxjs/toolkit'; import { SubscriptionThunks, THUNK_TYPE } from '@subscription/index'; import { RootState } from '..'; -import { addSubscription, unsubscribe, unsubscribeAll } from '../../utils/api/subscription.handler'; +import { SubscriptionHandler } from '../../utils/api/subscription.handler'; import { startListening } from '../middleware/listener.middleware'; +import { setToken } from './user.reducer'; @@ -43,12 +44,7 @@ const SubscriptionSlice = createSlice({ initialState, reducers: { triggerSubscription: (state, {payload}: PayloadAction<ThunkEntityDTO>) => { - // overwrite old subscription if it exists - const currentState = current(state) - const currentThunk = currentState.thunks[CATEGORIES[payload.category]]; - const newThunk: ThunkEntity = {...payload, locked: true}; - state.thunks[CATEGORIES[payload.category]] = newThunk; }, @@ -63,14 +59,23 @@ const SubscriptionSlice = createSlice({ state.thunks[CATEGORIES[payload.category]] = {...thunk, id: payload.id, locked: false}; }, - stopAllSubscriptions: (state) => { - unsubscribeAll() + removeAll: (state) => { + SubscriptionHandler.unsubscribeAll() state.thunks = initialState.thunks; }, }, }) -export const { triggerSubscription, stopAllSubscriptions } = SubscriptionSlice.actions +export const { triggerSubscription } = SubscriptionSlice.actions + +// on logout remove all subscriptions +startListening({ + predicate: (action) => setToken.match(action) && action.payload.token === null, + effect: async (_, listenerApi) => { + listenerApi.dispatch(SubscriptionSlice.actions.removeAll()); + }, +}) + // unsubscribe old subscription startListening({ @@ -78,7 +83,7 @@ startListening({ effect: async (action, listenerApi) => { const {subscription} = listenerApi.getOriginalState() as RootState; const lastThunk = subscription.thunks[CATEGORIES[action.payload.category]]; - unsubscribe(lastThunk.id); + SubscriptionHandler.unsubscribe(lastThunk.id); }, }) @@ -95,7 +100,7 @@ startListening({ } const subscription = await listenerApi.dispatch(thunkFn(action.payload.payload)); - const thunkId = await addSubscription(subscription.payload); + const thunkId = await SubscriptionHandler.add(subscription.payload); listenerApi.dispatch(SubscriptionSlice.actions.setThunkId({id: thunkId, category: action.payload.category})); }, diff --git a/react-ui/src/utils/api/subscription.handler.ts b/react-ui/src/utils/api/subscription.handler.ts index e288a4a6f468fc1f919edcd2e65c46966f14f4f3..e065879f03d26cd23c4b64ab4c4e2afe749f89b7 100644 --- a/react-ui/src/utils/api/subscription.handler.ts +++ b/react-ui/src/utils/api/subscription.handler.ts @@ -1,65 +1,68 @@ import { QueryActionCreatorResult } from '@reduxjs/toolkit/query'; -type SubscriptionType = QueryActionCreatorResult<any>; +type Subscription = QueryActionCreatorResult<any>; -interface SubscriptionEntity { - subscription: SubscriptionType, +interface Entity { + subscription: Subscription, id: number } -interface SubscriptionReducerState { - subscriptions: SubscriptionEntity[] -} - -const initialState: SubscriptionReducerState = { - subscriptions: [] +const initialState = { + subscriptions: [] as Entity[] } -let state = initialState; +export const SubscriptionHandler = (() => { + let state = initialState; + const add = (subscription: Subscription): number => { + const id = state.subscriptions.length; + const subscriptionEntity: Entity = { + subscription, + id + } -export const addSubscription = (subscription: SubscriptionType): number => { - const id = state.subscriptions.length; + state.subscriptions = [...state.subscriptions, subscriptionEntity]; - const subscriptionEntity: SubscriptionEntity = { - subscription, - id + return id; } - state.subscriptions = [...state.subscriptions, subscriptionEntity]; - return id; -} + const unsubscribeAll = () => { + state.subscriptions.forEach(({ subscription }) => { + unsubscribeAction(subscription) + }); + state.subscriptions = initialState.subscriptions; + } -export const unsubscribeAll = () => { - state.subscriptions.forEach(({ subscription }) => { - unsubscribeAction(subscription) - }); + /** + * @param id + * @returns returns true if the subscription was stopped, false if it was not found + */ + const unsubscribe = (id: number): boolean => { + const subscription = state.subscriptions.find(({ id: subscriptionId }) => subscriptionId === id); - state.subscriptions = initialState.subscriptions; -} + if (subscription) { + unsubscribeAction(subscription.subscription); + } -/** - * @param id - * @returns returns true if the subscription was stopped, false if it was not found - */ -export const unsubscribe = (id: number): boolean => { - const subscription = state.subscriptions.find(({ id: subscriptionId }) => subscriptionId === id); + return !!subscription; + } - if (subscription) { - unsubscribeAction(subscription.subscription); + /** + * Actual unsubscribe action + * + * @param subscription + */ + const unsubscribeAction = (subscription: Subscription) => { + subscription.unsubscribe(); } - return !!subscription; -} -/** - * Actual unsubscribe action - * - * @param subscription - */ -const unsubscribeAction = (subscription: SubscriptionType) => { - subscription.unsubscribe(); -} \ No newline at end of file + return { + add, + unsubscribe, + unsubscribeAll + } +})(); \ No newline at end of file diff --git a/react-ui/src/utils/provider/auth.provider.tsx b/react-ui/src/utils/provider/auth.provider.tsx index 44901c66f80d47a43c339120e897fc613595ac78..d1f472cc7be17408b300d3e6af72e046cd581cea 100644 --- a/react-ui/src/utils/provider/auth.provider.tsx +++ b/react-ui/src/utils/provider/auth.provider.tsx @@ -1,5 +1,4 @@ import { AuthServiceLoginApiArg, AuthServiceLoginApiResponse, useAuthServiceLoginMutation } from "@api/api"; -import { unsubscribeAll } from "@api/subscription.handler"; import { getCookieValue } from "@helper/coookie"; import { useAppDispatch, useAppSelector } from "@hooks"; import { setToken } from "@reducer/user.reducer"; @@ -100,7 +99,6 @@ export const AuthProvider = ({ children }) => { } const logout = () => { - unsubscribeAll(); dispatch(setToken(null)); // TODO: purge other information }