diff --git a/client/api/ApiDeclare.ts b/client/api/ApiDeclare.ts index 896402e..e02882e 100644 --- a/client/api/ApiDeclare.ts +++ b/client/api/ApiDeclare.ts @@ -19,6 +19,7 @@ export type CallMethod = "Chat.getInfo" | "Chat.updateSettings" | + "Chat.setAvatar" | "Chat.createGroup" | diff --git a/client/api/client_data/GroupSettings.ts b/client/api/client_data/GroupSettings.ts index 14a007e..eeac578 100644 --- a/client/api/client_data/GroupSettings.ts +++ b/client/api/client_data/GroupSettings.ts @@ -4,6 +4,10 @@ interface GroupSettings { new_member_join_method?: 'disabled' | 'allowed_by_admin' | 'answered_and_allowed_by_admin' answered_and_allowed_by_admin_question?: string + // 下面两个比较特殊, 由服务端给予 + group_title: string + group_id: string + [key: string]: unknown } diff --git a/client/ui/chat/ChatFragment.tsx b/client/ui/chat/ChatFragment.tsx index 58b6e10..519ae98 100644 --- a/client/ui/chat/ChatFragment.tsx +++ b/client/ui/chat/ChatFragment.tsx @@ -195,6 +195,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC } const attachFileInputRef = React.useRef(null) + const uploadChatAvatarRef = React.useRef(null) function insertText(text: string) { const input = inputRef.current!.shadowRoot!.querySelector('[part=input]') as HTMLTextAreaElement @@ -224,6 +225,22 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC addFile(file.type, file.name, file) } }) + useEventListener(uploadChatAvatarRef, 'change', async (_e) => { + const file = uploadChatAvatarRef.current!.files?.[0] as File + if (file == null) return + + const re = await Client.invoke("Chat.setAvatar", { + token: data.access_token, + target: target, + avatar: file + }) + + if (checkApiSuccessOrSncakbar(re, "修改失败")) return + snackbar({ + message: "修改成功 (刷新页面以更新)", + placement: "top", + }) + }) const groupPreferenceStore = new PreferenceStore() groupPreferenceStore.setOnUpdate(async (value, oldvalue) => { @@ -494,9 +511,35 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC flexDirection: "column", height: "100%", }}> +
+ +
{ chatInfo.type == 'group' && + + { + uploadChatAvatarRef.current!.click() + }} /> + + { + if (this.checkArgsMissing(args, ['avatar', 'token'])) return { + msg: "参数缺失", + code: 400, + } + if (!(args.avatar instanceof Buffer)) return { + msg: "参数不合法", + code: 400, + } + const token = TokenManager.decode(args.token as string) + + const user = User.findById(token.author) as User + + const chat = Chat.findById(args.target as string) + if (chat == null) return { + code: 404, + msg: "对话不存在", + } + + if (chat.bean.type == 'group') + if (chat.checkUserIsAdmin(user.bean.id)) { + const avatar: Buffer = args.avatar as Buffer + if (avatar) + chat.setAvatar(avatar) + } else + return { + code: 403, + msg: "没有此权限", + } + + return { + msg: "成功", + code: 200, + } + }) /** - * 更新设定 + * 更新设定 (包括资料) * @param token 令牌 * @param title 名称 * @param [id] 群组 ID @@ -475,9 +516,15 @@ export default class ChatApi extends BaseApi { } if (chat.bean.type == 'group') - if (chat.checkUserIsAdmin(user.bean.id)) + if (chat.checkUserIsAdmin(user.bean.id)) { ChatGroup.fromChat(chat).getSettings().update(args.settings as GroupSettingsBean) - else + + const settings = args.settings as any + if (settings.group_title != null) + chat.setTitle(settings.group_title) + if (settings.group_id != null) + chat.setId(settings.group_id) + } else return { code: 403, msg: "没有此权限", diff --git a/server/data/Chat.ts b/server/data/Chat.ts index 52bfa93..addbe69 100644 --- a/server/data/Chat.ts +++ b/server/data/Chat.ts @@ -200,10 +200,8 @@ export default class Chat { return null } - getId() { - return this.bean.id - } setId(id: string) { + if (this.bean.id == id) return if (Chat.findAllChatBeansByCondition('id = ?', id).length > 0) throw new DataWrongError(`对话ID ${id} 已被使用`) this.setAttr("id", id)