refactor(Inputbar): Update file name handling in AttachmentPreview, adjust padding in Inputbar, and enhance textarea expansion logic
This commit is contained in:
parent
bc02727633
commit
5fa7465174
@ -9,6 +9,10 @@ import styled from 'styled-components'
|
|||||||
import { QuickPanelContext } from './provider'
|
import { QuickPanelContext } from './provider'
|
||||||
import { QuickPanelCallBackOptions, QuickPanelCloseAction, QuickPanelListItem, QuickPanelOpenOptions } from './types'
|
import { QuickPanelCallBackOptions, QuickPanelCloseAction, QuickPanelListItem, QuickPanelOpenOptions } from './types'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
setInputText: React.Dispatch<React.SetStateAction<string>>
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 快捷面板内容视图;
|
* @description 快捷面板内容视图;
|
||||||
* 请不要往这里添加入参,避免耦合;
|
* 请不要往这里添加入参,避免耦合;
|
||||||
@ -16,16 +20,16 @@ import { QuickPanelCallBackOptions, QuickPanelCloseAction, QuickPanelListItem, Q
|
|||||||
*
|
*
|
||||||
* 无奈之举,为了清除输入框搜索文本,所以传了个setInputText进来
|
* 无奈之举,为了清除输入框搜索文本,所以传了个setInputText进来
|
||||||
*/
|
*/
|
||||||
export const QuickPanelView: React.FC<{
|
export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
|
||||||
setInputText: React.Dispatch<React.SetStateAction<string>>
|
|
||||||
}> = ({ setInputText }) => {
|
|
||||||
const ctx = use(QuickPanelContext)
|
const ctx = use(QuickPanelContext)
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
throw new Error('QuickPanel must be used within a QuickPanelProvider')
|
throw new Error('QuickPanel must be used within a QuickPanelProvider')
|
||||||
}
|
}
|
||||||
|
|
||||||
const ASSISTIVE_KEY = isMac ? '⌘' : 'Ctrl'
|
const ASSISTIVE_KEY = isMac ? '⌘' : 'Ctrl'
|
||||||
const [isAssistiveKeyPressed, setIsAssistiveKeyPressed] = useState(false)
|
const [isAssistiveKeyPressed, setIsAssistiveKeyPressed] = useState(false)
|
||||||
|
|
||||||
// 避免上下翻页时,鼠标干扰
|
// 避免上下翻页时,鼠标干扰
|
||||||
const [isMouseOver, setIsMouseOver] = useState(false)
|
const [isMouseOver, setIsMouseOver] = useState(false)
|
||||||
|
|
||||||
@ -133,6 +137,7 @@ export const QuickPanelView: React.FC<{
|
|||||||
searchText: searchText,
|
searchText: searchText,
|
||||||
multiple: isAssistiveKeyPressed
|
multiple: isAssistiveKeyPressed
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.beforeAction?.(quickPanelCallBackOptions)
|
ctx.beforeAction?.(quickPanelCallBackOptions)
|
||||||
item?.action?.(quickPanelCallBackOptions)
|
item?.action?.(quickPanelCallBackOptions)
|
||||||
ctx.afterAction?.(quickPanelCallBackOptions)
|
ctx.afterAction?.(quickPanelCallBackOptions)
|
||||||
@ -345,6 +350,7 @@ export const QuickPanelView: React.FC<{
|
|||||||
}, [index, isAssistiveKeyPressed, historyPanel, ctx, list, handleItemAction, handleClose, clearSearchText])
|
}, [index, isAssistiveKeyPressed, historyPanel, ctx, list, handleItemAction, handleClose, clearSearchText])
|
||||||
|
|
||||||
const [footerWidth, setFooterWidth] = useState(0)
|
const [footerWidth, setFooterWidth] = useState(0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!footerRef.current || !ctx.isVisible) return
|
if (!footerRef.current || !ctx.isVisible) return
|
||||||
const footerWidth = footerRef.current.clientWidth
|
const footerWidth = footerRef.current.clientWidth
|
||||||
|
|||||||
@ -51,7 +51,7 @@ const AttachmentPreview: FC<Props> = ({ files, setFiles }) => {
|
|||||||
window.api.file.openPath(path)
|
window.api.file.openPath(path)
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
{file.origin_name || file.name}
|
{FileManager.formatFileName(file)}
|
||||||
{isImage(file.ext) && (
|
{isImage(file.ext) && (
|
||||||
<Image
|
<Image
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
@ -78,7 +78,7 @@ const ContentContainer = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 4px 0;
|
gap: 4px 0;
|
||||||
padding: 5px 15px 0;
|
padding: 5px 15px 0 10px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const FileName = styled.span`
|
const FileName = styled.span`
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ClearOutlined,
|
ClearOutlined,
|
||||||
CodeOutlined,
|
CodeOutlined,
|
||||||
ColumnHeightOutlined,
|
|
||||||
FileSearchOutlined,
|
FileSearchOutlined,
|
||||||
FormOutlined,
|
FormOutlined,
|
||||||
FullscreenExitOutlined,
|
FullscreenExitOutlined,
|
||||||
@ -527,22 +526,6 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
EventEmitter.emit(EVENT_NAMES.NEW_CONTEXT)
|
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 onInput = () => !expended && resizeTextArea()
|
||||||
|
|
||||||
const onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
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)
|
const selectedFile = await window.api.file.get(tempFilePath)
|
||||||
selectedFile && setFiles((prevFiles) => [...prevFiles, selectedFile])
|
selectedFile && setFiles((prevFiles) => [...prevFiles, selectedFile])
|
||||||
setText(text)
|
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 newHeight = Math.min(maxHeightInPixels, Math.max(startHeight.current + delta, 30))
|
||||||
const textArea = textareaRef.current?.resizableTextArea?.textArea
|
const textArea = textareaRef.current?.resizableTextArea?.textArea
|
||||||
|
|
||||||
if (textArea) {
|
if (textArea) {
|
||||||
textArea.style.height = `${newHeight}px`
|
textArea.style.height = `${newHeight}px`
|
||||||
setExpend(newHeight == maxHeightInPixels)
|
setExpend(newHeight == maxHeightInPixels)
|
||||||
@ -819,11 +803,49 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
}
|
}
|
||||||
}, [assistant, model, updateAssistant])
|
}, [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 = () => {
|
const resetHeight = () => {
|
||||||
if (expended) {
|
if (expended) {
|
||||||
setExpend(false)
|
setExpend(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
setTextareaHeight(undefined)
|
setTextareaHeight(undefined)
|
||||||
|
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
const textArea = textareaRef.current?.resizableTextArea?.textArea
|
const textArea = textareaRef.current?.resizableTextArea?.textArea
|
||||||
if (textArea) {
|
if (textArea) {
|
||||||
@ -833,13 +855,8 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const onMentionModel = (model: Model) => {
|
|
||||||
setMentionModels((prev) => {
|
const isExpended = expended || !!textareaHeight
|
||||||
const modelId = getModelUniqId(model)
|
|
||||||
const exists = prev.some((m) => getModelUniqId(m) === modelId)
|
|
||||||
return exists ? prev.filter((m) => getModelUniqId(m) !== modelId) : [...prev, model]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container onDragOver={handleDragOver} onDrop={handleDrop} className="inputbar">
|
<Container onDragOver={handleDragOver} onDrop={handleDrop} className="inputbar">
|
||||||
@ -957,18 +974,11 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
</ToolbarButton>
|
</ToolbarButton>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</Tooltip>
|
</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}>
|
<ToolbarButton type="text" onClick={onToggleExpended}>
|
||||||
{expended ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
|
{isExpended ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
|
||||||
</ToolbarButton>
|
</ToolbarButton>
|
||||||
</Tooltip>
|
</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} />
|
<NewContextButton onNewContext={onNewContext} ToolbarButton={ToolbarButton} />
|
||||||
<TokenCount
|
<TokenCount
|
||||||
estimateTokenCount={estimateTokenCount}
|
estimateTokenCount={estimateTokenCount}
|
||||||
@ -1030,7 +1040,7 @@ const Container = styled.div`
|
|||||||
|
|
||||||
const InputBarContainer = styled.div`
|
const InputBarContainer = styled.div`
|
||||||
border: 0.5px solid var(--color-border);
|
border: 0.5px solid var(--color-border);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.2s ease;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 14px 20px;
|
margin: 14px 20px;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@ -1041,7 +1051,7 @@ const InputBarContainer = styled.div`
|
|||||||
|
|
||||||
const TextareaStyle: CSSProperties = {
|
const TextareaStyle: CSSProperties = {
|
||||||
paddingLeft: 0,
|
paddingLeft: 0,
|
||||||
padding: '4px 15px 8px' // 减小顶部padding
|
padding: '6px 15px 8px' // 减小顶部padding
|
||||||
}
|
}
|
||||||
|
|
||||||
const Textarea = styled(TextArea)`
|
const Textarea = styled(TextArea)`
|
||||||
|
|||||||
@ -36,7 +36,7 @@ const KnowledgeBaseInput: FC<{
|
|||||||
|
|
||||||
const Container = styled(Flex)`
|
const Container = styled(Flex)`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 5px 15px 0;
|
padding: 5px 15px 0 10px;
|
||||||
`
|
`
|
||||||
|
|
||||||
export default KnowledgeBaseInput
|
export default KnowledgeBaseInput
|
||||||
|
|||||||
@ -46,7 +46,7 @@ const MentionModelsInput: FC<{
|
|||||||
|
|
||||||
const Container = styled(Flex)`
|
const Container = styled(Flex)`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 5px 15px 0;
|
padding: 5px 15px 10px;
|
||||||
i.iconfont {
|
i.iconfont {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
margin-inline-end: 7px;
|
margin-inline-end: 7px;
|
||||||
|
|||||||
@ -84,7 +84,7 @@ const Container = styled.div`
|
|||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
}
|
}
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 800px) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user