"use client"; import { useEffect, type Dispatch, type RefObject, type SetStateAction } from "react"; import type { ChatSession } from "@/lib/home-types"; import type { Account } from "@/lib/home-types"; import type { ChartLibraryRecord, Profile } from "@/lib/home-types"; import type { PublicLanguageModelCatalog } from "@/lib/public-models"; import { toSidebarSessionRow } from "@/lib/session-sidebar-row"; import type { ShellRegistration } from "@/lib/session-list-context"; type AccountDialogName = "profile" | "chart-library" | "general" | "billing" | "logout"; type HomeShellRegistrationParams = { account: Account | null; accountMenuOpen: boolean; accountTrigger: RefObject; activeSessionId: string | undefined; cancellationPending: boolean; chartLibrary: readonly ChartLibraryRecord[]; creatingSession: boolean; hydrated: boolean; loadMoreSessions: () => void; modalOpen: boolean; modelCatalog: PublicLanguageModelCatalog | null; openAccountDialog: (dialog: AccountDialogName, options?: { source?: string }) => void; pendingSessionId: string | null; profile: Profile; rectificationErrorMessage: string; rectificationErrorSessionId: string | null; rectificationOpeningSessionId: string | null; rectificationSurfaceOpen: boolean; registerShellControls: (registration: ShellRegistration | null) => void; renameSession: (session: ChatSession) => void | Promise; selectSession: (sessionId: string) => void; sessionMenuId: string | null; sessions: readonly ChatSession[]; sessionsCursor: string | null; setAccountMenuOpen: Dispatch>; setPendingSessionDeletion: Dispatch>; setSessionMenuId: Dispatch>; shareSession: (session: ChatSession) => void | Promise; startNewChat: () => void | Promise; togglePinnedSession: (sessionId: string) => void; visibleSessions: readonly ChatSession[]; }; export function useHomeShellRegistration(params: HomeShellRegistrationParams) { const { account, accountMenuOpen, accountTrigger, activeSessionId, cancellationPending, chartLibrary, creatingSession, hydrated, loadMoreSessions, modalOpen, modelCatalog, openAccountDialog, pendingSessionId, profile, rectificationErrorMessage, rectificationErrorSessionId, rectificationOpeningSessionId, rectificationSurfaceOpen, registerShellControls, renameSession, selectSession, sessionMenuId, sessions, sessionsCursor, setAccountMenuOpen, setPendingSessionDeletion, setSessionMenuId, shareSession, startNewChat, togglePinnedSession, visibleSessions, } = params; useEffect(() => { if (!hydrated || !account) { registerShellControls(null); return; } const name = profile.name.trim(); const email = account.user.email || "尚未读取邮箱"; registerShellControls({ escapeBlocked: accountMenuOpen || modalOpen, activeSessionId: activeSessionId ?? null, openingSessionId: rectificationOpeningSessionId, openErrorSessionId: rectificationErrorSessionId, openErrorMessage: rectificationErrorSessionId ? rectificationErrorMessage : "", insetClassName: `chat-panel${rectificationSurfaceOpen ? " is-rectification" : ""}`, insetInert: modalOpen, sidebarAccount: { name: name || account.user.email || "账户", email, credits: account.credits, avatar: account.avatar, initial: name.slice(0, 1) || account.user.email?.slice(0, 1).toUpperCase() || "你", }, sidebarSessions: visibleSessions.map((session) => toSidebarSessionRow(session, chartLibrary)), controls: { newChatDisabled: !hydrated || !modelCatalog || creatingSession || Boolean(pendingSessionId) || cancellationPending, creatingSession, accountMenuOpen, accountTriggerRef: accountTrigger, sessionControls: { hasMore: Boolean(sessionsCursor), onLoadMore: loadMoreSessions, menuSessionId: sessionMenuId, disabled: Boolean(pendingSessionId) || cancellationPending, onMenuSessionChange: setSessionMenuId, onTogglePinned: togglePinnedSession, onRename: (sessionId) => { const session = sessions.find((candidate) => candidate.id === sessionId); if (session) void renameSession(session); }, onShare: (sessionId) => { const session = sessions.find((candidate) => candidate.id === sessionId); if (session) void shareSession(session); }, onDelete: (sessionId) => { const session = sessions.find((candidate) => candidate.id === sessionId); if (session) setPendingSessionDeletion(session); }, }, onAccountMenuOpenChange: setAccountMenuOpen, onNewChat: () => { void startNewChat(); }, onSelectSession: selectSession, onOpenProfile: () => openAccountDialog("profile"), onOpenChartLibrary: () => openAccountDialog("chart-library"), onOpenGeneral: () => openAccountDialog("general"), onOpenBilling: () => openAccountDialog("billing", { source: "account-menu" }), onOpenLogout: () => openAccountDialog("logout"), }, }); }, [ account, accountMenuOpen, accountTrigger, activeSessionId, cancellationPending, chartLibrary, creatingSession, hydrated, loadMoreSessions, modalOpen, modelCatalog, openAccountDialog, pendingSessionId, profile.name, rectificationErrorMessage, rectificationErrorSessionId, rectificationOpeningSessionId, rectificationSurfaceOpen, registerShellControls, renameSession, selectSession, sessionMenuId, sessions, sessionsCursor, setAccountMenuOpen, setPendingSessionDeletion, setSessionMenuId, shareSession, startNewChat, togglePinnedSession, visibleSessions, ]); useEffect(() => () => registerShellControls(null), [registerShellControls]); }