diff --git a/client/ui/chat/ChatFragment.tsx b/client/ui/chat/ChatFragment.tsx index bd07d03..ab3fe7e 100644 --- a/client/ui/chat/ChatFragment.tsx +++ b/client/ui/chat/ChatFragment.tsx @@ -344,7 +344,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC : {chatInfo.title} } - 设置 + {chatInfo.type == 'group' && 设置}
- + } { @@ -576,7 +576,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC flexDirection: "column", height: "100%", }}> - + } { - target: string + chat: Chat } export default function GroupMembersList({ - target, + chat, ...props }: Args) { + const target = chat.id const searchRef = React.useRef(null) const [searchText, setSearchText] = React.useState('') const [groupMembers, setGroupMembers] = React.useState([]) @@ -41,6 +43,7 @@ export default function GroupMembersList({ const id = setTimeout(() => updateMembers(), 15 * 1000) return () => { clearTimeout(id) + EventBus.off('GroupMembersList.updateMembers') } }, [target]) diff --git a/client/ui/chat/GroupMembersListItem.tsx b/client/ui/chat/GroupMembersListItem.tsx index 8020a8f..b19da42 100644 --- a/client/ui/chat/GroupMembersListItem.tsx +++ b/client/ui/chat/GroupMembersListItem.tsx @@ -1,4 +1,4 @@ -import { $ } from "mdui/jq" +import { $, dialog } from "mdui" import Avatar from "../Avatar.tsx" import React from 'react' import User from "../../api/client_data/User.ts" @@ -9,7 +9,7 @@ interface Args extends React.HTMLAttributes { } export default function GroupMembersListItem({ user }: Args) { - const { nickname, avatar_file_hash } = user + const { id, nickname, avatar_file_hash } = user const itemRef = React.useRef(null) return ( @@ -19,10 +19,52 @@ export default function GroupMembersListItem({ user }: Args) { }} ref={itemRef}> {nickname} - {/*
- - -
*/} +
+ dialog({ + headline: "移除群组成员", + description: `确定要移除 ${nickname} 吗?`, + actions: [ + { + text: "取消", + onClick: () => { + return true + }, + }, + { + text: "确定", + onClick: () => { + ;(async () => { + const re = await Client.invoke("Chat.removeMembers", { + token: data.access_token, + chat_id: target, + user_ids: [ + id + ], + }) + if (re.code != 200) + checkApiSuccessOrSncakbar(re, "移除群组成员失败") + EventBus.emit('GroupMembersList.updateMembers') + snackbar({ + message: `已移除 ${nickname}`, + placement: "top", + action: "撤销操作", + onActionClick: async () => { + const re = await Client.invoke("User.addContacts", { + token: data.access_token, + targets: ls, + }) + if (re.code != 200) + checkApiSuccessOrSncakbar(re, "恢复所选收藏失败") + EventBus.emit('ContactsList.updateContacts') + } + }) + })() + return true + }, + } + ], + })}> +
) } diff --git a/client/ui/chat/JoinRequestsList.tsx b/client/ui/chat/JoinRequestsList.tsx index 260dceb..8ed022a 100644 --- a/client/ui/chat/JoinRequestsList.tsx +++ b/client/ui/chat/JoinRequestsList.tsx @@ -11,15 +11,17 @@ import EventBus from "../../EventBus.ts" import isMobileUI from "../isMobileUI.ts" import JoinRequest from "../../api/client_data/JoinRequest.ts" import JoinRequestsListItem from "./JoinRequestsListItem.tsx"; +import Chat from "../../api/client_data/Chat.ts" interface Args extends React.HTMLAttributes { - target: string + chat: Chat } -export default function JoinRequestsList({ - target, +export default function GroupMembersList({ + chat, ...props }: Args) { + const target = chat.id const searchRef = React.useRef(null) const [searchText, setSearchText] = React.useState('') const [updateJoinRequests, setUpdateJoinRequests] = React.useState([]) @@ -44,6 +46,7 @@ export default function JoinRequestsList({ const id = setTimeout(() => updateJoinRequests(), 15 * 1000) return () => { clearTimeout(id) + EventBus.off('JoinRequestsList.updateJoinRequests') } }, [target]) diff --git a/server/api/ApiDeclare.ts b/server/api/ApiDeclare.ts index f288735..c94b59d 100644 --- a/server/api/ApiDeclare.ts +++ b/server/api/ApiDeclare.ts @@ -40,6 +40,10 @@ export type CallMethod = "Chat.sendJoinRequest" | "Chat.getJoinRequests" | + // 对话成员 + "Chat.removeMembers" | + "Chat.quit" | + // 对话消息 "Chat.sendMessage" | "Chat.getMessageHistory" diff --git a/server/api/ChatApi.ts b/server/api/ChatApi.ts index 694e38a..1232024 100644 --- a/server/api/ChatApi.ts +++ b/server/api/ChatApi.ts @@ -155,6 +155,75 @@ export default class ChatApi extends BaseApi { }, } }) */ + /** + * ====================================================== + * 对话成员 + * ====================================================== + */ + this.registerEvent("Chat.quit", (args, { deviceId }) => { + if (this.checkArgsMissing(args, ['token', 'chat_id', 'user_ids'])) return { + msg: "参数缺失", + code: 400, + } + const action = args.action as string + + const token = TokenManager.decode(args.token as string) + if (!this.checkToken(token, deviceId)) return { + code: 401, + msg: "令牌无效", + } + + const chat = Chat.findById(args.chat_id as string) + if (chat == null) return { + code: 404, + msg: "对话不存在", + } + if (!chat.checkUserIsAdmin(token.author)) return { + code: 403, + msg: "没有此权限", + } + + const members = args.user_ids as string[] + members.splice(members.indexOf(token.author)) + chat.removeMembers(members) + + return { + code: 200, + msg: '成功', + } + }) + this.registerEvent("Chat.removeMembers", (args, { deviceId }) => { + if (this.checkArgsMissing(args, ['token', 'chat_id', 'user_ids'])) return { + msg: "参数缺失", + code: 400, + } + const action = args.action as string + + const token = TokenManager.decode(args.token as string) + if (!this.checkToken(token, deviceId)) return { + code: 401, + msg: "令牌无效", + } + + const chat = Chat.findById(args.chat_id as string) + if (chat == null) return { + code: 404, + msg: "对话不存在", + } + if (!chat.checkUserIsAdmin(token.author)) return { + code: 403, + msg: "没有此权限", + } + + const members = args.user_ids as string[] + members.splice(members.indexOf(token.author)) + chat.removeMembers(members) + + return { + code: 200, + msg: '成功', + } + }) /** * ====================================================== * 加入对话申请