fix: keep the welcome composer at the bottom

This commit is contained in:
鲨鱼辣椒
2026-09-29 15:50:43 +08:00
parent f8a7880da3
commit e812371973
8 changed files with 46 additions and 18 deletions

View File

@@ -65,10 +65,27 @@ for (const width of [375, 768, 1280, 1470]) {
await expect(page.getByRole('button', { name: '去作品广场逛逛' })).toBeVisible();
await teachers.getByRole('button', { name: '先自己试试' }).click();
await heading.scrollIntoViewIfNeeded();
const composer = page.getByTestId('coding-message-composer');
await expect(composer).toBeInViewport({ ratio: 1 });
const box = (await composer.boundingBox())!;
expect(850 - box.y - box.height).toBeLessThanOrEqual(40);
expect((await page.getByTestId('community-invitation').boundingBox())!.y).toBeLessThan(box.y);
await page.screenshot({ path: test.info().outputPath(`community-welcome-${width}.png`) });
});
}
test('a short window scrolls the welcome while keeping the composer at the bottom', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 600 });
await page.goto(baseUrl + '?teachers');
const composer = page.getByTestId('coding-message-composer');
await expect(composer).toBeInViewport({ ratio: 1 });
const before = (await composer.boundingBox())!;
await page.getByTestId('community-invitation').scrollIntoViewIfNeeded();
const after = (await composer.boundingBox())!;
expect(after.y).toBeCloseTo(before.y, 0);
expect(600 - after.y - after.height).toBeLessThanOrEqual(40);
});
test('the community link opens only on click and leaves the draft mounted', async ({ page }) => {
await page.setViewportSize({ width: 1280, height: 850 });
const communityRequests: string[] = [];

View File

@@ -35,7 +35,7 @@ export function Layout() {
<main className="classroom-main flex min-h-0 min-w-0 flex-1 flex-col">
<div className="classroom-tabs" role="tablist"><button role="tab" aria-selected="true">操作对话</button><button role="tab">作品</button></div>
<CodingChatBody welcome={!sent} hidden={false} bubble={bubble}>
<div className="classroom-chat-view min-h-0 flex-1">{!sent ? <CodingStartHeading /> : <p>第一条消息已发送(测试)</p>}</div>
<div className="classroom-chat-view min-h-0 flex-1 flex-col">{!sent ? <><CodingStartHeading /><CommunityInvitation /></> : <p>第一条消息已发送(测试)</p>}</div>
<div className="classroom-composer-view shrink-0">
<CodingComposer value={draft} editable canSend={Boolean(draft)} preparing={false} recovering={false}
runStatus="idle" mode="prompt" queue={{ items: [] }} error={null} recoverableError={false}
@@ -43,7 +43,6 @@ export function Layout() {
onModeChange={() => {}} onSubmit={() => { setSent(true); setDraft(''); }} onRecover={() => {}}
onAddFiles={() => {}} onRemoveAttachment={() => {}} />
</div>
{!sent && <CommunityInvitation />}
</CodingChatBody>
</main>
</div>;

View File

@@ -1110,6 +1110,9 @@ test('first PI Conversation is editable under 500 ms and submits before runtime
await appendFile(performanceFragment, `${JSON.stringify({ editableMs })}\n`);
}
await expect(page.getByTestId('coding-message-composer')).toBeInViewport({ ratio: 1 });
expect(await page.getByTestId('coding-message-composer').evaluate(el => innerHeight - el.getBoundingClientRect().bottom)).toBeLessThan(40);
const pixelPng = Buffer.from(
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=',
'base64',