import { useEffect, useMemo, useState } from "react"; import { BugOutlined, IdcardOutlined, LoginOutlined, LogoutOutlined, PictureOutlined, UserOutlined, VideoCameraOutlined, WalletOutlined, } from "@ant-design/icons"; import { LocalAvatar } from "./LocalAvatar"; import type { WebUserSession } from "../types"; interface TopbarProps { session: WebUserSession | null; usage: { balanceCents: number; imageUsed: number; videoUsed: number }; profileMenuOpen: boolean; onProfileMenuOpenChange: (open: boolean) => void; onOpenWorkspace: () => void; onOpenProfile: () => void; onOpenAuth: (mode: "login" | "register") => void; onLogout: () => void; onBugFeedback: () => void; } export function Topbar({ session, usage, profileMenuOpen, onProfileMenuOpenChange, onOpenWorkspace, onOpenProfile, onOpenAuth, onLogout, onBugFeedback, }: TopbarProps) { const [isTopbarHidden, setIsTopbarHidden] = useState(false); useEffect(() => { let restoreTimer: number | undefined; const handleScroll = (event: Event) => { if (profileMenuOpen) return; const target = event.target; const activeWorkspace = document.querySelector(".ecommerce-standalone__page--workspace:not([hidden])"); if (!activeWorkspace) return; const isWorkspacePreviewScroll = target instanceof HTMLElement && target.classList.contains("clone-ai-preview") && activeWorkspace.contains(target); const isPageScroll = target === document || target === document.scrollingElement || target === document.documentElement || target === document.body; if (!isWorkspacePreviewScroll && !isPageScroll) return; setIsTopbarHidden(true); if (restoreTimer) window.clearTimeout(restoreTimer); restoreTimer = window.setTimeout(() => { setIsTopbarHidden(false); }, 240); }; window.addEventListener("scroll", handleScroll, { capture: true, passive: true }); return () => { window.removeEventListener("scroll", handleScroll, { capture: true }); if (restoreTimer) window.clearTimeout(restoreTimer); }; }, [profileMenuOpen]); const balance = Math.max(usage.balanceCents, 0) / 100; const displayName = session?.user.displayName || session?.user.username || "用户"; const actualWorkCount = Math.max(usage.imageUsed + usage.videoUsed, 0); const shownWorkCount = actualWorkCount; const avatarMenuStats = useMemo( () => [ { icon: , label: "UID", value: session?.user.id ?? "-" }, { icon: , label: "积分", value: `${balance.toFixed(2)} 积分` }, { icon: , label: "图片", value: usage.imageUsed }, { icon: , label: "视频", value: usage.videoUsed }, { icon: , label: "作品", value: shownWorkCount }, ], [balance, session?.user.id, shownWorkCount, usage.imageUsed, usage.videoUsed], ); return (
{session ? (
{profileMenuOpen ? ( <>
) : null}
) : ( )}
); }