diff --git a/client/ui/dialog/ChatInfoDialog.tsx b/client/ui/dialog/ChatInfoDialog.tsx new file mode 100644 index 0000000..14e1ab4 --- /dev/null +++ b/client/ui/dialog/ChatInfoDialog.tsx @@ -0,0 +1,55 @@ +import React from 'react' +import Chat from "../../api/client_data/Chat.ts" +import useAsyncEffect from "../useAsyncEffect.ts" +import Client from "../../api/Client.ts" +import data from "../../Data.ts" +import { Dialog } from "mdui" + +interface Args extends React.HTMLAttributes { + chat: Chat + chatInfoDialogRef: React.MutableRefObject +} + +export default function ChatInfoDialog({ chat, chatInfoDialogRef }: Args) { + const [isMySelf, setIsMySelf] = React.useState(false) + + useAsyncEffect(async () => { + const re = await Client.invoke("Chat.getInfo", { + token: data.access_token, + target: chat.id, + }) + }) + + return ( + +
+ + {user?.nickname} +
+ + + + {!isMySelf && 編輯聯絡人訊息} + { + isMySelf && <> + 編輯資料 + 賬號設定 + 隱私設定 + + } + +
+ ) +} diff --git a/client/ui/main/ContactsList.tsx b/client/ui/main/ContactsList.tsx index 6364550..89d2733 100644 --- a/client/ui/main/ContactsList.tsx +++ b/client/ui/main/ContactsList.tsx @@ -3,17 +3,16 @@ import User from "../../api/client_data/User.ts" import ContactsListItem from "./ContactsListItem.tsx" import useEventListener from "../useEventListener.ts" import { ListItem, TextField } from "mdui" +import useAsyncEffect from "../useAsyncEffect.ts" +import Client from "../../api/Client.ts" +import data from "../../Data.ts" interface Args extends React.HTMLAttributes { - contactsList: User[] - setContactsList: React.Dispatch> display: boolean openChatFragment: (id: string) => void } export default function ContactsList({ - contactsList, - setContactsList, display, openChatFragment, ...props @@ -21,11 +20,27 @@ export default function ContactsList({ const searchRef = React.useRef(null) const [isMultiSelecting, setIsMultiSelecting] = React.useState(false) const [searchText, setSearchText] = React.useState('') + const [contactsList, setContactsList] = React.useState([ + { + id: '1', + avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png", + nickname: "麻油衣酱", + }, + { + id: '0', + avatar: "https://www.court-records.net/mugshot/aa6-004-maya.png", + nickname: "Maya Fey", + }, + ] as User[]) useEventListener(searchRef, 'input', (e) => { setSearchText((e.target as unknown as TextField).value) }) + useAsyncEffect(async () => { + + }) + return - searchText == '' || + searchText == '' || user.nickname.includes(searchText) || user.id.includes(searchText) || user.username?.includes(searchText) diff --git a/server/api/ApiDeclare.ts b/server/api/ApiDeclare.ts index 4bdf33a..c69e2cb 100644 --- a/server/api/ApiDeclare.ts +++ b/server/api/ApiDeclare.ts @@ -8,8 +8,9 @@ export type CallMethod = "User.setAvatar" | "User.getMyInfo" | - "User.getMyContactGroups" | - "User.setMyContactGroups" | + "User.getMyContacts" | + "User.addContact" | + "User.removeContacts" | "Chat.getInfo" | "Chat.sendMessage" | diff --git a/server/api/ChatApi.ts b/server/api/ChatApi.ts index 473273f..d33e3f9 100644 --- a/server/api/ChatApi.ts +++ b/server/api/ChatApi.ts @@ -29,20 +29,15 @@ export default class ChatApi extends BaseApi { // 私聊 if (chat!.bean.type == 'private') { - const targetId = args.target as string - const target = User.findById(targetId) const mine = User.findById(token.author) as User - if (target == null) return { - code: 404, - msg: "找不到用户", - } return { code: 200, msg: "成功", data: { type: chat.bean.type, - title: ChatPrivate.fromChat(chat).getTitleForPrivate(mine, target) + title: chat.getTitleForPrivate(mine), + avatar: chat.bean.avatar_file_hash ? "uploaded_files/" + chat.bean.avatar_file_hash : chat.bean.avatar_file_hash } } } diff --git a/server/api/UserApi.ts b/server/api/UserApi.ts index 297ee65..b760d84 100644 --- a/server/api/UserApi.ts +++ b/server/api/UserApi.ts @@ -2,6 +2,8 @@ import { Buffer } from "node:buffer"; import User from "../data/User.ts"; import BaseApi from "./BaseApi.ts" import TokenManager from "./TokenManager.ts"; +import ChatPrivate from "../data/ChatPrivate.ts"; +import Chat from "../data/Chat.ts"; export default class UserApi extends BaseApi { override getName(): string { @@ -196,7 +198,7 @@ export default class UserApi extends BaseApi { } }) // 獲取聯絡人列表 - this.registerEvent("User.getMyContactGroups", (args) => { + this.registerEvent("User.getMyContacts", (args) => { if (this.checkArgsMissing(args, ['token'])) return { msg: "參數缺失", code: 400, @@ -214,13 +216,15 @@ export default class UserApi extends BaseApi { msg: "成功", code: 200, data: { - contact_groups: user!.getContactGroups() + contacts: user!.getContactsList().map((id) => { + title: Chat.findById(id)?.bean.title + }) } } }) - // 更新聯絡人列表 - this.registerEvent("User.setMyContactGroups", (args) => { - if (this.checkArgsMissing(args, ['token', 'contact_groups'])) return { + // 添加聯絡人 + this.registerEvent("User.addContact", (args) => { + if (this.checkArgsMissing(args, ['token', 'contact_chat_id'])) return { msg: "參數缺失", code: 400, } @@ -232,7 +236,7 @@ export default class UserApi extends BaseApi { } const user = User.findById(token.author) - user!.setContactGroups(args.contact_groups as { [key: string]: string[] }) + user!.addContact(args.contact_chat_id as string) return { msg: "成功", diff --git a/server/data/Chat.ts b/server/data/Chat.ts index 8c624e0..29109da 100644 --- a/server/data/Chat.ts +++ b/server/data/Chat.ts @@ -30,13 +30,13 @@ export default class Chat { /* 设置 */ settings TEXT NOT NULL ); `) - return db + return db } - + protected static findAllBeansByCondition(condition: string, ...args: SQLInputValue[]): ChatBean[] { return this.database.prepare(`SELECT * FROM ${Chat.table_name} WHERE ${condition}`).all(...args) as unknown as ChatBean[] } - + static findById(id: string) { const beans = this.findAllBeansByCondition('id = ?', id) if (beans.length == 0) @@ -49,7 +49,7 @@ export default class Chat { static create(chatId: string, type: 'private' | 'group') { const chat = new Chat( Chat.findAllBeansByCondition( - 'count = ?', + 'count = ?', Chat.database.prepare(`INSERT INTO ${Chat.table_name} ( type, id, @@ -80,4 +80,13 @@ export default class Chat { Chat.database.prepare(`UPDATE ${Chat.table_name} SET ${key} = ? WHERE id = ?`).run(value, this.bean.id) this.bean[key] = value } + + getTitleForPrivate(userMySelf: User) { + if (this.bean.user_a_id == userMySelf.bean.id) + return User.findById(this.bean?.user_b_id as string)?.getNickName() || "未知對話" + if (this.bean.user_b_id == userMySelf.bean.id) + return userMySelf.getNickName() + + return "未知對話" + } } diff --git a/server/data/ChatPrivate.ts b/server/data/ChatPrivate.ts index 6fc63ae..c8c76ff 100644 --- a/server/data/ChatPrivate.ts +++ b/server/data/ChatPrivate.ts @@ -25,15 +25,4 @@ export default class ChatPrivate extends Chat { } return a } - - getTitleForPrivate(user: User, targetUser: User) { - const chat = Chat.findById(ChatPrivate.getChatIdByUsersId(user.bean.id, targetUser.bean.id)) - - if (chat?.bean.user_a_id == user.bean.id) - return targetUser.getNickName() - if (chat?.bean.user_b_id == user.bean.id) - return user.getNickName() - - return "未知對話" - } } \ No newline at end of file diff --git a/server/data/User.ts b/server/data/User.ts index e67ea03..62501f7 100644 --- a/server/data/User.ts +++ b/server/data/User.ts @@ -9,8 +9,11 @@ import config from '../config.ts' import UserBean from './UserBean.ts' import FileManager from './FileManager.ts' -import { SQLInputValue } from "node:sqlite"; -import DataWrongError from "../api/DataWrongError.ts"; +import { SQLInputValue } from "node:sqlite" +import DataWrongError from "../api/DataWrongError.ts" +import ChatPrivate from "./ChatPrivate.ts" +import Chat from "./Chat.ts" +import ChatBean from "./ChatBean.ts"; type UserBeanKey = keyof UserBean @@ -77,6 +80,7 @@ export default class User { )[0] ) avatar && user.setAvatar(avatar) + user.addContact(ChatPrivate.getChatIdByUsersId(user.bean.id, user.bean.id)) return user } @@ -115,12 +119,14 @@ export default class User { setUserName(userName: string) { this.setAttr("username", userName) } - addContact(userId) { - + addContact(chatId: string) { + const ls = this.getContactsList() + ls.push(chatId) + this.setAttr("contacts_list", JSON.stringify(ls)) } getContactsList() { try { - return JSON.parse(this.bean.contacts_list) + return JSON.parse(this.bean.contacts_list) as string[] } catch (e) { console.log(chalk.yellow(`警告: 聯絡人組解析失敗: ${(e as Error).message}`)) return [