- 基于 openim-electron-demo 改造:工号+密码登录(自研账号服务)、会话列表/聊天窗/通讯录界面重做
- 文字/语音/文件/图片消息、文件拖拽发送、表情面板、一对一语音通话(LiveKit)
- RTC 令牌对接账号服务带鉴权版 /api/rtc_token(Bearer imToken + {room,identity})
- account-service: CORS Allow-Headers 补 authorization(浏览器/渲染进程跨域调 rtc_token 需要)
- 附本地 mock 账号服务(scripts/mock-account-server.js)与截图联调脚本
118 lines
3.4 KiB
TypeScript
118 lines
3.4 KiB
TypeScript
import { Badge } from "antd";
|
|
import clsx from "clsx";
|
|
import i18n, { t } from "i18next";
|
|
import { useEffect, useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
import group_notifications from "@/assets/images/contact/group_notifications.png";
|
|
import my_friends from "@/assets/images/contact/my_friends.png";
|
|
import my_groups from "@/assets/images/contact/my_groups.png";
|
|
import new_friends from "@/assets/images/contact/new_friends.png";
|
|
import FlexibleSider from "@/components/FlexibleSider";
|
|
import { useContactStore } from "@/store";
|
|
|
|
const Links = [
|
|
{
|
|
label: t("placeholder.newFriends"),
|
|
icon: new_friends,
|
|
path: "/contact/newFriends",
|
|
},
|
|
{
|
|
label: t("placeholder.groupNotification"),
|
|
icon: group_notifications,
|
|
path: "/contact/groupNotifications",
|
|
},
|
|
{
|
|
label: t("placeholder.myFriend"),
|
|
icon: my_friends,
|
|
path: "/contact",
|
|
},
|
|
{
|
|
label: t("placeholder.myGroup"),
|
|
icon: my_groups,
|
|
path: "/contact/myGroups",
|
|
},
|
|
];
|
|
|
|
i18n.on("languageChanged", () => {
|
|
Links[0].label = t("placeholder.newFriends");
|
|
Links[1].label = t("placeholder.groupNotification");
|
|
Links[2].label = t("placeholder.myFriend");
|
|
Links[3].label = t("placeholder.myGroup");
|
|
});
|
|
|
|
const ContactSider = () => {
|
|
const [selectIndex, setSelectIndex] = useState(2);
|
|
const unHandleFriendApplicationCount = useContactStore(
|
|
(state) => state.unHandleFriendApplicationCount,
|
|
);
|
|
const unHandleGroupApplicationCount = useContactStore(
|
|
(state) => state.unHandleGroupApplicationCount,
|
|
);
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
if (location.hash.includes("/contact/newFriends")) {
|
|
setSelectIndex(0);
|
|
}
|
|
if (location.hash.includes("/contact/groupNotifications")) {
|
|
setSelectIndex(1);
|
|
}
|
|
if (location.hash.includes("/contact/myGroups")) {
|
|
setSelectIndex(3);
|
|
}
|
|
}, []);
|
|
|
|
const getBadge = (index: number) => {
|
|
if (index === 0) {
|
|
return unHandleFriendApplicationCount;
|
|
}
|
|
if (index === 1) {
|
|
return unHandleGroupApplicationCount;
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
return (
|
|
<FlexibleSider
|
|
needHidden={true}
|
|
wrapClassName="flex flex-col border-r border-[var(--gap-text)] bg-white"
|
|
>
|
|
<div className="app-drag px-4 pt-4">
|
|
<div className="pb-3 text-base font-bold">{t("placeholder.contact")}</div>
|
|
</div>
|
|
<div className="h-full flex-1 overflow-y-auto bg-white">
|
|
<ul>
|
|
{Links.map((item, index) => {
|
|
return (
|
|
<li
|
|
key={item.path}
|
|
className={clsx(
|
|
"mx-2 flex cursor-pointer items-center rounded-lg px-3 py-2.5 text-sm",
|
|
index === selectIndex
|
|
? "bg-[var(--primary-active)]"
|
|
: "hover:bg-[#F3F5F7]",
|
|
)}
|
|
onClick={() => {
|
|
setSelectIndex(index);
|
|
navigate(String(item.path));
|
|
}}
|
|
>
|
|
<Badge size="small" count={getBadge(index)}>
|
|
<img
|
|
alt={item.label}
|
|
src={item.icon}
|
|
className="mr-3 h-12 w-12 rounded-lg"
|
|
/>
|
|
</Badge>
|
|
<div className="text-sm">{item.label}</div>
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
</div>
|
|
</FlexibleSider>
|
|
);
|
|
};
|
|
export default ContactSider;
|