From aa20e7ba66904ec194ef8843a80cb6cf1a35c016 Mon Sep 17 00:00:00 2001 From: Wu Yue Date: Mon, 11 Aug 2025 23:52:50 +0800 Subject: [PATCH] fix(core): copilot tool restore (#13470) Close [AI-410](https://linear.app/affine-design/issue/AI-410) ## Summary by CodeRabbit - New Features - None - Bug Fixes - Middle-click panning now reliably returns to the previously active tool, including after using Copilot or frame navigation. - Smoother, more responsive transition into panning to reduce accidental selections. - Refactor - Simplified AI panel click-outside handling with no change to user-visible behavior. --- .../affine/gfx/pointer/src/tools/pan-tool.ts | 20 +++++++++++++------ .../ai/widgets/ai-panel/ai-panel.ts | 3 --- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/blocksuite/affine/gfx/pointer/src/tools/pan-tool.ts b/blocksuite/affine/gfx/pointer/src/tools/pan-tool.ts index 3de276c84..345011327 100644 --- a/blocksuite/affine/gfx/pointer/src/tools/pan-tool.ts +++ b/blocksuite/affine/gfx/pointer/src/tools/pan-tool.ts @@ -1,4 +1,7 @@ -import { EdgelessLegacySlotIdentifier } from '@blocksuite/affine-block-surface'; +import { + DefaultTool, + EdgelessLegacySlotIdentifier, +} from '@blocksuite/affine-block-surface'; import { on } from '@blocksuite/affine-shared/utils'; import type { PointerEventState } from '@blocksuite/std'; import { BaseTool, MouseButton, type ToolOptions } from '@blocksuite/std/gfx'; @@ -64,12 +67,15 @@ export class PanTool extends BaseTool { const { toolType, options: originalToolOptions } = currentTool; const selectionToRestore = this.gfx.selection.surfaceSelections; if (!toolType) return; + // restore to DefaultTool if previous tool is CopilotTool + if (toolType.toolName === 'copilot') { + this.controller.setTool(DefaultTool); + return; + } let finalOptions: ToolOptions> | undefined = originalToolOptions; - const PRESENT_TOOL_NAME = 'frameNavigator'; - - if (toolType.toolName === PRESENT_TOOL_NAME) { + if (toolType.toolName === 'frameNavigator') { // When restoring PresentTool (frameNavigator) after a temporary pan (e.g., via middle mouse button), // set 'restoredAfterPan' to true. This allows PresentTool to avoid an unwanted viewport reset // and maintain the panned position. @@ -93,8 +99,10 @@ export class PanTool extends BaseTool { }); } - this.controller.setTool(PanTool, { - panning: true, + requestAnimationFrame(() => { + this.controller.setTool(PanTool, { + panning: true, + }); }); const dispose = on(document, 'pointerup', evt => { diff --git a/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/ai-panel.ts b/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/ai-panel.ts index 7f014b51e..7c2b3cb3e 100644 --- a/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/ai-panel.ts +++ b/packages/frontend/core/src/blocksuite/ai/widgets/ai-panel/ai-panel.ts @@ -141,10 +141,7 @@ export class AffineAIPanelWidget extends WidgetComponent { !this.contains(e.target as Node) ) { this._clickOutside(); - return true; } - - return false; }; private readonly _onKeyDown = (event: KeyboardEvent) => {