fix(desktop): align H5 mobile composer and diff scrolling

H5 exposes the desktop chat surfaces in a much narrower viewport, so the empty-session composer needs the same inset treatment as active sessions and generated diff rows need intrinsic width instead of compressing long code into the phone viewport.

Constraint: Keep desktop layout and short diff-row backgrounds unchanged while enabling sideways scrolling on H5.
Rejected: Force wrapping long diff lines | it makes code harder to inspect and diverges from desktop diff behavior.
Confidence: high
Scope-risk: narrow
Directive: Keep workspace diff rows content-width driven when adjusting mobile code preview styling.
Tested: cd desktop && bun run test -- src/pages/EmptySession.test.tsx --run
Tested: cd desktop && bun run test -- src/components/workspace/WorkspacePanel.test.tsx --run
Tested: cd desktop && bun run lint
Not-tested: Full bun run verify gate; change is scoped to desktop UI styling and covered by narrow Vitest plus typecheck.
This commit is contained in:
程序员阿江(Relakkes) 2026-05-10 21:51:32 +08:00
parent bfe3c8b5e0
commit 6ae98a2f4e
4 changed files with 62 additions and 5 deletions

View File

@ -127,7 +127,7 @@ export function WorkspaceDiffSurface({
return (
<div
key={index}
className={`grid grid-cols-[48px_18px_minmax(0,1fr)] gap-2 px-3 ${
className={`grid min-w-full w-max grid-cols-[48px_18px_max-content] gap-2 px-3 ${
isAdded
? 'bg-[var(--color-diff-added-bg)]'
: isRemoved

View File

@ -763,6 +763,57 @@ describe('WorkspacePanel', () => {
expect(view.getByRole('button', { name: 'Collapse preview' })).toBeTruthy()
})
it('keeps diff rows intrinsically wide so H5 users can scroll sideways', async () => {
const longDiffLine = '+const label = "this is a very long generated line that should not be compressed into the phone viewport";'
await setWorkspaceState((state) => ({
...state,
panelBySession: {
...state.panelBySession,
'session-wide-diff': {
isOpen: true,
activeView: 'changed',
hasUserSelectedView: true,
},
},
statusBySession: {
...state.statusBySession,
'session-wide-diff': {
state: 'ok',
workDir: '/repo',
repoName: 'repo',
branch: 'main',
isGitRepo: true,
changedFiles: [],
},
},
previewTabsBySession: {
...state.previewTabsBySession,
'session-wide-diff': [{
id: 'diff:wide.ts',
path: 'wide.ts',
kind: 'diff',
title: 'wide.ts',
diff: longDiffLine,
state: 'ok',
}],
},
activePreviewTabIdBySession: {
...state.activePreviewTabIdBySession,
'session-wide-diff': 'diff:wide.ts',
},
}))
const view = await renderPanel('session-wide-diff')
const diffSurface = view.getByTestId('workspace-code')
const firstRow = diffSurface.querySelector('div')
expect(firstRow?.className).toContain('w-max')
expect(firstRow?.className).toContain('min-w-full')
expect(firstRow?.className).toContain('grid-cols-[48px_18px_max-content]')
expect(diffSurface.textContent).toContain(longDiffLine)
})
it('can expand long file previews beyond the default rendered line cap', async () => {
const longFile = Array.from({ length: 2300 }, (_, index) => `const line${index + 1} = ${index + 1}`).join('\n')

View File

@ -194,6 +194,8 @@ describe('EmptySession', () => {
})
expect(screen.getByTestId('model-selector')).toHaveAttribute('data-compact', 'true')
expect(screen.getByRole('button', { name: 'Run' })).toHaveClass('h-11', 'w-11')
expect(screen.getByTestId('empty-session-composer-shell')).toHaveClass('px-3')
expect(screen.getByTestId('empty-session-composer-panel')).toHaveClass('rounded-2xl')
})
it('creates a session with the selected project and branch when submitted', async () => {

View File

@ -541,15 +541,19 @@ export function EmptySession() {
</div>
</div>
<div className={`absolute left-0 right-0 z-30 flex justify-center ${
<div
data-testid="empty-session-composer-shell"
className={`absolute left-0 right-0 z-30 flex justify-center ${
isMobileComposer
? 'bottom-0 px-0 pb-0'
? 'bottom-0 px-3 pb-[calc(env(safe-area-inset-bottom)+10px)]'
: 'bottom-4 px-8'
}`}>
}`}
>
<div className={`flex w-full flex-col ${isMobileComposer ? 'max-w-none' : 'max-w-3xl'}`}>
<div
data-testid="empty-session-composer-panel"
className={`glass-panel relative flex flex-col gap-3 ${
isMobileComposer ? 'rounded-t-2xl rounded-b-none p-3 shadow-[0_-12px_36px_rgba(54,35,28,0.12)]' : 'rounded-t-xl rounded-b-none p-4'
isMobileComposer ? 'rounded-2xl p-3 shadow-[0_-12px_36px_rgba(54,35,28,0.12)]' : 'rounded-t-xl rounded-b-none p-4'
}`}
onDragOver={(event) => event.preventDefault()}
onDrop={handleDrop}