Merge pull request #35 from jesse-ux/codex/rectification-composer-height

Fix rectification composer layout
This commit is contained in:
jesse-ux
2026-07-27 23:36:20 +08:00
committed by GitHub
4 changed files with 35 additions and 27 deletions
-3
View File
@@ -840,9 +840,6 @@ input:disabled, select:disabled { color: var(--color-ink-tertiary); background:
.conversational-composer-footer button, .conversational-confirmation button, .conversational-original-question button { width: 100%; }
}
/* Rectification reuses the ordinary session message list and composer. */
.rectification-chat { display: contents; }
/* Starter workbench */
.welcome {
width: min(1040px, 100%);
+18 -15
View File
@@ -2841,8 +2841,9 @@ export default function Home() {
</button>
</header>
<div className={`conversation ${rectificationSurfaceOpen || activeSession?.messages.length ? "" : "is-empty"}`}>
{!rectificationSurfaceOpen && (!activeSession?.messages.length ? (
{!rectificationSurfaceOpen && (
<div className={`conversation ${activeSession?.messages.length ? "" : "is-empty"}`}>
{!activeSession?.messages.length ? (
<div className="welcome">
{!profileComplete ? (
<>
@@ -3024,19 +3025,21 @@ export default function Home() {
{activeError && <p className="error-message">{activeError}</p>}
<div ref={conversationEnd} />
</div>
))}
{rectificationSurfaceOpen && (
<ConversationalBirthTimeRectification
models={modelCatalog?.models ?? []}
selectedModelId={activeSession?.modelId ?? ""}
onSelectModel={(modelId) => void selectSessionModel(modelId)}
pendingConsultationQuestion={rectificationPendingQuestion}
continuationPending={rectificationContinuationPending}
onPendingChange={setRectificationMutationPending}
onContinueOriginalQuestion={(continuation) => void continueRectificationOriginalQuestion(continuation)}
/>
)}
</div>
)}
</div>
)}
{rectificationSurfaceOpen && (
<ConversationalBirthTimeRectification
models={modelCatalog?.models ?? []}
selectedModelId={activeSession?.modelId ?? ""}
onSelectModel={(modelId) => void selectSessionModel(modelId)}
pendingConsultationQuestion={rectificationPendingQuestion}
continuationPending={rectificationContinuationPending}
onPendingChange={setRectificationMutationPending}
onContinueOriginalQuestion={(continuation) => void continueRectificationOriginalQuestion(continuation)}
/>
)}
{!rectificationSurfaceOpen && <div className={`composer-wrap ${starterHomeVisible ? "composer-wrap-starter" : ""}`}>
{activeSuggestions.length > 0 && (
@@ -186,12 +186,14 @@ export function RectificationV4Panel(props: RectificationV4PanelProps) {
}
return (
<section className="rectification-chat" aria-label="生时校正对话" aria-busy={processing || controller.pending}>
<div className="message-list" aria-live="polite">
{messages.map((message) => <ChatMessageRow key={message.renderKey} message={message} />)}
{controller.error && <p className="error-message" role="alert">{controller.error}</p>}
<div ref={conversationEnd} />
</div>
<>
<section className="conversation" aria-label="生时校正对话" aria-busy={processing || controller.pending}>
<div className="message-list" aria-live="polite">
{messages.map((message) => <ChatMessageRow key={message.renderKey} message={message} />)}
{controller.error && <p className="error-message" role="alert">{controller.error}</p>}
<div ref={conversationEnd} />
</div>
</section>
{showControls && (
<div className="composer-wrap">
@@ -247,6 +249,6 @@ export function RectificationV4Panel(props: RectificationV4PanelProps) {
</div>
</div>
)}
</section>
</>
);
}
@@ -68,6 +68,10 @@ test("v4 rectification reuses the ordinary session message list, composer, and m
const page = readFileSync(new URL("../src/app/page.tsx", import.meta.url), "utf8");
const css = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
assert.match(
component,
/<>\s*<section className="conversation"[\s\S]*?<\/section>\s*\{showControls && \(\s*<div className="composer-wrap"/,
);
assert.match(component, /className="message-list"/);
assert.match(component, /<ChatMessageRow/);
assert.match(component, /className="composer-wrap"/);
@@ -76,9 +80,11 @@ test("v4 rectification reuses the ordinary session message list, composer, and m
assert.match(component, /<ModelSelector/);
assert.match(component, /controller\.answer\(answer, props\.selectedModelId \|\| null\)/);
assert.match(wrapper, /<RectificationV4Panel \{\.\.\.props\} \/>/);
assert.match(page, /rectificationSurfaceOpen \|\| activeSession\?\.messages\.length/);
assert.match(page, /\{!rectificationSurfaceOpen && \(\s*<div className=\{`conversation/);
assert.match(page, /\{rectificationSurfaceOpen && \(\s*<ConversationalBirthTimeRectification/);
assert.doesNotMatch(page, /is-rectification/);
assert.match(css, /\.rectification-chat \{ display: contents; \}/);
assert.doesNotMatch(component, /rectification-chat/);
assert.doesNotMatch(css, /\.rectification-chat/);
});
test("turn history and the context-aware next question render as one chat timeline", () => {