diff --git a/client/ui/main/ContactsList.tsx b/client/ui/main/ContactsList.tsx index 89d2733..7563b9a 100644 --- a/client/ui/main/ContactsList.tsx +++ b/client/ui/main/ContactsList.tsx @@ -1,44 +1,42 @@ import React from "react" -import User from "../../api/client_data/User.ts" import ContactsListItem from "./ContactsListItem.tsx" import useEventListener from "../useEventListener.ts" -import { ListItem, TextField } from "mdui" +import { Dialog, ListItem, TextField } from "mdui" import useAsyncEffect from "../useAsyncEffect.ts" import Client from "../../api/Client.ts" import data from "../../Data.ts" +import { checkApiSuccessOrSncakbar } from "../snackbar.ts" +import Chat from "../../api/client_data/Chat.ts" interface Args extends React.HTMLAttributes { display: boolean - openChatFragment: (id: string) => void + chatInfoDialogRef: React.MutableRefObject + setChatInfo: React.Dispatch> } export default function ContactsList({ display, - openChatFragment, + setChatInfo, + chatInfoDialogRef, ...props }: Args) { 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[]) + const [contactsList, setContactsList] = React.useState([]) useEventListener(searchRef, 'input', (e) => { setSearchText((e.target as unknown as TextField).value) }) useAsyncEffect(async () => { - + const re = await Client.invoke("User.getMyContacts", { + token: data.access_token, + }) + if (re.code != 200) + return checkApiSuccessOrSncakbar(re, "获取联络人列表失败") + + setContactsList(re.data!.contacts_list as Chat[]) }) return setIsMultiSelecting(!isMultiSelecting)}>{ isMultiSelecting ? "關閉多選" : "多選模式" } */} { - contactsList.filter((user) => + contactsList.filter((chat) => searchText == '' || - user.nickname.includes(searchText) || - user.id.includes(searchText) || - user.username?.includes(searchText) + chat.title.includes(searchText) || + chat.id.includes(searchText) ).map((v) => { const self = (e.target as ListItem) - if (isMultiSelecting) + /*if (isMultiSelecting) self.active = !self.active - else - void(0) - }} */ + else*/ + setChatInfo(v) + chatInfoDialogRef.current!.open = true + }} key={v.id} contact={v} /> ) diff --git a/client/ui/main/ContactsListItem.tsx b/client/ui/main/ContactsListItem.tsx index 5568351..1bed435 100644 --- a/client/ui/main/ContactsListItem.tsx +++ b/client/ui/main/ContactsListItem.tsx @@ -1,15 +1,14 @@ -import { ListItem } from "mdui"; -import User from "../../api/client_data/User.ts" +import Chat from "../../api/client_data/Chat.ts" import Avatar from "../Avatar.tsx" import React from 'react' interface Args extends React.HTMLAttributes { - contact: User + contact: Chat active?: boolean } export default function ContactsListItem({ contact, ...prop }: Args) { - const { id, nickname, avatar } = contact + const { id, title, avatar } = contact const ref = React.useRef(null) return ( @@ -20,8 +19,8 @@ export default function ContactsListItem({ contact, ...prop }: Args) { }} {...prop as any}> {nickname} - + }}>{title} + ) } diff --git a/server/api/UserApi.ts b/server/api/UserApi.ts index f1e810f..c2be4c8 100644 --- a/server/api/UserApi.ts +++ b/server/api/UserApi.ts @@ -18,7 +18,7 @@ export default class UserApi extends BaseApi { } try { const access_token = TokenManager.decode(args.access_token as string) - + if (access_token.expired_time < Date.now()) return { msg: "登錄令牌失效", code: 401, @@ -135,7 +135,7 @@ export default class UserApi extends BaseApi { msg: "參數缺失", code: 400, } - + const token = TokenManager.decode(args.token as string) if (!this.checkToken(token)) return { code: 401, @@ -144,9 +144,9 @@ export default class UserApi extends BaseApi { const user = User.findById(token.author) if (args.nickname != null) - user!.setNickName(args.nickname as string) + user!.setNickName(args.nickname as string) if (args.username != null) - user!.setUserName(args.username as string) + user!.setUserName(args.username as string) return { msg: "成功", @@ -192,14 +192,21 @@ export default class UserApi extends BaseApi { msg: "令牌無效", } - const user = User.findById(token.author) + const user = User.findById(token.author) as User + const contacts = user.getContactsList() + contacts.push(ChatPrivate.getChatIdByUsersId(token.author, token.author)) return { msg: "成功", code: 200, data: { - contacts: user!.getContactsList().map((id) => { - title: Chat.findById(id)?.bean.title + contacts_list: contacts.map((id) => { + const chat = Chat.findById(id) + return { + id, + title: chat?.getTitle(user) || "未知", + avatar: chat?.getAvatarFileHash(user) ? "uploaded_files/" + chat?.getAvatarFileHash(user) : undefined + } }) } } @@ -230,6 +237,6 @@ export default class UserApi extends BaseApi { * 公開資料 * ================================================ */ - + } } \ No newline at end of file diff --git a/server/data/User.ts b/server/data/User.ts index 0d6abc5..beba3f9 100644 --- a/server/data/User.ts +++ b/server/data/User.ts @@ -36,7 +36,7 @@ export default class User { /* 用戶名, 可選 */ username TEXT, /* 昵称 */ nickname TEXT NOT NULL, /* 头像, 可选 */ avatar_file_hash TEXT, - /* 聯絡人組 */ contact_groups TEXT NOT NULL, + /* 聯絡人組 */ contacts_list TEXT NOT NULL, /* 设置 */ settings TEXT NOT NULL ); `) @@ -80,7 +80,7 @@ export default class User { )[0] ) avatar && user.setAvatar(avatar) - user.addContact(ChatPrivate.getChatIdByUsersId(user.bean.id, user.bean.id)) + ChatPrivate.findOrCreateForPrivate(user, user) return user } @@ -133,9 +133,7 @@ export default class User { return JSON.parse(this.bean.contacts_list) as string[] } catch (e) { console.log(chalk.yellow(`警告: 聯絡人組解析失敗: ${(e as Error).message}`)) - return [ - this.bean.id - ] + return [] } } getNickName(): string {