feat: updates
This commit is contained in:
@@ -14,5 +14,7 @@ export const KEY_TOKEN = "RUSTCHAT_TOKEN";
|
|||||||
export const KEY_EXPIRE = "RUSTCHAT_TOKEN_EXPIRE";
|
export const KEY_EXPIRE = "RUSTCHAT_TOKEN_EXPIRE";
|
||||||
export const KEY_REFRESH_TOKEN = "RUSTCHAT_REFRESH_TOKEN";
|
export const KEY_REFRESH_TOKEN = "RUSTCHAT_REFRESH_TOKEN";
|
||||||
export const KEY_UID = "RUSTCHAT_CURR_UID";
|
export const KEY_UID = "RUSTCHAT_CURR_UID";
|
||||||
|
export const KEY_USERS_VERSION = "RUSTCHAT_USERS_VERSION";
|
||||||
|
export const KEY_AFTER_MID = "RUSTCHAT_AFTER_MID";
|
||||||
|
|
||||||
export default BASE_URL;
|
export default BASE_URL;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createSlice } from "@reduxjs/toolkit";
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
// import { KEY_REFRESH_TOKEN, KEY_TOKEN, KEY_UID } from "../config";
|
import { KEY_AFTER_MID, KEY_USERS_VERSION, KEY_UID } from "../config";
|
||||||
const initialState = {
|
const initialState = {
|
||||||
usersVersion: null,
|
usersVersion: null,
|
||||||
afterMid: null,
|
afterMid: null,
|
||||||
@@ -18,10 +18,14 @@ const visitMarkSlice = createSlice({
|
|||||||
setUsersVersion(state, action) {
|
setUsersVersion(state, action) {
|
||||||
const { version } = action.payload;
|
const { version } = action.payload;
|
||||||
state.usersVersion = version;
|
state.usersVersion = version;
|
||||||
|
let currUid = localStorage.getItem(KEY_UID);
|
||||||
|
localStorage.setItem(`${KEY_USERS_VERSION}_${currUid}`, version);
|
||||||
},
|
},
|
||||||
setAfterMid(state, action) {
|
setAfterMid(state, action) {
|
||||||
const { mid } = action.payload;
|
const { mid } = action.payload;
|
||||||
state.afterMid = mid;
|
state.afterMid = mid;
|
||||||
|
let currUid = localStorage.getItem(KEY_UID);
|
||||||
|
localStorage.setItem(`${KEY_AFTER_MID}_${currUid}`, mid);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@ listenerMiddleware.startListening({
|
|||||||
effect: async (action, listenerApi) => {
|
effect: async (action, listenerApi) => {
|
||||||
const { type = "" } = action;
|
const { type = "" } = action;
|
||||||
const key = getCacheKey(type);
|
const key = getCacheKey(type);
|
||||||
console.log("listener effect", key, listenerApi.getState(), window.CACHE);
|
// console.log("listener effect", key, listenerApi.getState(), window.CACHE);
|
||||||
if (key && window.CACHE) {
|
if (key && window.CACHE) {
|
||||||
await window.CACHE.setItem(key, listenerApi.getState()[key]);
|
await window.CACHE.setItem(key, listenerApi.getState()[key]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
import { configureStore, combineReducers } from "@reduxjs/toolkit";
|
|
||||||
import { setupListeners } from "@reduxjs/toolkit/query";
|
|
||||||
import storage from "redux-persist/lib/storage";
|
|
||||||
import {
|
|
||||||
persistReducer,
|
|
||||||
FLUSH,
|
|
||||||
REHYDRATE,
|
|
||||||
PAUSE,
|
|
||||||
PERSIST,
|
|
||||||
PURGE,
|
|
||||||
REGISTER,
|
|
||||||
} from "redux-persist";
|
|
||||||
import authDataReducer from "./slices/auth.data";
|
|
||||||
import uiReducer from "./slices/ui";
|
|
||||||
import channelsReducer from "./slices/channels";
|
|
||||||
import contactsReducer from "./slices/contacts";
|
|
||||||
import pendingMsgReducer from "./slices/message.pending";
|
|
||||||
import channelMsgReducer from "./slices/message.channel";
|
|
||||||
import userMsgReducer from "./slices/message.user";
|
|
||||||
import { authApi } from "./services/auth";
|
|
||||||
import { contactApi } from "./services/contact";
|
|
||||||
import { channelApi } from "./services/channel";
|
|
||||||
import { serverApi } from "./services/server";
|
|
||||||
const persistConfig = {
|
|
||||||
key: "root",
|
|
||||||
version: 1,
|
|
||||||
storage,
|
|
||||||
};
|
|
||||||
const persistedReducer = persistReducer(
|
|
||||||
persistConfig,
|
|
||||||
combineReducers({
|
|
||||||
ui: uiReducer,
|
|
||||||
contacts: contactsReducer,
|
|
||||||
channels: channelsReducer,
|
|
||||||
pendingMsg: pendingMsgReducer,
|
|
||||||
userMsg: userMsgReducer,
|
|
||||||
channelMsg: channelMsgReducer,
|
|
||||||
authData: authDataReducer,
|
|
||||||
[authApi.reducerPath]: authApi.reducer,
|
|
||||||
[contactApi.reducerPath]: contactApi.reducer,
|
|
||||||
[channelApi.reducerPath]: channelApi.reducer,
|
|
||||||
[serverApi.reducerPath]: serverApi.reducer,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const store = configureStore({
|
|
||||||
reducer: persistedReducer,
|
|
||||||
middleware: (getDefaultMiddleware) =>
|
|
||||||
getDefaultMiddleware({
|
|
||||||
serializableCheck: {
|
|
||||||
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
|
|
||||||
},
|
|
||||||
}).concat(
|
|
||||||
authApi.middleware,
|
|
||||||
contactApi.middleware,
|
|
||||||
channelApi.middleware,
|
|
||||||
serverApi.middleware
|
|
||||||
),
|
|
||||||
});
|
|
||||||
setupListeners(store.dispatch);
|
|
||||||
// export function swapToUserStore(userId) {
|
|
||||||
// console.log({ userId });
|
|
||||||
// const newConfig = {
|
|
||||||
// ...persistConfig,
|
|
||||||
// keyPrefix: userId,
|
|
||||||
// };
|
|
||||||
// store.replaceReducer(
|
|
||||||
// persistReducer(
|
|
||||||
// newConfig,
|
|
||||||
// combineReducers({
|
|
||||||
// ui: uiReducer,
|
|
||||||
// channels: channelsReducer,
|
|
||||||
// userMsg: userMsgReducer,
|
|
||||||
// channelMsg: channelMsgReducer,
|
|
||||||
// authData: authDataReducer,
|
|
||||||
// [authApi.reducerPath]: authApi.reducer,
|
|
||||||
// [contactApi.reducerPath]: contactApi.reducer,
|
|
||||||
// [channelApi.reducerPath]: channelApi.reducer,
|
|
||||||
// [serverApi.reducerPath]: serverApi.reducer,
|
|
||||||
// })
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
export default store;
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import styled, { keyframes } from "styled-components";
|
import styled, { keyframes } from "styled-components";
|
||||||
import { useOutsideClick } from "rooks";
|
import { useOutsideClick, useKey } from "rooks";
|
||||||
import Modal from "./Modal";
|
import Modal from "./Modal";
|
||||||
const AniFadeIn = keyframes`
|
const AniFadeIn = keyframes`
|
||||||
from{
|
from{
|
||||||
@@ -43,7 +43,14 @@ const StyledWrapper = styled.div`
|
|||||||
export default function ImagePreviewModal({ image = null, closeModal }) {
|
export default function ImagePreviewModal({ image = null, closeModal }) {
|
||||||
const wrapperRef = useRef();
|
const wrapperRef = useRef();
|
||||||
useOutsideClick(wrapperRef, closeModal);
|
useOutsideClick(wrapperRef, closeModal);
|
||||||
|
useKey(
|
||||||
|
"Escape",
|
||||||
|
() => {
|
||||||
|
console.log("close preview modal");
|
||||||
|
closeModal();
|
||||||
|
},
|
||||||
|
{ eventTypes: ["keyup"] }
|
||||||
|
);
|
||||||
if (!image) return null;
|
if (!image) return null;
|
||||||
return (
|
return (
|
||||||
<Modal>
|
<Modal>
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import useNotification from "./useNotification";
|
import useNotification from "./useNotification";
|
||||||
import BASE_URL from "../../../app/config";
|
import BASE_URL, {
|
||||||
|
KEY_AFTER_MID,
|
||||||
|
KEY_USERS_VERSION,
|
||||||
|
} from "../../../app/config";
|
||||||
import { useRenewMutation } from "../../../app/services/auth";
|
import { useRenewMutation } from "../../../app/services/auth";
|
||||||
import {
|
import {
|
||||||
setChannels,
|
setChannels,
|
||||||
@@ -21,8 +24,6 @@ import {
|
|||||||
} from "../../../app/slices/auth.data";
|
} from "../../../app/slices/auth.data";
|
||||||
import { setUsersVersion, setAfterMid } from "../../../app/slices/visit.mark";
|
import { setUsersVersion, setAfterMid } from "../../../app/slices/visit.mark";
|
||||||
|
|
||||||
// import { addChannelMsg } from "../../../app/slices/message.channel";
|
|
||||||
// import { addUserMsg } from "../../../app/slices/message.user";
|
|
||||||
import { setReady } from "../../../app/slices/ui";
|
import { setReady } from "../../../app/slices/ui";
|
||||||
import useMessageHandler from "./useMessageHandler";
|
import useMessageHandler from "./useMessageHandler";
|
||||||
const getQueryString = (params = {}) => {
|
const getQueryString = (params = {}) => {
|
||||||
@@ -34,7 +35,7 @@ const getQueryString = (params = {}) => {
|
|||||||
});
|
});
|
||||||
return sp.toString();
|
return sp.toString();
|
||||||
};
|
};
|
||||||
const NotificationHub = ({ usersVersion = 0, afterMid = 0 }) => {
|
const NotificationHub = () => {
|
||||||
const { enableNotification } = useNotification();
|
const { enableNotification } = useNotification();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -53,11 +54,15 @@ const NotificationHub = ({ usersVersion = 0, afterMid = 0 }) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let sse = null;
|
let sse = null;
|
||||||
if (token) {
|
if (token) {
|
||||||
|
const users_version =
|
||||||
|
localStorage.getItem(`${KEY_USERS_VERSION}_${currUser.uid}`) ?? 0;
|
||||||
|
const after_mid =
|
||||||
|
localStorage.getItem(`${KEY_AFTER_MID}_${currUser.uid}`) ?? 0;
|
||||||
sse = new EventSource(
|
sse = new EventSource(
|
||||||
`${BASE_URL}/user/events?${getQueryString({
|
`${BASE_URL}/user/events?${getQueryString({
|
||||||
"api-key": token,
|
"api-key": token,
|
||||||
users_version: usersVersion,
|
users_version,
|
||||||
after_mid: afterMid,
|
after_mid,
|
||||||
})}`
|
})}`
|
||||||
);
|
);
|
||||||
sse.onopen = () => {
|
sse.onopen = () => {
|
||||||
@@ -89,7 +94,7 @@ const NotificationHub = ({ usersVersion = 0, afterMid = 0 }) => {
|
|||||||
sse.close();
|
sse.close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [token, refreshToken, usersVersion, afterMid]);
|
}, [token, refreshToken]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (refreshTokenSuccess) {
|
if (refreshTokenSuccess) {
|
||||||
const { token, refresh_token } = data;
|
const { token, refresh_token } = data;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export default function Loading() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const inter = setTimeout(() => {
|
const inter = setTimeout(() => {
|
||||||
setReloadVisible(true);
|
setReloadVisible(true);
|
||||||
}, 1500);
|
}, 10000);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(inter);
|
clearTimeout(inter);
|
||||||
|
|||||||
@@ -20,10 +20,8 @@ export default function HomePage() {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const {
|
const {
|
||||||
ui: { ready, menuExpand, setting, channelSetting },
|
ui: { ready, menuExpand, setting, channelSetting },
|
||||||
visitMark: { usersVersion, afterMid },
|
|
||||||
} = useSelector((store) => {
|
} = useSelector((store) => {
|
||||||
return {
|
return {
|
||||||
visitMark: store.visitMark,
|
|
||||||
ui: store.ui,
|
ui: store.ui,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -37,7 +35,7 @@ export default function HomePage() {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NotificationHub usersVersion={usersVersion} afterMid={afterMid} />
|
<NotificationHub />
|
||||||
{ready ? (
|
{ready ? (
|
||||||
<StyledWrapper>
|
<StyledWrapper>
|
||||||
<div className={`col left ${menuExpand ? "expand" : ""}`}>
|
<div className={`col left ${menuExpand ? "expand" : ""}`}>
|
||||||
|
|||||||
Reference in New Issue
Block a user