From a23800b042eaa16f110e1ce3684aa0574de0c9fb Mon Sep 17 00:00:00 2001 From: zerosoul Date: Tue, 22 Mar 2022 16:10:49 +0800 Subject: [PATCH] feat: lots updates --- src/app/cache/useRehydrate.js | 8 +- src/app/config.js | 2 +- src/app/services/auth.js | 10 + src/app/services/channel.js | 10 +- src/app/services/contact.js | 3 +- src/app/services/handlers.js | 12 +- src/app/slices/auth.data.js | 1 + src/app/slices/message.channel.js | 12 +- src/app/slices/ui.js | 2 +- .../component/ChannelSetting/Overview.js | 9 +- src/common/component/ChannelSetting/navs.js | 46 ++--- src/common/component/Contact.js | 2 - src/common/component/FAQ.js | 10 +- src/common/component/ImagePreviewModal.js | 2 +- src/common/component/InviteLink.js | 1 + src/common/component/ManageMembers.js | 113 +++++++----- src/common/component/Message/Commands.js | 91 +++++---- src/common/component/Message/EmojiPicker.js | 20 +- src/common/component/Message/Reaction.js | 29 ++- src/common/component/Message/Reply.js | 3 +- src/common/component/Message/index.js | 18 +- src/common/component/Message/styled.js | 3 - src/common/component/SaveTip.js | 2 +- src/common/component/Search.js | 75 ++++---- .../component/Send/UploadModal/index.js | 2 +- src/common/component/Send/index.js | 8 +- src/common/component/Setting/navs.js | 172 +++++++++--------- .../component/StyledSettingContainer.js | 2 +- src/common/component/styled/Input.js | 1 + src/common/hook/useLogout.js | 3 - src/common/hook/useStreaming/chat.handler.js | 24 ++- src/common/hook/useStreaming/index.js | 46 +++-- src/common/utils.js | 15 +- src/routes/chat/ChannelList/NavItem.js | 13 +- src/routes/chat/ChannelList/styled.js | 69 +++++++ src/routes/chat/styled.js | 57 ------ src/routes/chat/utils.js | 2 +- src/routes/home/ServerDropList.js | 2 +- src/routes/home/index.js | 4 +- src/routes/home/usePreload.js | 15 +- 40 files changed, 504 insertions(+), 415 deletions(-) create mode 100644 src/routes/chat/ChannelList/styled.js diff --git a/src/app/cache/useRehydrate.js b/src/app/cache/useRehydrate.js index a6fa3aa1..0118bd55 100644 --- a/src/app/cache/useRehydrate.js +++ b/src/app/cache/useRehydrate.js @@ -30,10 +30,14 @@ const useRehydrate = () => { // console.log("iterated", key); switch (_key) { case "channels": - rehydrateData.channels.push(data); + if (data) { + rehydrateData.channels.push(data); + } break; case "contacts": - rehydrateData.contacts.push(data); + if (data) { + rehydrateData.contacts.push(data); + } break; case "footprint": rehydrateData.footprint[key] = data; diff --git a/src/app/config.js b/src/app/config.js index 4add3edc..7a352b3e 100644 --- a/src/app/config.js +++ b/src/app/config.js @@ -1,6 +1,6 @@ // const BASE_URL = `${location.origin}/api`; const BASE_URL = `https://dev.rustchat.com/api`; -export const CACHE_VERSION = `0.1`; +export const CACHE_VERSION = `0.2.1`; // const BASE_URL = `https://rustchat.net/api`; export const ContentTypes = { text: "text/plain", diff --git a/src/app/services/auth.js b/src/app/services/auth.js index 6ca6196a..dc95d67f 100644 --- a/src/app/services/auth.js +++ b/src/app/services/auth.js @@ -1,6 +1,7 @@ import { createApi } from "@reduxjs/toolkit/query/react"; import { nanoid } from "@reduxjs/toolkit"; import baseQuery from "./base.query"; +import { updateToken, resetAuthData } from "../slices/auth.data"; import BASE_URL, { KEY_DEVICE_KEY } from "../config"; const getDeviceId = () => { let d = localStorage.getItem(KEY_DEVICE_KEY); @@ -43,6 +44,15 @@ export const authApi = createApi({ refresh_token: refreshToken, }, }), + async onQueryStarted(params, { dispatch, queryFulfilled }) { + try { + const { data } = await queryFulfilled; + dispatch(updateToken(data)); + } catch { + dispatch(resetAuthData()); + console.log("remove channel error"); + } + }, }), // 获取openid getOpenid: builder.mutation({ diff --git a/src/app/services/channel.js b/src/app/services/channel.js index 7908a89c..b248cd96 100644 --- a/src/app/services/channel.js +++ b/src/app/services/channel.js @@ -78,7 +78,7 @@ export const channelApi = createApi({ query: ({ id, content, type = "text", properties = "" }) => ({ headers: { "content-type": ContentTypes[type], - "X-Properties": properties, + "X-Properties": properties ? btoa(JSON.stringify(properties)) : "", }, url: `group/${id}/send`, method: "POST", @@ -95,6 +95,13 @@ export const channelApi = createApi({ body: members, }), }), + removeMembers: builder.mutation({ + query: ({ id, members }) => ({ + url: `group/${id}/members/remove`, + method: "POST", + body: members, + }), + }), }), }); @@ -106,4 +113,5 @@ export const { useCreateChannelMutation, useSendChannelMsgMutation, useAddMembersMutation, + useRemoveMembersMutation, } = channelApi; diff --git a/src/app/services/contact.js b/src/app/services/contact.js index 9cb67d9b..85f71b4d 100644 --- a/src/app/services/contact.js +++ b/src/app/services/contact.js @@ -32,7 +32,6 @@ export const contactApi = createApi({ // 用户已注销或被禁用 console.log("no matched user, redirect to login"); dispatch(resetAuthData()); - // navigate("/login"); } else { const markedContacts = contacts.map((u) => { return u.uid == matchedUser.uid ? { ...u, online: true } : u; @@ -76,7 +75,7 @@ export const contactApi = createApi({ query: ({ id, content, type = "text", properties = "" }) => ({ headers: { "content-type": ContentTypes[type], - "X-Properties": properties, + "X-Properties": properties ? btoa(JSON.stringify(properties)) : "", }, url: `user/${id}/send`, method: "POST", diff --git a/src/app/services/handlers.js b/src/app/services/handlers.js index 0754e103..3dc9add3 100644 --- a/src/app/services/handlers.js +++ b/src/app/services/handlers.js @@ -5,16 +5,24 @@ import { addChannelMsg, removeChannelMsg } from "../slices/message.channel"; import { addUserMsg, removeUserMsg } from "../slices/message.user"; import { addMessage, removeMessage } from "../slices/message"; export const onMessageSendStarted = async ( - { id, content, type = "text", from_uid, reply_mid = null }, + { + id, + content, + type = "text", + from_uid, + reply_mid = null, + properties = { local_id: new Date().getTime() }, + }, { dispatch, queryFulfilled }, from = "channel" ) => { // id: who send to ,from_uid: who sent - const ts = new Date().getTime(); + const ts = properties.local_id || new Date().getTime(); const tmpMsg = { content: type == "image" ? URL.createObjectURL(content) : content, content_type: ContentTypes[type], created_at: ts, + properties, from_uid, reply_mid, // 已读 diff --git a/src/app/slices/auth.data.js b/src/app/slices/auth.data.js index a5eef5ef..4260deaa 100644 --- a/src/app/slices/auth.data.js +++ b/src/app/slices/auth.data.js @@ -48,6 +48,7 @@ const authDataSlice = createSlice({ setUid(state, action) { const uid = action.payload; state.uid = uid; + console.log("set uid orginal"); }, updateToken(state, action) { const { token, refresh_token, expired_in } = action.payload; diff --git a/src/app/slices/message.channel.js b/src/app/slices/message.channel.js index 334b7b33..dd55e80b 100644 --- a/src/app/slices/message.channel.js +++ b/src/app/slices/message.channel.js @@ -12,9 +12,12 @@ const channelMsgSlice = createSlice({ return action.payload; }, addChannelMsg(state, action) { - const { id, mid } = action.payload; + const { id, mid, local_id = null } = action.payload; if (state[id]) { - if (state[id].findIndex((id) => id == mid) > -1) return; + const midExsited = state[id].findIndex((id) => id == mid) > -1; + const localMsgExsited = + state[id].findIndex((id) => id == local_id) > -1; + if (midExsited || localMsgExsited) return; state[id].push(+mid); } else { state[id] = [+mid]; @@ -24,7 +27,10 @@ const channelMsgSlice = createSlice({ const { id, mid } = action.payload; if (state[id]) { const idx = state[id].findIndex((i) => i == mid); - state[id].splice(idx, 1); + if (idx > -1) { + // 存在 则再删除 + state[id].splice(idx, 1); + } } }, removeChannelSession(state, action) { diff --git a/src/app/slices/ui.js b/src/app/slices/ui.js index 09ab8a9a..25d0ae1a 100644 --- a/src/app/slices/ui.js +++ b/src/app/slices/ui.js @@ -3,7 +3,7 @@ import { createSlice } from "@reduxjs/toolkit"; const initialState = { online: true, ready: false, - menuExpand: true, + menuExpand: false, setting: false, channelSetting: null, }; diff --git a/src/common/component/ChannelSetting/Overview.js b/src/common/component/ChannelSetting/Overview.js index 55df168b..c22b1d1e 100644 --- a/src/common/component/ChannelSetting/Overview.js +++ b/src/common/component/ChannelSetting/Overview.js @@ -10,6 +10,7 @@ import Label from "../styled/Label"; import Textarea from "../styled/Textarea"; import SaveTip from "../SaveTip"; import channelIcon from "../../../assets/icons/channel.svg?url"; +import { useSelector } from "react-redux"; const StyledWrapper = styled.div` position: relative; width: 512px; @@ -30,7 +31,7 @@ const StyledWrapper = styled.div` gap: 8px; .name { padding-left: 36px; - background: url(${channelIcon}); + background-image: url(${channelIcon}); background-size: 20px; background-position-x: 8px; background-position-y: 8px; @@ -40,6 +41,9 @@ const StyledWrapper = styled.div` } `; export default function Overview({ id = 0 }) { + const loginUser = useSelector( + (store) => store.contacts.byId[store.authData.uid] + ); const { data, refetch } = useGetChannelQuery(id); const [changed, setChanged] = useState(false); const [values, setValues] = useState(null); @@ -85,12 +89,14 @@ export default function Overview({ id = 0 }) { if (!values || !id) return null; const { name, description } = values; + const isAdmin = loginUser.is_admin; return (