fix(editor): shape tool should be the last used shape (#12425)

Close [BS-3305](https://linear.app/affine-design/issue/BS-3305/白板按s应该使用上次的shape形状)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added a method to cycle through shape types when using the shape tool.

- **Bug Fixes**
  - Improved shape tool behavior to ensure the selected shape type does not change unexpectedly after adding a new shape.

- **Tests**
  - Added an end-to-end test to verify that the shape tool retains the selected shape type after adding a new shape.
  - Enhanced shortcut tests to verify cycling shapes forward and backward using 's' and 'Shift+s' keys.

- **Refactor**
  - Streamlined the logic for cycling through shape types and connector modes for improved maintainability.
  - Removed external utility for cycling shapes, integrating the functionality directly into the shape tool.
  - Updated keyboard shortcut handling to use the new cycling method within the shape tool.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
L-Sun
2025-05-23 16:31:01 +00:00
parent 3f753eddf5
commit 7223d35c89
8 changed files with 83 additions and 45 deletions
@@ -235,21 +235,18 @@ export class EdgelessToolbarShapeDraggable extends EdgelessToolbarToolMixin(
const locked = this.gfx.viewport.locked;
const selection = this.gfx.selection;
if (locked || selection.editing) return;
if (
this.gfx.tool.dragging$.peek() &&
this.gfx.tool.currentToolName$.peek() === 'shape'
) {
return;
}
const activeIndex = shapes.findIndex(
s => s.name === this.draggingShape
);
const nextIndex = (activeIndex + 1) % shapes.length;
const next = shapes[nextIndex];
this.draggingShape = next.name;
const currentTool = this.gfx.tool.currentToolName$.peek();
if (this.readyToDrop) {
if (currentTool === ShapeTool.toolName) {
const activeIndex = shapes.findIndex(
s => s.name === this.draggingShape
);
const nextIndex = (activeIndex + 1) % shapes.length;
const next = shapes[nextIndex];
this.draggingShape = next.name;
}
this.draggableController.cancelWithoutAnimation();
const el = this.shapeContainer.querySelector(
`.shape.${this.draggingShape}`
@@ -264,8 +261,14 @@ export class EdgelessToolbarShapeDraggable extends EdgelessToolbarToolMixin(
const clientPos = { x: x + left, y: y + top };
this.draggableController.dragAndMoveTo(el, clientPos);
} else {
if (this.gfx.tool.dragging$.peek()) return;
let shapeName =
this.gfx.tool.get(ShapeTool).activatedOption.shapeName;
if (currentTool === ShapeTool.toolName) {
shapeName = this.gfx.tool.get(ShapeTool).cycleShapeName('next');
}
this.setEdgelessTool(ShapeTool, {
shapeName: this.draggingShape,
shapeName,
});
}
},