Add keyboard shortcuts, history management, alignment tools, export dialog, and prompt suggestions#5
Conversation
…port dialog, and prompt suggestions - Add useKeyboardShortcuts hook with 50+ shortcuts for editing, navigation, and tools - Add useHistory hook for undo/redo and generation history tracking - Add KeyboardShortcutsDialog component with search and category filtering - Add HistoryPanel for viewing action and generation history - Add AlignmentTools for multi-element alignment and distribution - Add PromptSuggestions with categories, search, and saved prompts - Add ExportDialog with multiple formats, presets, and quality options - Add clipboard utilities for copy/paste/duplicate operations - Add canvas-utils with snap guides, bounding box, and color utilities
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
/review |
|
/describe --comment |
|
/label |
|
/describe |
There was a problem hiding this comment.
🌗 Pull request overview
This PR adds comprehensive design tools for a canvas-based editor including clipboard operations,
history management, alignment utilities, export functionality, keyboard shortcuts, and prompt
suggestions. The implementation appears well-structured with proper separation of concerns.
Reviewed changes
Kimi reviewed 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/lib/clipboard.ts |
Clipboard operations with system fallback, element duplication, style copying, and image paste support |
src/lib/canvas-utils.ts |
Canvas utility functions for geometry, alignment, snapping, color manipulation, and animation |
src/components/lovart/ExportDialog.tsx |
Export dialog component with multiple format support, presets, and customizable options |
src/components/lovart/HistoryPanel.tsx |
New file (typescript) |
src/components/lovart/KeyboardShortcutsDialog.tsx |
New file (typescript) |
src/components/lovart/PromptSuggestions.tsx |
New file (typescript) |
src/hooks/useKeyboardShortcuts.ts |
Comprehensive keyboard shortcut system with platform-specific handling |
src/components/lovart/AlignmentTools.tsx |
New file (typescript) |
src/hooks/useHistory.ts |
History management hooks for canvas undo/redo and AI generation history tracking |
Issues found:
- 🟡
src/lib/clipboard.ts: [P2] Missing error handling for malformed clipboard data - 🟡
src/hooks/useKeyboardShortcuts.ts: [P2] Platform detection runs after initial render - 🟡
src/lib/clipboard.ts: [P2] Deep copy may fail for complex nested objects
Powered by Kimi | Model: kimi-k2-turbo-preview
| */ | ||
| export function duplicateElements( | ||
| elements: CanvasElement[], | ||
| offset: { x: number; y: number } = { x: PASTE_OFFSET, y: PASTE_OFFSET } | ||
| ): CanvasElement[] { |
There was a problem hiding this comment.
JSON.parse will throw an error if the clipboard contains invalid JSON. This could happen with
non-Lovart clipboard content. Wrap the parse in a try-catch block to gracefully handle malformed
data and fall back to internal clipboard.
| */ | |
| export function duplicateElements( | |
| elements: CanvasElement[], | |
| offset: { x: number; y: number } = { x: PASTE_OFFSET, y: PASTE_OFFSET } | |
| ): CanvasElement[] { | |
| try { | |
| const parsed = JSON.parse(text); | |
| if (parsed.type === 'lovart-elements') { | |
| clipboardData = parsed; | |
| } | |
| } catch (e) { | |
| // Invalid JSON, continue to internal clipboard | |
| } |
Powered by Kimi | Model: kimi-k2-turbo-preview
There was a problem hiding this comment.
🌗 Kimi Answer
这段代码定义了一个函数 duplicateElements,用来**原地复制(duplicate)**画布上的元素。
- 参数
elements是要被复制的元素列表; - 参数
offset控制新元素相对于原位置的偏移量,默认向右下各移动 20 像素(PASTE_OFFSET的值); - 函数会给每个元素生成全新的
id(uuidv4()),然后把它们的x、y坐标加上偏移量,返回一份“复制体”列表。
简单说:把选中的元素各复制一份,并稍微错开一点位置,避免完全重叠。
Powered by Kimi | Model: kimi-k2-turbo-preview
There was a problem hiding this comment.
🌗 Kimi Answer
这段代码定义了一个“就地复制”函数:它会把你选中的所有元素直接复制一份到当前画布上,并且在 X、Y 方向各偏移 20 像素,避免新元素完全盖住原元素。复制出的每个元素都会重新生成一个唯一 ID,防止 ID 冲突。
Powered by Kimi | Model: kimi-k2-turbo-preview
|
|
||
| // Format special keys | ||
| let keyDisplay = shortcut.key; | ||
| switch (shortcut.key) { | ||
| case 'ArrowUp': keyDisplay = '↑'; break; | ||
| case 'ArrowDown': keyDisplay = '↓'; break; |
There was a problem hiding this comment.
The isMac detection runs in useEffect, which executes after the first render. This means
shortcuts won't work correctly on the initial render cycle. Move platform detection to
module level or use a synchronous check.
| // Format special keys | |
| let keyDisplay = shortcut.key; | |
| switch (shortcut.key) { | |
| case 'ArrowUp': keyDisplay = '↑'; break; | |
| case 'ArrowDown': keyDisplay = '↓'; break; | |
| const isMac = useRef(typeof navigator !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.platform)); |
Powered by Kimi | Model: kimi-k2-turbo-preview
| */ | ||
| export async function copyElements(elements: CanvasElement[]): Promise<boolean> { | ||
| if (elements.length === 0) return false; | ||
|
|
||
| const clipboardData: ClipboardData = { |
There was a problem hiding this comment.
The spread operator only performs a shallow copy. If CanvasElement contains nested objects or arrays,
they will be shared between copies. This could cause mutations to affect both original and copied
elements. Consider using a proper deep clone method or structuredClone for complex objects.
| */ | |
| export async function copyElements(elements: CanvasElement[]): Promise<boolean> { | |
| if (elements.length === 0) return false; | |
| const clipboardData: ClipboardData = { | |
| elements: elements.map(el => structuredClone(el)), // Deep copy |
Powered by Kimi | Model: kimi-k2-turbo-preview
🌗 Kimi PR DescriptionSuggested TitleAdd keyboard shortcuts, history management, alignment tools, export dialog Suggested Description✨ FeatureBackgroundThe Lovart design tool lacked essential productivity features common in professional design applications. Users needed better ways to navigate, manage their work history, align elements precisely, and export their designs in various formats. Changes
Impact
📁 Changed Files
Powered by Kimi | Model: |
🏷️ Kimi Labels✅ Applied labels: Reason: Adds new alignment and layout tools to the canvas editor, expanding functionality without fixing bugs or changing documentation Powered by Kimi | Model: |
✅ PR description updated |
✨ Feature
Background
The Lovart design tool needed a comprehensive set of productivity features to improve user workflow and efficiency. Users requested better ways to manage their design process, access their work history, and export their creations in various formats.
Changes
Impact
The implementation includes comprehensive error handling, accessibility features, and performance optimizations to ensure smooth user experience across all supported browsers.
📁 Changed Files
src/lib/clipboard.tssrc/lib/canvas-utils.tssrc/components/lovart/ExportDialog.tsxsrc/components/lovart/HistoryPanel.tsxsrc/components/lovart/KeyboardShortcutsDialog.tsxsrc/components/lovart/PromptSuggestions.tsxsrc/hooks/useKeyboardShortcuts.tssrc/components/lovart/AlignmentTools.tsxsrc/hooks/useHistory.tsPowered by Kimi | Model:
kimi-k2-turbo-preview