refactor(home): 校正面 15 个状态从 Home 下沉
Home() useState 66->52, useRef 41->39. Shell-facing fields merge into one object; subtree state lives in useRectificationSurface. Chat props 20->7. Growth contract rebaselined. Zero behavior/copy change.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import type { Dispatch, MutableRefObject, SetStateAction } from "react";
|
||||
import { useEffect, useRef, useState, type Dispatch, type MutableRefObject, type SetStateAction } from "react";
|
||||
|
||||
import { resolveSessionTitle } from "@/lib/agent-reply";
|
||||
import { rectificationOpenIdentity } from "@/lib/rectification-session-open";
|
||||
@@ -27,7 +27,10 @@ import {
|
||||
openResponseFromPayload,
|
||||
type RectificationEntrySummary,
|
||||
} from "@/lib/rectification-entry";
|
||||
import type { PersistedRectificationTurn } from "@/components/conversational-birth-time-rectification";
|
||||
import type {
|
||||
PersistedRectificationTurn,
|
||||
RectificationChatPanel,
|
||||
} from "@/components/conversational-birth-time-rectification";
|
||||
import type { PublicLanguageModelCatalog } from "@/lib/public-models";
|
||||
import {
|
||||
hydrateRectificationCase,
|
||||
@@ -38,6 +41,60 @@ import {
|
||||
type RectificationCaseSnapshotPayload,
|
||||
} from "@/lib/rectification-surface-state";
|
||||
|
||||
export type RectificationShellState = {
|
||||
sessionId: string | null;
|
||||
caseId: string | null;
|
||||
openingSessionId: string | null;
|
||||
loading: boolean;
|
||||
mutationPending: boolean;
|
||||
entrySummary: RectificationEntrySummary | null;
|
||||
entrySummarySettled: boolean;
|
||||
error: string;
|
||||
errorSessionId: string | null;
|
||||
};
|
||||
|
||||
export const EMPTY_RECTIFICATION_SHELL: RectificationShellState = {
|
||||
sessionId: null,
|
||||
caseId: null,
|
||||
openingSessionId: null,
|
||||
loading: false,
|
||||
mutationPending: false,
|
||||
entrySummary: null,
|
||||
entrySummarySettled: false,
|
||||
error: "",
|
||||
errorSessionId: null,
|
||||
};
|
||||
|
||||
function fieldSetter<K extends keyof RectificationShellState>(
|
||||
setRectification: Dispatch<SetStateAction<RectificationShellState>>,
|
||||
key: K,
|
||||
): Dispatch<SetStateAction<RectificationShellState[K]>> {
|
||||
return (value) => {
|
||||
setRectification((current) => ({
|
||||
...current,
|
||||
[key]: typeof value === "function"
|
||||
? (value as (prev: RectificationShellState[K]) => RectificationShellState[K])(current[key])
|
||||
: value,
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
export function createRectificationShellSetters(
|
||||
setRectification: Dispatch<SetStateAction<RectificationShellState>>,
|
||||
) {
|
||||
return {
|
||||
setRectificationSessionId: fieldSetter(setRectification, "sessionId"),
|
||||
setRectificationCaseId: fieldSetter(setRectification, "caseId"),
|
||||
setRectificationOpeningSessionId: fieldSetter(setRectification, "openingSessionId"),
|
||||
setRectificationLoading: fieldSetter(setRectification, "loading"),
|
||||
setRectificationMutationPending: fieldSetter(setRectification, "mutationPending"),
|
||||
setRectificationEntrySummary: fieldSetter(setRectification, "entrySummary"),
|
||||
setRectificationEntrySummarySettled: fieldSetter(setRectification, "entrySummarySettled"),
|
||||
setRectificationError: fieldSetter(setRectification, "error"),
|
||||
setRectificationErrorSessionId: fieldSetter(setRectification, "errorSessionId"),
|
||||
};
|
||||
}
|
||||
|
||||
export type RectificationSurfaceParams = {
|
||||
account: Account | null;
|
||||
activeChartId: string;
|
||||
@@ -47,11 +104,8 @@ export type RectificationSurfaceParams = {
|
||||
modelCatalog: PublicLanguageModelCatalog | null;
|
||||
persistSession: (session: ChatSession, mode?: "create" | "update") => Promise<void>;
|
||||
profile: Profile;
|
||||
rectificationLoading: boolean;
|
||||
rectificationMutationPending: boolean;
|
||||
rectificationOpenInFlight: MutableRefObject<boolean>;
|
||||
rectificationSessionId: string | null;
|
||||
resumeRectificationSession: MutableRefObject<(session: ChatSession) => void>;
|
||||
rectification: RectificationShellState;
|
||||
setRectification: Dispatch<SetStateAction<RectificationShellState>>;
|
||||
sessionSelectionSource: MutableRefObject<"user" | "history">;
|
||||
sessions: ChatSession[];
|
||||
setActiveSessionId: Dispatch<SetStateAction<string>>;
|
||||
@@ -60,18 +114,6 @@ export type RectificationSurfaceParams = {
|
||||
setDraftTheme: (theme: Theme | null) => void;
|
||||
setOnboardingStep: Dispatch<SetStateAction<OnboardingStep>>;
|
||||
setProfileNotice: Dispatch<SetStateAction<string>>;
|
||||
setRectificationCaseId: Dispatch<SetStateAction<string | null>>;
|
||||
setRectificationEntrySummary: Dispatch<SetStateAction<RectificationEntrySummary | null>>;
|
||||
setRectificationError: Dispatch<SetStateAction<string>>;
|
||||
setRectificationErrorSessionId: Dispatch<SetStateAction<string | null>>;
|
||||
setRectificationLoading: Dispatch<SetStateAction<boolean>>;
|
||||
setRectificationPendingQuestion: Dispatch<SetStateAction<string | null>>;
|
||||
setRectificationReadonly: Dispatch<SetStateAction<boolean>>;
|
||||
setRectificationSessionId: Dispatch<SetStateAction<string | null>>;
|
||||
setRectificationShouldStartOpening: Dispatch<SetStateAction<boolean>>;
|
||||
setRectificationSnapshot: Dispatch<SetStateAction<RectificationCaseSnapshotPayload | null>>;
|
||||
setRectificationOpeningSessionId: Dispatch<SetStateAction<string | null>>;
|
||||
setRectificationTurns: Dispatch<SetStateAction<PersistedRectificationTurn[]>>;
|
||||
setSessions: Dispatch<SetStateAction<ChatSession[]>>;
|
||||
uiPreview: MutableRefObject<boolean>;
|
||||
updateSession: (sessionId: string, change: (session: ChatSession) => ChatSession) => void;
|
||||
@@ -90,11 +132,8 @@ export function useRectificationSurface(params: RectificationSurfaceParams) {
|
||||
modelCatalog,
|
||||
persistSession,
|
||||
profile,
|
||||
rectificationLoading,
|
||||
rectificationMutationPending,
|
||||
rectificationOpenInFlight,
|
||||
rectificationSessionId,
|
||||
resumeRectificationSession,
|
||||
rectification,
|
||||
setRectification,
|
||||
sessionSelectionSource,
|
||||
sessions,
|
||||
setActiveSessionId,
|
||||
@@ -103,18 +142,6 @@ export function useRectificationSurface(params: RectificationSurfaceParams) {
|
||||
setDraftTheme,
|
||||
setOnboardingStep,
|
||||
setProfileNotice,
|
||||
setRectificationCaseId,
|
||||
setRectificationEntrySummary,
|
||||
setRectificationError,
|
||||
setRectificationErrorSessionId,
|
||||
setRectificationLoading,
|
||||
setRectificationPendingQuestion,
|
||||
setRectificationReadonly,
|
||||
setRectificationSessionId,
|
||||
setRectificationShouldStartOpening,
|
||||
setRectificationSnapshot,
|
||||
setRectificationOpeningSessionId,
|
||||
setRectificationTurns,
|
||||
setSessions,
|
||||
uiPreview,
|
||||
updateSession,
|
||||
@@ -123,6 +150,29 @@ export function useRectificationSurface(params: RectificationSurfaceParams) {
|
||||
rectificationSessionOpenerRef,
|
||||
} = params;
|
||||
|
||||
const rectificationSessionId = rectification.sessionId;
|
||||
const rectificationCaseId = rectification.caseId;
|
||||
const rectificationLoading = rectification.loading;
|
||||
const rectificationMutationPending = rectification.mutationPending;
|
||||
|
||||
const setRectificationSessionId = fieldSetter(setRectification, "sessionId");
|
||||
const setRectificationCaseId = fieldSetter(setRectification, "caseId");
|
||||
const setRectificationOpeningSessionId = fieldSetter(setRectification, "openingSessionId");
|
||||
const setRectificationLoading = fieldSetter(setRectification, "loading");
|
||||
const setRectificationMutationPending = fieldSetter(setRectification, "mutationPending");
|
||||
const setRectificationEntrySummary = fieldSetter(setRectification, "entrySummary");
|
||||
const setRectificationError = fieldSetter(setRectification, "error");
|
||||
const setRectificationErrorSessionId = fieldSetter(setRectification, "errorSessionId");
|
||||
|
||||
const [rectificationHeaderSlot, setRectificationHeaderSlot] = useState<HTMLElement | null>(null);
|
||||
const [rectificationPendingQuestion, setRectificationPendingQuestion] = useState<string | null>(null);
|
||||
const [rectificationReadonly, setRectificationReadonly] = useState(false);
|
||||
const [rectificationShouldStartOpening, setRectificationShouldStartOpening] = useState(false);
|
||||
const [rectificationTurns, setRectificationTurns] = useState<PersistedRectificationTurn[]>([]);
|
||||
const [rectificationSnapshot, setRectificationSnapshot] = useState<RectificationCaseSnapshotPayload | null>(null);
|
||||
const rectificationOpenInFlight = useRef(false);
|
||||
const resumeRectificationSession = useRef<(session: ChatSession) => void>(() => undefined);
|
||||
|
||||
async function refreshRectificationEntrySummary() {
|
||||
if (!account) return;
|
||||
try {
|
||||
@@ -289,12 +339,6 @@ export function useRectificationSurface(params: RectificationSurfaceParams) {
|
||||
await openRectificationCase("new", null, null);
|
||||
}
|
||||
|
||||
resumeRectificationSession.current = (session) => {
|
||||
sessionSelectionSource.current = "history";
|
||||
void openRectificationSession(session.id);
|
||||
};
|
||||
rectificationSessionOpenerRef.current = openRectificationSession;
|
||||
|
||||
function handleRectificationProfileIncomplete() {
|
||||
setRectificationError("profile_incomplete");
|
||||
setRectificationSessionId(null);
|
||||
@@ -320,7 +364,41 @@ export function useRectificationSurface(params: RectificationSurfaceParams) {
|
||||
}));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
resumeRectificationSession.current = (session) => {
|
||||
sessionSelectionSource.current = "history";
|
||||
void openRectificationSession(session.id);
|
||||
};
|
||||
rectificationSessionOpenerRef.current = openRectificationSession;
|
||||
});
|
||||
|
||||
const rectificationPanel: RectificationChatPanel = {
|
||||
caseId: rectificationCaseId ?? "",
|
||||
sessionId: rectificationSessionId ?? "",
|
||||
readonly: rectificationReadonly,
|
||||
shouldStartOpening: rectificationShouldStartOpening,
|
||||
initialTurns: rectificationTurns,
|
||||
initialSnapshot: rectificationSnapshot,
|
||||
pendingConsultationQuestion: rectificationPendingQuestion,
|
||||
headerSlot: rectificationHeaderSlot,
|
||||
onMessagesChange: handleRectificationMessagesChange,
|
||||
onCompleted: () => {
|
||||
void refreshAccount();
|
||||
if (rectificationCaseId && rectificationSessionId) {
|
||||
void refreshRectificationCase(rectificationCaseId, rectificationSessionId);
|
||||
}
|
||||
},
|
||||
onPendingChange: setRectificationMutationPending,
|
||||
onProfileIncomplete: handleRectificationProfileIncomplete,
|
||||
onOpeningConsumed: () => setRectificationShouldStartOpening(false),
|
||||
onRestart: () => void startNewRectification(),
|
||||
};
|
||||
|
||||
return {
|
||||
rectificationHeaderSlot,
|
||||
setRectificationHeaderSlot,
|
||||
rectificationPanel,
|
||||
resumeRectificationSession,
|
||||
refreshRectificationEntrySummary,
|
||||
refreshRectificationCase,
|
||||
openRectificationCase,
|
||||
|
||||
Reference in New Issue
Block a user