diff --git a/src/app/services/base.query.js b/src/app/services/base.query.js
index 2633f62c..c575e563 100644
--- a/src/app/services/base.query.js
+++ b/src/app/services/base.query.js
@@ -10,6 +10,7 @@ const whiteList = [
"checkInviteTokenValid",
"getGoogleAuthConfig",
"getLoginConfig",
+ "getServerVersion",
"getServer",
"getOpenid",
"getMetamaskNonce",
diff --git a/src/app/services/channel.js b/src/app/services/channel.js
index 48073a59..bedd369e 100644
--- a/src/app/services/channel.js
+++ b/src/app/services/channel.js
@@ -1,177 +1,192 @@
-import { createApi } from '@reduxjs/toolkit/query/react';
+import { createApi } from "@reduxjs/toolkit/query/react";
// import toast from "react-hot-toast";
-import baseQuery from './base.query';
-import BASE_URL, { ContentTypes } from '../config';
-import { updateChannel } from '../slices/channels';
-import { removeMessage } from '../slices/message';
-import { removeChannelSession } from '../slices/message.channel';
-import { removeReactionMessage } from '../slices/message.reaction';
-import { onMessageSendStarted } from './handlers';
+import baseQuery from "./base.query";
+import BASE_URL, { ContentTypes } from "../config";
+import { updateChannel, removeChannel } from "../slices/channels";
+import { removeMessage } from "../slices/message";
+import { removeChannelSession } from "../slices/message.channel";
+import { removeReactionMessage } from "../slices/message.reaction";
+import { onMessageSendStarted } from "./handlers";
export const channelApi = createApi({
- reducerPath: 'channelApi',
- baseQuery,
- refetchOnFocus: true,
- endpoints: (builder) => ({
- getChannels: builder.query({
- query: () => ({ url: `group` })
+ reducerPath: "channelApi",
+ baseQuery,
+ refetchOnFocus: true,
+ endpoints: (builder) => ({
+ getChannels: builder.query({
+ query: () => ({ url: `group` }),
+ }),
+ getChannel: builder.query({
+ query: (id) => ({ url: `group/${id}` }),
+ }),
+ leaveChannel: builder.query({
+ query: (id) => ({ url: `group/${id}/leave` }),
+ async onQueryStarted(gid, { dispatch, queryFulfilled }) {
+ try {
+ await queryFulfilled;
+ dispatch(removeChannel(gid));
+ } catch {
+ console.log("channel update failed");
+ }
+ },
+ }),
+ createChannel: builder.mutation({
+ query: (data) => ({
+ url: "group",
+ method: "POST",
+ body: data,
+ }),
+ }),
+ updateChannel: builder.mutation({
+ query: ({ id, ...data }) => ({
+ url: `group/${id}`,
+ method: "PUT",
+ body: data,
+ }),
+ async onQueryStarted(
+ { id, name, description },
+ { dispatch, queryFulfilled }
+ ) {
+ // id: who send to ,from_uid: who sent
+ const patchResult = dispatch(updateChannel({ id, name, description }));
+ try {
+ await queryFulfilled;
+ } catch {
+ console.log("channel update failed");
+ patchResult.undo();
+ }
+ },
+ }),
+ getHistoryMessages: builder.query({
+ query: ({ gid, mid = 0, limit = 50 }) => ({
+ url: `/group/${gid}/history?before=${mid}&limit=${limit}`,
+ }),
+ // async onQueryStarted(id, { dispatch, getState, queryFulfilled }) {
+ // const {
+ // ui: { channelSetting },
+ // channelMessage,
+ // } = getState();
+ // try {
+ // await queryFulfilled;
+ // dispatch(removeChannel(id));
+ // if (id == channelSetting) {
+ // dispatch(toggleChannelSetting());
+ // }
+ // // 删掉该channel下的所有消息&reaction
+ // const mids = channelMessage[id];
+ // if (mids) {
+ // dispatch(removeChannelSession(id));
+ // dispatch(removeMessage(mids));
+ // dispatch(removeReactionMessage(mids));
+ // }
+ // } catch {
+ // console.log("remove channel error");
+ // }
+ // },
+ }),
+ createInviteLink: builder.query({
+ query: (gid) => ({
+ headers: {
+ "content-type": "text/plain",
+ accept: "text/plain",
+ },
+ url: `/group/${gid}/create_invite_link`,
+ responseHandler: (response) => response.text(),
+ }),
+ transformResponse: (link) => {
+ // 替换掉域名
+ const invite = new URL(link);
+ return `${location.origin}${invite.pathname}${invite.search}${invite.hash}`;
+ },
+ }),
+ removeChannel: builder.query({
+ query: (id) => ({
+ url: `group/${id}`,
+ method: "DELETE",
+ }),
+ async onQueryStarted(id, { dispatch, getState, queryFulfilled }) {
+ const { channelMessage } = getState();
+ try {
+ await queryFulfilled;
+ // 删掉该channel下的所有消息&reaction
+ const mids = channelMessage[id];
+ if (mids) {
+ dispatch(removeChannelSession(id));
+ dispatch(removeMessage(mids));
+ dispatch(removeReactionMessage(mids));
+ }
+ } catch {
+ console.log("remove channel error");
+ }
+ },
+ }),
+ sendChannelMsg: builder.mutation({
+ query: ({ id, content, type = "text", properties = "" }) => ({
+ headers: {
+ "content-type": ContentTypes[type],
+ "X-Properties": properties
+ ? btoa(unescape(encodeURIComponent(JSON.stringify(properties))))
+ : "",
+ },
+ url: `group/${id}/send`,
+ method: "POST",
+ body: type == "file" ? JSON.stringify(content) : content,
+ }),
+ async onQueryStarted(param1, param2) {
+ await onMessageSendStarted.call(this, param1, param2, "channel");
+ },
+ }),
+ addMembers: builder.mutation({
+ query: ({ id, members }) => ({
+ url: `group/${id}/members/add`,
+ method: "POST",
+ body: members,
+ }),
+ }),
+ removeMembers: builder.mutation({
+ query: ({ id, members }) => ({
+ url: `group/${id}/members/remove`,
+ method: "POST",
+ body: members,
+ }),
+ }),
+ updateIcon: builder.mutation({
+ query: ({ gid, image }) => ({
+ headers: {
+ "content-type": "image/png",
+ },
+ url: `/group/${gid}/avatar`,
+ method: "POST",
+ body: image,
+ }),
+ async onQueryStarted({ gid }, { dispatch, queryFulfilled }) {
+ try {
+ await queryFulfilled;
+ dispatch(
+ updateChannel({
+ id: gid,
+ icon: `${BASE_URL}/resource/group_avatar?gid=${gid}&t=${new Date().getTime()}`,
+ })
+ );
+ } catch (error) {
+ console.log("err", error);
+ }
+ },
+ }),
}),
- getChannel: builder.query({
- query: (id) => ({ url: `group/${id}` })
- }),
- createChannel: builder.mutation({
- query: (data) => ({
- url: 'group',
- method: 'POST',
- body: data
- })
- }),
- updateChannel: builder.mutation({
- query: ({ id, ...data }) => ({
- url: `group/${id}`,
- method: 'PUT',
- body: data
- }),
- async onQueryStarted({ id, name, description }, { dispatch, queryFulfilled }) {
- // id: who send to ,from_uid: who sent
- const patchResult = dispatch(updateChannel({ id, name, description }));
- try {
- await queryFulfilled;
- } catch {
- console.log('channel update failed');
- patchResult.undo();
- }
- }
- }),
- getHistoryMessages: builder.query({
- query: ({ gid, mid = 0, limit = 50 }) => ({
- url: `/group/${gid}/history?before=${mid}&limit=${limit}`
- })
- // async onQueryStarted(id, { dispatch, getState, queryFulfilled }) {
- // const {
- // ui: { channelSetting },
- // channelMessage,
- // } = getState();
- // try {
- // await queryFulfilled;
- // dispatch(removeChannel(id));
- // if (id == channelSetting) {
- // dispatch(toggleChannelSetting());
- // }
- // // 删掉该channel下的所有消息&reaction
- // const mids = channelMessage[id];
- // if (mids) {
- // dispatch(removeChannelSession(id));
- // dispatch(removeMessage(mids));
- // dispatch(removeReactionMessage(mids));
- // }
- // } catch {
- // console.log("remove channel error");
- // }
- // },
- }),
- createInviteLink: builder.query({
- query: (gid) => ({
- headers: {
- 'content-type': 'text/plain',
- accept: 'text/plain'
- },
- url: `/group/${gid}/create_invite_link`,
- responseHandler: (response) => response.text()
- }),
- transformResponse: (link) => {
- // 替换掉域名
- const invite = new URL(link);
- return `${location.origin}${invite.pathname}${invite.search}${invite.hash}`;
- }
- }),
- removeChannel: builder.query({
- query: (id) => ({
- url: `group/${id}`,
- method: 'DELETE'
- }),
- async onQueryStarted(id, { dispatch, getState, queryFulfilled }) {
- const { channelMessage } = getState();
- try {
- await queryFulfilled;
- // 删掉该channel下的所有消息&reaction
- const mids = channelMessage[id];
- if (mids) {
- dispatch(removeChannelSession(id));
- dispatch(removeMessage(mids));
- dispatch(removeReactionMessage(mids));
- }
- } catch {
- console.log('remove channel error');
- }
- }
- }),
- sendChannelMsg: builder.mutation({
- query: ({ id, content, type = 'text', properties = '' }) => ({
- headers: {
- 'content-type': ContentTypes[type],
- 'X-Properties': properties
- ? btoa(unescape(encodeURIComponent(JSON.stringify(properties))))
- : ''
- },
- url: `group/${id}/send`,
- method: 'POST',
- body: type == 'file' ? JSON.stringify(content) : content
- }),
- async onQueryStarted(param1, param2) {
- await onMessageSendStarted.call(this, param1, param2, 'channel');
- }
- }),
- addMembers: builder.mutation({
- query: ({ id, members }) => ({
- url: `group/${id}/members/add`,
- method: 'POST',
- body: members
- })
- }),
- removeMembers: builder.mutation({
- query: ({ id, members }) => ({
- url: `group/${id}/members/remove`,
- method: 'POST',
- body: members
- })
- }),
- updateIcon: builder.mutation({
- query: ({ gid, image }) => ({
- headers: {
- 'content-type': 'image/png'
- },
- url: `/group/${gid}/avatar`,
- method: 'POST',
- body: image
- }),
- async onQueryStarted({ gid }, { dispatch, queryFulfilled }) {
- try {
- await queryFulfilled;
- dispatch(
- updateChannel({
- id: gid,
- icon: `${BASE_URL}/resource/group_avatar?gid=${gid}&t=${new Date().getTime()}`
- })
- );
- } catch (error) {
- console.log('err', error);
- }
- }
- })
- })
});
export const {
- useLazyCreateInviteLinkQuery,
- useCreateInviteLinkQuery,
- useLazyGetHistoryMessagesQuery,
- useGetChannelQuery,
- useUpdateChannelMutation,
- useLazyRemoveChannelQuery,
- useGetChannelsQuery,
- useCreateChannelMutation,
- useSendChannelMsgMutation,
- useAddMembersMutation,
- useRemoveMembersMutation,
- useUpdateIconMutation
+ useLazyLeaveChannelQuery,
+ useLazyCreateInviteLinkQuery,
+ useCreateInviteLinkQuery,
+ useLazyGetHistoryMessagesQuery,
+ useGetChannelQuery,
+ useUpdateChannelMutation,
+ useLazyRemoveChannelQuery,
+ useGetChannelsQuery,
+ useCreateChannelMutation,
+ useSendChannelMsgMutation,
+ useAddMembersMutation,
+ useRemoveMembersMutation,
+ useUpdateIconMutation,
} = channelApi;
diff --git a/src/app/slices/channels.js b/src/app/slices/channels.js
index 94d94dc0..1af46c25 100644
--- a/src/app/slices/channels.js
+++ b/src/app/slices/channels.js
@@ -40,7 +40,6 @@ const channelsSlice = createSlice({
},
updateChannel(state, action) {
const ignoreInPublic = ["add_member", "remove_member"];
- // console.log("set channels store", action);
const { id, operation, members = [], ...rest } = action.payload;
const currChannel = state.byId[id];
if (
@@ -48,7 +47,6 @@ const channelsSlice = createSlice({
(currChannel.is_public && ignoreInPublic.includes(operation))
)
return;
-
switch (operation) {
case "remove_member":
{
@@ -71,9 +69,7 @@ const channelsSlice = createSlice({
console.log("add member to channel", [..._set]);
state.byId[id].members = [..._set];
}
-
break;
-
default:
state.byId[id] = { ...state.byId[id], ...rest };
break;
diff --git a/src/common/component/LeaveChannel/LeaveConfirmModal.js b/src/common/component/LeaveChannel/LeaveConfirmModal.js
new file mode 100644
index 00000000..cf9f7e0d
--- /dev/null
+++ b/src/common/component/LeaveChannel/LeaveConfirmModal.js
@@ -0,0 +1,53 @@
+import { useEffect } from "react";
+import toast from "react-hot-toast";
+import { useNavigate } from "react-router-dom";
+import useLeaveChannel from "../../hook/useLeaveChannel";
+import Modal from "../Modal";
+import StyledModal from "../styled/Modal";
+import Button from "../styled/Button";
+
+export default function LeaveConfirmModal({ id, closeModal, handleNextStep }) {
+ const navigateTo = useNavigate();
+ const { isOwner, leaving, leaveChannel, leaveSuccess } = useLeaveChannel(id);
+
+ useEffect(() => {
+ if (leaveSuccess) {
+ toast.success("Leave channel successfully!");
+ closeModal();
+ navigateTo("/chat");
+ }
+ }, [leaveSuccess]);
+ if (!id) return null;
+ return (
+