Files
ColdBreeze-chat-web/src/app/store.ts
T

101 lines
3.5 KiB
TypeScript

import { combineReducers, configureStore } from '@reduxjs/toolkit';
import { setupListeners } from '@reduxjs/toolkit/query';
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import listenerMiddleware from './listener.middleware';
import authDataReducer from './slices/auth.data';
import footprintReducer from './slices/footprint';
import serverReducer from './slices/server';
import uiReducer from './slices/ui';
import channelsReducer from './slices/channels';
import contactsReducer from './slices/contacts';
import reactionMsgReducer from './slices/message.reaction';
import channelMsgReducer from './slices/message.channel';
import userMsgReducer from './slices/message.user';
import favoritesReducer from './slices/favorites';
import fileMsgReducer from './slices/message.file';
import messageReducer from './slices/message';
import { authApi } from './services/auth';
import { contactApi } from './services/contact';
import { channelApi } from './services/channel';
import { messageApi } from './services/message';
import { serverApi } from './services/server';
const reducer = combineReducers({
authData: authDataReducer,
ui: uiReducer,
footprint: footprintReducer,
server: serverReducer,
favorites: favoritesReducer,
contacts: contactsReducer,
channels: channelsReducer,
reactionMessage: reactionMsgReducer,
userMessage: userMsgReducer,
channelMessage: channelMsgReducer,
fileMessage: fileMsgReducer,
message: messageReducer,
[authApi.reducerPath]: authApi.reducer,
[messageApi.reducerPath]: messageApi.reducer,
[contactApi.reducerPath]: contactApi.reducer,
[channelApi.reducerPath]: channelApi.reducer,
[serverApi.reducerPath]: serverApi.reducer
});
const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware()
.concat(
authApi.middleware,
contactApi.middleware,
channelApi.middleware,
serverApi.middleware,
messageApi.middleware
)
.prepend(listenerMiddleware.middleware)
});
let initialized = false;
setupListeners(store.dispatch, (dispatch, { onOnline, onOffline, onFocus, onFocusLost }) => {
const handleFocus = () => dispatch(onFocus());
const handleFocusLost = () => dispatch(onFocusLost());
const handleOnline = () => dispatch(onOnline());
const handleOffline = () => dispatch(onOffline());
const handleVisibilityChange = () => {
if (window.document.visibilityState === "visible") {
handleFocus();
} else {
handleFocusLost();
}
};
if (!initialized) {
if (typeof window !== "undefined" && window.addEventListener) {
// Handle focus events
window.addEventListener("visibilitychange", handleVisibilityChange, false);
window.addEventListener("focus", handleFocus, false);
// Handle connection events
window.addEventListener("online", handleOnline, false);
window.addEventListener("offline", handleOffline, false);
initialized = true;
}
}
return () => {
window.removeEventListener("focus", handleFocus);
window.removeEventListener("visibilitychange", handleVisibilityChange);
window.removeEventListener("online", handleOnline);
window.removeEventListener("offline", handleOffline);
initialized = false;
};
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
export default store;