refactor(home): let useSessionManagement own six session states
5.4: sessionsCursor / showArchivedSessions / sessionMenuId / pendingSessionDeletion / sessionDetailLoadingId / sessionFullPrompt move into use-session-management.ts, which now also computes visibleSessions from the archived flag it owns. Home reads back only what its own JSX renders. sessions / activeSessionId / creatingSession / pendingSessionId stay in the shell: each is read by the bootstrap effect or the consultation run before the session hook is called. Reasons are listed one by one in the progress record. useSessionManagement params 41 -> 34, useProfileOnboarding 38 -> 26. The growth contract tightens to useState 36 / useRef 37 / lines 1846 and gains an assertion that useSessionManagement still runs before useRectificationSurface, with the opener handed over through rectificationSessionOpenerRef. Zero behavior change, zero copy change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
This commit is contained in:
co-authored by
Claude Opus 5
parent
e6c6839742
commit
bdb81c8c86
+10
-14
@@ -77,7 +77,6 @@ import {
|
||||
} from "@/hooks/use-rectification-surface";
|
||||
import { useSynastry } from "@/hooks/use-synastry";
|
||||
import { useSessionManagement } from "@/hooks/use-session-management";
|
||||
import { sortSessions } from "@/lib/session-groups";
|
||||
import { showChatNotice as setComposerNotice } from "@/lib/chat-notice";
|
||||
import { chatReplyAnnouncement, type ChatReplyPhase } from "@/lib/chat-reply-announcement";
|
||||
import {
|
||||
@@ -252,10 +251,6 @@ export default function Home() {
|
||||
const [accountError, setAccountError] = useState("");
|
||||
const [signingOut, setSigningOut] = useState(false);
|
||||
const [sessions, setSessions] = useState<ChatSession[]>([]);
|
||||
const [showArchivedSessions, setShowArchivedSessions] = useState(false);
|
||||
const [sessionsCursor, setSessionsCursor] = useState<string | null>(null);
|
||||
const [sessionMenuId, setSessionMenuId] = useState<string | null>(null);
|
||||
const [pendingSessionDeletion, setPendingSessionDeletion] = useState<ChatSession | null>(null);
|
||||
const [modelCatalog, setModelCatalog] = useState<PublicLanguageModelCatalog | null>(null);
|
||||
const [activeSessionId, setActiveSessionId] = useState("");
|
||||
const draftTheme = useRef<Theme | null>(null);
|
||||
@@ -295,8 +290,6 @@ export default function Home() {
|
||||
const prepareStartedAt = useRef<number | null>(null);
|
||||
const [guidedJourneyPreview, setGuidedJourneyPreview] = useState(false);
|
||||
const [creatingSession, setCreatingSession] = useState(false);
|
||||
const [sessionDetailLoadingId, setSessionDetailLoadingId] = useState<string | null>(null);
|
||||
const [sessionFullPrompt, setSessionFullPrompt] = useState<{ question: string; theme: Theme } | null>(null);
|
||||
const [onboardingStep, setOnboardingStep] = useState<OnboardingStep>("name");
|
||||
const [onboardingJustCompleted, setOnboardingJustCompleted] = useState(false);
|
||||
const [onboardingPaywallOpen, setOnboardingPaywallOpen] = useState(false);
|
||||
@@ -390,11 +383,6 @@ export default function Home() {
|
||||
const activeRectificationSession = activeSession?.sessionType === "birth_time_rectification";
|
||||
const rectificationSurfaceOpen = activeRectificationSession
|
||||
&& activeSession.id === rectificationSessionId;
|
||||
const visibleSessions = sortSessions(sessions.filter((session) => (showArchivedSessions ? session.archivedAt : !session.archivedAt)
|
||||
&& (session.sessionType === "birth_time_rectification"
|
||||
|| session.messages.length > 0
|
||||
|| !session.messagesHydrated
|
||||
|| session.id === activeSessionId)));
|
||||
const activeError = requestError && requestError.sessionId === activeSession?.id ? requestError.message : "";
|
||||
const isLoading = pendingSessionId === activeSession?.id;
|
||||
const productEntrypointsDisabled = !hydrated
|
||||
@@ -439,6 +427,15 @@ export default function Home() {
|
||||
? "服务端未能读取完整出生资料,请重新确认并保存后再开始生时校正。"
|
||||
: rectificationError;
|
||||
const {
|
||||
visibleSessions,
|
||||
sessionsCursor,
|
||||
setSessionsCursor,
|
||||
showArchivedSessions,
|
||||
sessionMenuId,
|
||||
setSessionMenuId,
|
||||
pendingSessionDeletion,
|
||||
setPendingSessionDeletion,
|
||||
setSessionFullPrompt,
|
||||
updateSession,
|
||||
persistSession,
|
||||
ensureSessionMessages,
|
||||
@@ -457,8 +454,7 @@ export default function Home() {
|
||||
rectificationSessionId, sessionDetailInFlight, sessionSelectionSource, sessions, sessionsRef,
|
||||
setActiveChartId, setActiveSessionId, setBirthTimeConsultationConsent, setCreatingSession,
|
||||
setDraft, setDraftEntrypoint, setDraftTheme, setRectificationError, setRectificationErrorSessionId, setRequestError,
|
||||
setSessionDetailLoadingId, setSessionFullPrompt, setSessions, sessionsCursor, setSessionsCursor,
|
||||
showArchivedSessions, setShowArchivedSessions, uiPreview, visibleSessions,
|
||||
setSessions, uiPreview,
|
||||
openRectificationSession: (exactSessionId) => rectificationSessionOpenerRef.current(exactSessionId),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import type { Dispatch, MutableRefObject, SetStateAction } from "react";
|
||||
import { useRef } from "react";
|
||||
import { useRef, useState } from "react";
|
||||
|
||||
import { showChatNotice as setComposerNotice } from "@/lib/chat-notice";
|
||||
import { writeChatSession } from "@/lib/chat-session-write-contract";
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
writeSessionUrl,
|
||||
} from "@/lib/chat-session-url";
|
||||
import { consultationReportMarkdown } from "@/lib/consultation-report-export";
|
||||
import { sortSessions } from "@/lib/session-groups";
|
||||
import {
|
||||
clearBirthTimeConsultationConsent,
|
||||
type BirthTimeConsultationConsentState,
|
||||
@@ -76,15 +77,8 @@ export type SessionManagementParams = {
|
||||
setRectificationError: Dispatch<SetStateAction<string>>;
|
||||
setRectificationErrorSessionId: Dispatch<SetStateAction<string | null>>;
|
||||
setRequestError: Dispatch<SetStateAction<RequestError | null>>;
|
||||
setSessionDetailLoadingId: Dispatch<SetStateAction<string | null>>;
|
||||
setSessionFullPrompt: Dispatch<SetStateAction<{ question: string; theme: Theme } | null>>;
|
||||
setSessions: Dispatch<SetStateAction<ChatSession[]>>;
|
||||
sessionsCursor: string | null;
|
||||
setSessionsCursor: Dispatch<SetStateAction<string | null>>;
|
||||
showArchivedSessions: boolean;
|
||||
setShowArchivedSessions: Dispatch<SetStateAction<boolean>>;
|
||||
uiPreview: MutableRefObject<boolean>;
|
||||
visibleSessions: ChatSession[];
|
||||
openRectificationSession: (exactSessionId: string) => Promise<void> | void;
|
||||
};
|
||||
|
||||
@@ -121,20 +115,27 @@ export function useSessionManagement(params: SessionManagementParams) {
|
||||
setRectificationError,
|
||||
setRectificationErrorSessionId,
|
||||
setRequestError,
|
||||
setSessionDetailLoadingId,
|
||||
setSessionFullPrompt,
|
||||
setSessions,
|
||||
sessionsCursor,
|
||||
setSessionsCursor,
|
||||
showArchivedSessions,
|
||||
setShowArchivedSessions,
|
||||
uiPreview,
|
||||
visibleSessions,
|
||||
openRectificationSession,
|
||||
} = params;
|
||||
// Owned here since 2026-09-16 (state lowering batch 2). Home reads back only
|
||||
// what its own JSX renders; the rest never leaves this hook.
|
||||
const [sessionsCursor, setSessionsCursor] = useState<string | null>(null);
|
||||
const [showArchivedSessions, setShowArchivedSessions] = useState(false);
|
||||
const [sessionMenuId, setSessionMenuId] = useState<string | null>(null);
|
||||
const [pendingSessionDeletion, setPendingSessionDeletion] = useState<ChatSession | null>(null);
|
||||
const [sessionDetailLoadingId, setSessionDetailLoadingId] = useState<string | null>(null);
|
||||
const [sessionFullPrompt, setSessionFullPrompt] = useState<{ question: string; theme: Theme } | null>(null);
|
||||
sessionsRef.current = sessions;
|
||||
const loadMoreInFlight = useRef(false);
|
||||
|
||||
const visibleSessions = sortSessions(sessions.filter((session) => (showArchivedSessions ? session.archivedAt : !session.archivedAt)
|
||||
&& (session.sessionType === "birth_time_rectification"
|
||||
|| session.messages.length > 0
|
||||
|| !session.messagesHydrated
|
||||
|| session.id === activeSessionId)));
|
||||
|
||||
function updateSession(sessionId: string, change: (session: ChatSession) => ChatSession) {
|
||||
setSessions((current) => current.map((session) => (session.id === sessionId ? change(session) : session)));
|
||||
}
|
||||
@@ -520,6 +521,15 @@ export function useSessionManagement(params: SessionManagementParams) {
|
||||
}
|
||||
}
|
||||
return {
|
||||
visibleSessions,
|
||||
sessionsCursor,
|
||||
setSessionsCursor,
|
||||
showArchivedSessions,
|
||||
sessionMenuId,
|
||||
setSessionMenuId,
|
||||
pendingSessionDeletion,
|
||||
setPendingSessionDeletion,
|
||||
setSessionFullPrompt,
|
||||
updateSession,
|
||||
persistSession,
|
||||
ensureSessionMessages,
|
||||
|
||||
Reference in New Issue
Block a user