import { FriendUserItem } from "@openim/wasm-client-sdk/lib/types/entity"; import axios from "axios"; import { Empty, Spin } from "antd"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { GroupedVirtuoso } from "react-virtuoso"; import { ACCOUNT_URL } from "@/config/endpoints"; import { useContactStore } from "@/store"; import { emit } from "@/utils/events"; import { getIMToken } from "@/utils/storage"; import FriendListItem from "./FriendListItem"; type DirInfo = { title: string; department: string }; export const MyFriends = () => { const { t } = useTranslation(); const friendList = useContactStore((state) => state.friendList); const [dirMap, setDirMap] = useState>({}); const [dirReady, setDirReady] = useState(false); useEffect(() => { let cancelled = false; const loadTitles = async () => { try { const token = await getIMToken(); if (!token) { setDirReady(true); return; } const { data } = await axios.get( `${ACCOUNT_URL}/api/directory`, { params: { keyword: "", limit: 100 }, headers: { Authorization: `Bearer ${token}` }, }, ); if (cancelled) return; if (data?.code === 0) { const map: Record = {}; for (const item of data.data?.items ?? []) { if (item.userID) { map[item.userID] = { title: item.title || "", department: item.department || "", }; } } setDirMap(map); } } catch { // 目录不可用时职务行留空、部门归入未分组 } finally { if (!cancelled) setDirReady(true); } }; void loadTitles(); return () => { cancelled = true; }; }, []); const sectionData = useMemo(() => { const ungrouped = t("placeholder.ungrouped"); const map = new Map(); for (const friend of friendList) { const dept = dirMap[friend.userID]?.department?.trim() || ungrouped; const list = map.get(dept) ?? []; list.push(friend); map.set(dept, list); } const names = [...map.keys()].sort((a, b) => { if (a === ungrouped) return 1; if (b === ungrouped) return -1; return a.localeCompare(b, "zh"); }); return { groupCounts: names.map((name) => map.get(name)!.length), indexList: names, totalList: names.flatMap((name) => map.get(name)!), }; }, [friendList, dirMap, t]); const showUserCard = useCallback((userID: string) => { emit("OPEN_USER_CARD", { userID, }); }, []); return (
{t("placeholder.myFriend")}
{!dirReady && friendList.length === 0 ? ( ) : !friendList.length ? ( ) : (
(
{sectionData.indexList[index]}
)} itemContent={(index) => { const friend = sectionData.totalList[index]; return ( ); }} className="no-scrollbar h-full overflow-x-hidden" />
)}
); };