import { useAuth } from "@web/src/providers/auth-provider"; import { Avatar, Tag, theme, Tooltip } from "antd"; import React, { ReactNode, useEffect, useState, useRef, CSSProperties, } from "react"; import { SyncOutlined } from "@ant-design/icons"; import * as Y from "yjs"; import { stringToColor, YWsProvider } from "@nice/common"; import { lightenColor } from "@nice/client"; import { useLocalSettings } from "@web/src/hooks/useLocalSetting"; import Breadcrumb from "../element/breadcrumb"; interface AdminHeaderProps { children?: ReactNode; roomId?: string; awarePlaceholder?: string; borderless?: boolean; style?: CSSProperties; className?: string; } const AdminHeader: React.FC = ({ className, style, borderless = false, children, roomId, awarePlaceholder = "协作人员", }) => { const { user, sessionId, accessToken } = useAuth(); const [userStates, setUserStates] = useState>(new Map()); const { token } = theme.useToken(); const providerRef = useRef(null); const { websocketUrl } = useLocalSettings(); useEffect(() => { let cleanup: (() => void) | undefined; // 如果已经连接或缺少必要参数,则返回 if (!user || !roomId || !websocketUrl) { return; } // 设置延时,避免立即连接 const connectTimeout = setTimeout(() => { try { const ydoc = new Y.Doc(); const provider = new YWsProvider( websocketUrl + "/yjs", roomId, ydoc, { params: { userId: user?.id, sessionId, }, } ); providerRef.current = provider; const { awareness } = provider; const updateAwarenessData = () => { const uniqueStates = new Map(); awareness.getStates().forEach((value, key) => { const sessionId = value?.user?.sessionId; if (sessionId) { uniqueStates.set(sessionId, value); } }); setUserStates(uniqueStates); }; const localState = { user: { id: user.id, showname: user?.showname || user.username, deptName: user.department?.name, sessionId, }, }; awareness.setLocalStateField("user", localState.user); awareness.on("change", updateAwarenessData); updateAwarenessData(); const handleBeforeUnload = () => { awareness.setLocalState(null); provider.disconnect(); }; window.addEventListener("beforeunload", handleBeforeUnload); // 定义清理函数 cleanup = () => { if (providerRef.current) { awareness.off("change", updateAwarenessData); awareness.setLocalState(null); provider.disconnect(); providerRef.current = null; } setUserStates(new Map()); window.removeEventListener( "beforeunload", handleBeforeUnload ); }; } catch (error) { console.error("WebSocket connection error:", error); } }, 100); // 返回清理函数 return () => { clearTimeout(connectTimeout); if (cleanup) { cleanup(); } }; }, [roomId, user, websocketUrl, sessionId]); // 其余渲染代码保持不变... const renderAvatars = () => Array.from(userStates.entries()).map(([key, value]) => ( {value?.user.deptName && ( {value?.user?.deptName} )} {value?.user?.showname || "匿名用户"} } key={key}> {!value?.user?.avatarUrl && (value?.user?.showname?.toUpperCase() || "匿名用户")} )); return (
{roomId && ( } color={token.colorPrimaryHover}> {awarePlaceholder} )} {renderAvatars()}
{children}
); }; export default AdminHeader;