From b59bc37f2f7e22539c2cc71fb6cdae953b331cb1 Mon Sep 17 00:00:00 2001 From: Haitao Pan Date: Wed, 25 Mar 2026 18:26:09 +0800 Subject: [PATCH] Fix assistant artifact toggle overlap --- lib/features/assistant/assistant_page.dart | 12 ++++++-- lib/widgets/assistant_artifact_sidebar.dart | 5 ++- test/features/assistant_page_suite.dart | 34 ++++++++++++++++++++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/lib/features/assistant/assistant_page.dart b/lib/features/assistant/assistant_page.dart index 8e689a3c..4a702d2e 100644 --- a/lib/features/assistant/assistant_page.dart +++ b/lib/features/assistant/assistant_page.dart @@ -34,6 +34,7 @@ const double _assistantHorizontalPaneGap = 2; const double _assistantVerticalResizeHandleHeight = 10; const double _assistantArtifactPaneMinWidth = 280; const double _assistantArtifactPaneDefaultWidth = 360; +const double _assistantCollapsedArtifactToggleClearance = 56; typedef AssistantClipboardImageReader = Future Function(); @@ -446,6 +447,9 @@ class _AssistantPageState extends State { currentTask: currentTask, items: timelineItems, messageViewMode: controller.currentAssistantMessageViewMode, + topTrailingInset: _artifactPaneCollapsed + ? _assistantCollapsedArtifactToggleClearance + : 0, scrollController: _conversationController, onOpenDetail: widget.onOpenDetail, onFocusComposer: _focusComposer, @@ -605,8 +609,8 @@ class _AssistantPageState extends State { Positioned.fill(child: panel), if (_artifactPaneCollapsed) Positioned( - right: AppSpacing.sm, - top: AppSpacing.lg, + right: 0, + top: 0, child: AssistantArtifactSidebarRevealButton( onTap: () { setState(() { @@ -1819,6 +1823,7 @@ class _ConversationArea extends StatelessWidget { required this.currentTask, required this.items, required this.messageViewMode, + required this.topTrailingInset, required this.scrollController, required this.onOpenDetail, required this.onFocusComposer, @@ -1832,6 +1837,7 @@ class _ConversationArea extends StatelessWidget { final _AssistantTaskEntry currentTask; final List<_TimelineItem> items; final AssistantMessageViewMode messageViewMode; + final double topTrailingInset; final ScrollController scrollController; final ValueChanged onOpenDetail; final VoidCallback onFocusComposer; @@ -1852,7 +1858,7 @@ class _ConversationArea extends StatelessWidget { child: Column( children: [ Padding( - padding: const EdgeInsets.fromLTRB(10, 8, 10, 8), + padding: EdgeInsets.fromLTRB(10, 8, 10 + topTrailingInset, 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/widgets/assistant_artifact_sidebar.dart b/lib/widgets/assistant_artifact_sidebar.dart index 13f48712..308c5b16 100644 --- a/lib/widgets/assistant_artifact_sidebar.dart +++ b/lib/widgets/assistant_artifact_sidebar.dart @@ -425,7 +425,10 @@ class AssistantArtifactSidebarRevealButton extends StatelessWidget { ], ), borderRadius: BorderRadius.circular(AppRadius.sidebar), - border: Border.all(color: palette.chromeStroke), + border: Border.all( + color: palette.chromeStroke.withValues(alpha: 0.88), + width: 0.9, + ), boxShadow: [palette.chromeShadowAmbient], ), child: Icon( diff --git a/test/features/assistant_page_suite.dart b/test/features/assistant_page_suite.dart index ae5453b0..53b9cbf5 100644 --- a/test/features/assistant_page_suite.dart +++ b/test/features/assistant_page_suite.dart @@ -266,6 +266,36 @@ void main() { expect(find.byKey(const Key('assistant-artifact-pane')), findsNothing); }); + testWidgets( + 'AssistantPage keeps the collapsed artifact toggle clear of top toolbar controls', + (WidgetTester tester) async { + final controller = await createTestController(tester); + + await pumpPage( + tester, + child: AssistantPage(controller: controller, onOpenDetail: (_) {}), + platform: TargetPlatform.macOS, + ); + + final toggle = find.byKey(const Key('assistant-artifact-pane-toggle')); + final viewMode = find.byKey( + const Key('assistant-message-view-mode-button'), + ); + final connectionChip = find.byKey(const Key('assistant-connection-chip')); + + expect(toggle, findsOneWidget); + expect(viewMode, findsOneWidget); + expect(connectionChip, findsOneWidget); + + final toggleRect = tester.getRect(toggle); + final viewModeRect = tester.getRect(viewMode); + final connectionRect = tester.getRect(connectionChip); + + expect(toggleRect.overlaps(viewModeRect), isFalse); + expect(toggleRect.overlaps(connectionRect), isFalse); + }, + ); + testWidgets( 'AssistantPage shows Single Agent provider selector on the right', (WidgetTester tester) async {}, @@ -567,7 +597,9 @@ void main() { await _waitForCondition( () => controller - .assistantImportedSkillsForSession(controller.currentSessionKey) + .assistantImportedSkillsForSession( + controller.currentSessionKey, + ) .length == 3, );