mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 20:12:38 +08:00
feat: support clipboard images in mini assistant
This commit is contained in:
parent
7507443d8b
commit
4a7986f041
@ -7,12 +7,14 @@ import i18n from '@renderer/i18n'
|
||||
import { fetchChatCompletion } from '@renderer/services/ApiService'
|
||||
import { getDefaultTopic } from '@renderer/services/AssistantService'
|
||||
import { ConversationService } from '@renderer/services/ConversationService'
|
||||
import FileManager from '@renderer/services/FileManager'
|
||||
import { getAssistantMessage, getUserMessage } from '@renderer/services/MessagesService'
|
||||
import PasteService from '@renderer/services/PasteService'
|
||||
import store, { useAppSelector } from '@renderer/store'
|
||||
import { updateOneBlock, upsertManyBlocks, upsertOneBlock } from '@renderer/store/messageBlock'
|
||||
import { newMessagesActions, selectMessagesForTopic } from '@renderer/store/newMessage'
|
||||
import { cancelThrottledBlockUpdate, throttledBlockUpdate } from '@renderer/store/thunk/messageThunk'
|
||||
import type { Topic } from '@renderer/types'
|
||||
import type { FileMetadata, Topic } from '@renderer/types'
|
||||
import { ThemeMode } from '@renderer/types'
|
||||
import type { Chunk } from '@renderer/types/chunk'
|
||||
import { ChunkType } from '@renderer/types/chunk'
|
||||
@ -51,6 +53,7 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
||||
const [isFirstMessage, setIsFirstMessage] = useState(true)
|
||||
|
||||
const [userInputText, setUserInputText] = useState('')
|
||||
const [files, setFiles] = useState<FileMetadata[]>([])
|
||||
|
||||
const [clipboardText, setClipboardText] = useState('')
|
||||
const lastClipboardTextRef = useRef<string | null>(null)
|
||||
@ -73,6 +76,8 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
||||
const inputBarRef = useRef<HTMLDivElement>(null)
|
||||
const featureMenusRef = useRef<FeatureMenusRef>(null)
|
||||
|
||||
const supportedImageExts = useMemo(() => ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'], [])
|
||||
|
||||
const referenceText = useMemo(() => clipboardText || userInputText, [clipboardText, userInputText])
|
||||
|
||||
const userContent = useMemo(() => {
|
||||
@ -213,6 +218,23 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
||||
setUserInputText(e.target.value)
|
||||
}
|
||||
|
||||
const handlePaste = useCallback(
|
||||
async (event: React.ClipboardEvent<HTMLInputElement>) => {
|
||||
await PasteService.handlePaste(
|
||||
event.nativeEvent,
|
||||
supportedImageExts,
|
||||
setFiles,
|
||||
setUserInputText,
|
||||
false,
|
||||
undefined,
|
||||
userInputText,
|
||||
undefined,
|
||||
t
|
||||
)
|
||||
},
|
||||
[supportedImageExts, t, userInputText]
|
||||
)
|
||||
|
||||
const handleError = (error: Error) => {
|
||||
setIsLoading(false)
|
||||
setError(error.message)
|
||||
@ -227,10 +249,13 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
||||
try {
|
||||
const topicId = currentTopic.current.id
|
||||
|
||||
const uploadedFiles = files.length ? await FileManager.uploadFiles(files) : []
|
||||
|
||||
const { message: userMessage, blocks } = getUserMessage({
|
||||
content: [prompt, userContent].filter(Boolean).join('\n\n'),
|
||||
assistant: currentAssistant,
|
||||
topic: currentTopic.current
|
||||
topic: currentTopic.current,
|
||||
files: uploadedFiles
|
||||
})
|
||||
|
||||
store.dispatch(newMessagesActions.addMessage({ topicId, message: userMessage }))
|
||||
@ -272,6 +297,7 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
||||
|
||||
setIsFirstMessage(false)
|
||||
setUserInputText('')
|
||||
setFiles([])
|
||||
|
||||
const newAssistant = cloneDeep(currentAssistant)
|
||||
if (!newAssistant.settings) {
|
||||
@ -452,7 +478,7 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
||||
currentAskId.current = ''
|
||||
}
|
||||
},
|
||||
[userContent, currentAssistant]
|
||||
[files, userContent, currentAssistant]
|
||||
)
|
||||
|
||||
const handlePause = useCallback(() => {
|
||||
@ -546,6 +572,7 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
||||
loading={isLoading}
|
||||
handleKeyDown={handleKeyDown}
|
||||
handleChange={handleChange}
|
||||
handlePaste={handlePaste}
|
||||
ref={inputBarRef}
|
||||
/>
|
||||
<Divider style={{ margin: '10px 0' }} />
|
||||
@ -590,6 +617,7 @@ const HomeWindow: FC<{ draggable?: boolean }> = ({ draggable = true }) => {
|
||||
loading={isLoading}
|
||||
handleKeyDown={handleKeyDown}
|
||||
handleChange={handleChange}
|
||||
handlePaste={handlePaste}
|
||||
ref={inputBarRef}
|
||||
/>
|
||||
<Divider style={{ margin: '10px 0' }} />
|
||||
|
||||
@ -14,6 +14,7 @@ interface InputBarProps {
|
||||
loading: boolean
|
||||
handleKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void
|
||||
handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void
|
||||
handlePaste: (e: React.ClipboardEvent<HTMLInputElement>) => void
|
||||
}
|
||||
|
||||
const InputBar = ({
|
||||
@ -23,7 +24,8 @@ const InputBar = ({
|
||||
placeholder,
|
||||
loading,
|
||||
handleKeyDown,
|
||||
handleChange
|
||||
handleChange,
|
||||
handlePaste
|
||||
}: InputBarProps & { ref?: React.RefObject<HTMLDivElement | null> }) => {
|
||||
const inputRef = useRef<InputRef>(null)
|
||||
const { setTimeoutTimer } = useTimer()
|
||||
@ -40,6 +42,7 @@ const InputBar = ({
|
||||
autoFocus
|
||||
onKeyDown={handleKeyDown}
|
||||
onChange={handleChange}
|
||||
onPaste={handlePaste}
|
||||
ref={inputRef}
|
||||
/>
|
||||
</InputWrapper>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user