diff --git a/src/renderer/src/components/QuickPanel/view.tsx b/src/renderer/src/components/QuickPanel/view.tsx index b516dd8f..856b95b9 100644 --- a/src/renderer/src/components/QuickPanel/view.tsx +++ b/src/renderer/src/components/QuickPanel/view.tsx @@ -9,6 +9,10 @@ import styled from 'styled-components' import { QuickPanelContext } from './provider' import { QuickPanelCallBackOptions, QuickPanelCloseAction, QuickPanelListItem, QuickPanelOpenOptions } from './types' +interface Props { + setInputText: React.Dispatch> +} + /** * @description 快捷面板内容视图; * 请不要往这里添加入参,避免耦合; @@ -16,16 +20,16 @@ import { QuickPanelCallBackOptions, QuickPanelCloseAction, QuickPanelListItem, Q * * 无奈之举,为了清除输入框搜索文本,所以传了个setInputText进来 */ -export const QuickPanelView: React.FC<{ - setInputText: React.Dispatch> -}> = ({ setInputText }) => { +export const QuickPanelView: React.FC = ({ setInputText }) => { const ctx = use(QuickPanelContext) + if (!ctx) { throw new Error('QuickPanel must be used within a QuickPanelProvider') } const ASSISTIVE_KEY = isMac ? '⌘' : 'Ctrl' const [isAssistiveKeyPressed, setIsAssistiveKeyPressed] = useState(false) + // 避免上下翻页时,鼠标干扰 const [isMouseOver, setIsMouseOver] = useState(false) @@ -133,6 +137,7 @@ export const QuickPanelView: React.FC<{ searchText: searchText, multiple: isAssistiveKeyPressed } + ctx.beforeAction?.(quickPanelCallBackOptions) item?.action?.(quickPanelCallBackOptions) ctx.afterAction?.(quickPanelCallBackOptions) @@ -345,6 +350,7 @@ export const QuickPanelView: React.FC<{ }, [index, isAssistiveKeyPressed, historyPanel, ctx, list, handleItemAction, handleClose, clearSearchText]) const [footerWidth, setFooterWidth] = useState(0) + useEffect(() => { if (!footerRef.current || !ctx.isVisible) return const footerWidth = footerRef.current.clientWidth diff --git a/src/renderer/src/pages/home/Inputbar/AttachmentPreview.tsx b/src/renderer/src/pages/home/Inputbar/AttachmentPreview.tsx index 6ed77ee3..fc763982 100644 --- a/src/renderer/src/pages/home/Inputbar/AttachmentPreview.tsx +++ b/src/renderer/src/pages/home/Inputbar/AttachmentPreview.tsx @@ -51,7 +51,7 @@ const AttachmentPreview: FC = ({ files, setFiles }) => { window.api.file.openPath(path) } }}> - {file.origin_name || file.name} + {FileManager.formatFileName(file)} {isImage(file.ext) && ( = ({ assistant: _assistant, setActiveTopic, topic }) = EventEmitter.emit(EVENT_NAMES.NEW_CONTEXT) } - const onToggleExpended = () => { - const isExpended = !expended - setExpend(isExpended) - const textArea = textareaRef.current?.resizableTextArea?.textArea - - if (textArea) { - if (isExpended) { - textArea.style.height = '70vh' - } else { - resetHeight() - } - } - - textareaRef.current?.focus() - } - const onInput = () => !expended && resizeTextArea() const onChange = (e: React.ChangeEvent) => { @@ -617,7 +600,7 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = const selectedFile = await window.api.file.get(tempFilePath) selectedFile && setFiles((prevFiles) => [...prevFiles, selectedFile]) setText(text) - setTimeout(() => resizeTextArea(), 0) + setTimeout(() => resizeTextArea(), 50) } }) } @@ -674,6 +657,7 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = const newHeight = Math.min(maxHeightInPixels, Math.max(startHeight.current + delta, 30)) const textArea = textareaRef.current?.resizableTextArea?.textArea + if (textArea) { textArea.style.height = `${newHeight}px` setExpend(newHeight == maxHeightInPixels) @@ -819,11 +803,49 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = } }, [assistant, model, updateAssistant]) + const onMentionModel = (model: Model) => { + setMentionModels((prev) => { + const modelId = getModelUniqId(model) + const exists = prev.some((m) => getModelUniqId(m) === modelId) + return exists ? prev.filter((m) => getModelUniqId(m) !== modelId) : [...prev, model] + }) + } + + const onToggleExpended = () => { + if (textareaHeight) { + const textArea = textareaRef.current?.resizableTextArea?.textArea + if (textArea) { + textArea.style.height = 'auto' + setTextareaHeight(undefined) + setTimeout(() => { + textArea.style.height = `${textArea.scrollHeight}px` + }, 200) + return + } + } + + const isExpended = !expended + setExpend(isExpended) + const textArea = textareaRef.current?.resizableTextArea?.textArea + + if (textArea) { + if (isExpended) { + textArea.style.height = '70vh' + } else { + resetHeight() + } + } + + textareaRef.current?.focus() + } + const resetHeight = () => { if (expended) { setExpend(false) } + setTextareaHeight(undefined) + requestAnimationFrame(() => { const textArea = textareaRef.current?.resizableTextArea?.textArea if (textArea) { @@ -833,13 +855,8 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = } }) } - const onMentionModel = (model: Model) => { - setMentionModels((prev) => { - const modelId = getModelUniqId(model) - const exists = prev.some((m) => getModelUniqId(m) === modelId) - return exists ? prev.filter((m) => getModelUniqId(m) !== modelId) : [...prev, model] - }) - } + + const isExpended = expended || !!textareaHeight return ( @@ -957,18 +974,11 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = - + - {expended ? : } + {isExpended ? : } - {textareaHeight && ( - - - - - - )}