diff --git a/src/renderer/src/windows/mini/home/HomeWindow.tsx b/src/renderer/src/windows/mini/home/HomeWindow.tsx index 77aa0b9abe..d694783050 100644 --- a/src/renderer/src/windows/mini/home/HomeWindow.tsx +++ b/src/renderer/src/windows/mini/home/HomeWindow.tsx @@ -41,6 +41,7 @@ import type { FeatureMenusRef } from './components/FeatureMenus' import FeatureMenus from './components/FeatureMenus' import Footer from './components/Footer' import InputBar from './components/InputBar' +import PastedFilesPreview from './components/PastedFilesPreview' const logger = loggerService.withContext('HomeWindow') @@ -87,6 +88,8 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => { return userInputText.trim() }, [isFirstMessage, referenceText, userInputText]) + const hasChatInput = useMemo(() => Boolean(userContent) || files.length > 0, [files.length, userContent]) + useEffect(() => { i18n.changeLanguage(language || navigator.language || defaultLanguage) }, [language]) @@ -171,7 +174,7 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => { if (isLoading) return e.preventDefault() - if (userContent) { + if (userContent || files.length > 0) { if (route === 'home') { featureMenusRef.current?.useFeature() } else { @@ -242,7 +245,7 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => { const handleSendMessage = useCallback( async (prompt?: string) => { - if (isEmpty(userContent) || !currentTopic.current) { + if ((isEmpty(userContent) && files.length === 0) || !currentTopic.current) { return } @@ -251,8 +254,10 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => { const uploadedFiles = files.length ? await FileManager.uploadFiles(files) : [] + const content = [prompt, userContent].filter(Boolean).join('\n\n') || undefined + const { message: userMessage, blocks } = getUserMessage({ - content: [prompt, userContent].filter(Boolean).join('\n\n'), + content, assistant: currentAssistant, topic: currentTopic.current, files: uploadedFiles @@ -481,6 +486,10 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => { [files, userContent, currentAssistant] ) + const handleRemoveFile = useCallback((filePath: string) => { + setFiles((prevFiles) => prevFiles.filter((file) => file.path !== filePath)) + }, []) + const handlePause = useCallback(() => { if (currentAskId.current) { abortCompletion(currentAskId.current) @@ -575,6 +584,7 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => { handlePaste={handlePaste} ref={inputBarRef} /> + )} @@ -620,6 +630,7 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => { handlePaste={handlePaste} ref={inputBarRef} /> +
@@ -627,6 +638,7 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => { setRoute={setRoute} onSendMessage={handleSendMessage} text={userContent} + hasChatInput={hasChatInput} ref={featureMenusRef} />
diff --git a/src/renderer/src/windows/mini/home/components/FeatureMenus.tsx b/src/renderer/src/windows/mini/home/components/FeatureMenus.tsx index ebe878644e..e83206cf5b 100644 --- a/src/renderer/src/windows/mini/home/components/FeatureMenus.tsx +++ b/src/renderer/src/windows/mini/home/components/FeatureMenus.tsx @@ -11,6 +11,7 @@ interface FeatureMenusProps { text: string setRoute: Dispatch> onSendMessage: (prompt?: string) => void + hasChatInput: boolean } export interface FeatureMenusRef { @@ -23,6 +24,7 @@ export interface FeatureMenusRef { const FeatureMenus = ({ ref, text, + hasChatInput, setRoute, onSendMessage }: FeatureMenusProps & { ref?: React.RefObject }) => { @@ -36,7 +38,7 @@ const FeatureMenus = ({ title: t('miniwindow.feature.chat'), active: true, onClick: () => { - if (text) { + if (hasChatInput) { setRoute('chat') onSendMessage() } @@ -68,7 +70,7 @@ const FeatureMenus = ({ } } ], - [onSendMessage, setRoute, t, text] + [hasChatInput, onSendMessage, setRoute, t, text] ) useImperativeHandle(ref, () => ({ diff --git a/src/renderer/src/windows/mini/home/components/PastedFilesPreview.tsx b/src/renderer/src/windows/mini/home/components/PastedFilesPreview.tsx new file mode 100644 index 0000000000..28f94ba019 --- /dev/null +++ b/src/renderer/src/windows/mini/home/components/PastedFilesPreview.tsx @@ -0,0 +1,82 @@ +import { CloseOutlined, FileImageOutlined, FileOutlined } from '@ant-design/icons' +import type { FileMetadata } from '@renderer/types' +import { FileTypes } from '@renderer/types' +import { Tooltip } from 'antd' +import type { FC } from 'react' +import styled from 'styled-components' + +interface PastedFilesPreviewProps { + files: FileMetadata[] + onRemove: (filePath: string) => void +} + +const PastedFilesPreview: FC = ({ files, onRemove }) => { + if (!files.length) return null + + return ( + + {files.map((file) => ( + + {file.type === FileTypes.IMAGE ? : } + + {file.name} + + onRemove(file.path)}> + + + + ))} + + ) +} + +const Container = styled.div` + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 8px 0 2px; +` + +const FileChip = styled.div` + display: inline-flex; + align-items: center; + gap: 8px; + padding: 6px 10px; + border-radius: 8px; + background: var(--color-background-opacity); + border: 1px solid var(--color-border); + color: var(--color-text); + max-width: 100%; +` + +const IconWrapper = styled.span` + display: inline-flex; + align-items: center; + justify-content: center; + color: var(--color-text-secondary); +` + +const FileName = styled.span` + font-size: 12px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 180px; +` + +const RemoveButton = styled.button` + display: inline-flex; + align-items: center; + justify-content: center; + background: none; + border: none; + color: var(--color-text-secondary); + cursor: pointer; + padding: 2px; + + &:hover { + color: var(--color-text); + } +` + +export default PastedFilesPreview