refactor(Inputbar): Update file name handling in AttachmentPreview, adjust padding in Inputbar, and enhance textarea expansion logic

This commit is contained in:
kangfenmao 2025-04-05 20:02:32 +08:00
parent bc02727633
commit 5fa7465174
6 changed files with 60 additions and 44 deletions

View File

@ -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<React.SetStateAction<string>>
}
/**
* @description ;
* ;
@ -16,16 +20,16 @@ import { QuickPanelCallBackOptions, QuickPanelCloseAction, QuickPanelListItem, Q
*
* setInputText进来
*/
export const QuickPanelView: React.FC<{
setInputText: React.Dispatch<React.SetStateAction<string>>
}> = ({ setInputText }) => {
export const QuickPanelView: React.FC<Props> = ({ 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

View File

@ -51,7 +51,7 @@ const AttachmentPreview: FC<Props> = ({ files, setFiles }) => {
window.api.file.openPath(path)
}
}}>
{file.origin_name || file.name}
{FileManager.formatFileName(file)}
{isImage(file.ext) && (
<Image
style={{ display: 'none' }}
@ -78,7 +78,7 @@ const ContentContainer = styled.div`
display: flex;
flex-wrap: wrap;
gap: 4px 0;
padding: 5px 15px 0;
padding: 5px 15px 0 10px;
`
const FileName = styled.span`

View File

@ -1,7 +1,6 @@
import {
ClearOutlined,
CodeOutlined,
ColumnHeightOutlined,
FileSearchOutlined,
FormOutlined,
FullscreenExitOutlined,
@ -527,22 +526,6 @@ const Inputbar: FC<Props> = ({ 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<HTMLTextAreaElement>) => {
@ -617,7 +600,7 @@ const Inputbar: FC<Props> = ({ 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<Props> = ({ 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<Props> = ({ 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<Props> = ({ 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 (
<Container onDragOver={handleDragOver} onDrop={handleDrop} className="inputbar">
@ -957,18 +974,11 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
</ToolbarButton>
</Popconfirm>
</Tooltip>
<Tooltip placement="top" title={expended ? t('chat.input.collapse') : t('chat.input.expand')} arrow>
<Tooltip placement="top" title={isExpended ? t('chat.input.collapse') : t('chat.input.expand')} arrow>
<ToolbarButton type="text" onClick={onToggleExpended}>
{expended ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
{isExpended ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
</ToolbarButton>
</Tooltip>
{textareaHeight && (
<Tooltip placement="top" title={t('chat.input.auto_resize')} arrow>
<ToolbarButton type="text" onClick={resetHeight}>
<ColumnHeightOutlined />
</ToolbarButton>
</Tooltip>
)}
<NewContextButton onNewContext={onNewContext} ToolbarButton={ToolbarButton} />
<TokenCount
estimateTokenCount={estimateTokenCount}
@ -1030,7 +1040,7 @@ const Container = styled.div`
const InputBarContainer = styled.div`
border: 0.5px solid var(--color-border);
transition: all 0.3s ease;
transition: all 0.2s ease;
position: relative;
margin: 14px 20px;
margin-top: 0;
@ -1041,7 +1051,7 @@ const InputBarContainer = styled.div`
const TextareaStyle: CSSProperties = {
paddingLeft: 0,
padding: '4px 15px 8px' // 减小顶部padding
padding: '6px 15px 8px' // 减小顶部padding
}
const Textarea = styled(TextArea)`

View File

@ -36,7 +36,7 @@ const KnowledgeBaseInput: FC<{
const Container = styled(Flex)`
width: 100%;
padding: 5px 15px 0;
padding: 5px 15px 0 10px;
`
export default KnowledgeBaseInput

View File

@ -46,7 +46,7 @@ const MentionModelsInput: FC<{
const Container = styled(Flex)`
width: 100%;
padding: 5px 15px 0;
padding: 5px 15px 10px;
i.iconfont {
font-size: 12px;
margin-inline-end: 7px;

View File

@ -84,7 +84,7 @@ const Container = styled.div`
font-size: 10px;
margin-right: 3px;
}
@media (max-width: 700px) {
@media (max-width: 800px) {
display: none;
}
`