diff --git a/apps/desktop/src/components/editor/AiAssistant.vue b/apps/desktop/src/components/editor/AiAssistant.vue index 9b9dc8861..08d0cc3b1 100644 --- a/apps/desktop/src/components/editor/AiAssistant.vue +++ b/apps/desktop/src/components/editor/AiAssistant.vue @@ -74,6 +74,18 @@ const promptTextareaRef = ref(null); const promptCompositionActive = ref(false); const shikiCodeHighlighter = ref(); +// 新增:输入框拖拽调整相关常量 +const AI_TEXTAREA_MIN_ROWS = 3; +const AI_TEXTAREA_MAX_ROWS = 8; +const AI_TEXTAREA_LINE_HEIGHT_PX = 20; +const AI_TEXTAREA_ROWS_STORAGE_KEY = "dbx-ai-textarea-rows"; + +// 新增:输入框拖拽调整相关状态 +const textareaRows = ref(AI_TEXTAREA_MIN_ROWS); +const isResizing = ref(false); +let resizeStartY = 0; +let resizeStartRows = 0; + interface AiMentionCandidate { schema?: string; name: string; @@ -675,15 +687,68 @@ function startNewChat() { } onMounted(async () => { + // 新增:恢复用户偏好的输入框行数 + const savedRows = localStorage.getItem(AI_TEXTAREA_ROWS_STORAGE_KEY); + if (savedRows) { + const rows = parseInt(savedRows, 10); + if (!isNaN(rows) && rows >= AI_TEXTAREA_MIN_ROWS && rows <= AI_TEXTAREA_MAX_ROWS) { + textareaRows.value = rows; + } + } + + // 现有代码 conversations.value = await loadAiConversations().catch(() => []); shikiCodeHighlighter.value = await createAiShikiCodeHighlighter({ appearance: () => aiCodeAppearance.value, }).catch(() => undefined); }); +function startResize(event: MouseEvent) { + event.preventDefault(); + isResizing.value = true; + resizeStartY = event.clientY; + resizeStartRows = textareaRows.value; + + document.addEventListener("mousemove", handleResize); + document.addEventListener("mouseup", stopResize); + + document.body.style.userSelect = "none"; + document.body.style.cursor = "ns-resize"; +} + +function handleResize(event: MouseEvent) { + if (!isResizing.value) return; + + const deltaY = resizeStartY - event.clientY; + const deltaRows = Math.round(deltaY / AI_TEXTAREA_LINE_HEIGHT_PX); + + const newRows = Math.max(AI_TEXTAREA_MIN_ROWS, Math.min(AI_TEXTAREA_MAX_ROWS, resizeStartRows + deltaRows)); + textareaRows.value = newRows; +} + +function stopResize() { + if (!isResizing.value) return; + + isResizing.value = false; + + document.removeEventListener("mousemove", handleResize); + document.removeEventListener("mouseup", stopResize); + + document.body.style.userSelect = ""; + document.body.style.cursor = ""; + + localStorage.setItem(AI_TEXTAREA_ROWS_STORAGE_KEY, textareaRows.value.toString()); +} + onUnmounted(() => { clearTimeout(mentionTimer); cancelStream(); + // 清理拖拽事件监听,防止内存泄漏 + document.removeEventListener("mousemove", handleResize); + document.removeEventListener("mouseup", stopResize); + // 若卸载时仍在拖拽,复位 body 样式,避免全局残留 + document.body.style.userSelect = ""; + document.body.style.cursor = ""; }); function triggerAction(action: AiAction, instruction?: string) { @@ -850,122 +915,125 @@ const messageRenderer = computed(() => {
-
-
- - - - -
-
-
- - {{ t("common.loading") }} +
-
- {{ mentionError }} +
+
+ + {{ t("common.loading") }} +
+
+ {{ mentionError }} +
+
+ {{ t("ai.tableMentionEmpty") }} +
+
+ +
-
- {{ t("ai.tableMentionEmpty") }} -
-
+
+
+