mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-28 21:42:27 +08:00
feat(video): add error handling and loading state for video creation
handle video creation errors by showing toast notifications and prevent multiple submissions by adding a loading state
This commit is contained in:
parent
5776512bf6
commit
d80eac2fbe
@ -4649,6 +4649,7 @@
|
||||
},
|
||||
"video": {
|
||||
"error": {
|
||||
"create": "Failed to create video",
|
||||
"invalid": "Invalid video",
|
||||
"load": {
|
||||
"message": "Failed to load the video",
|
||||
|
||||
@ -4,6 +4,7 @@ import { useAddOpenAIVideo } from '@renderer/hooks/video/useOpenAIVideos'
|
||||
import { createVideo } from '@renderer/services/ApiService'
|
||||
import { Provider } from '@renderer/types'
|
||||
import { Video } from '@renderer/types/video'
|
||||
import { getErrorMessage } from '@renderer/utils'
|
||||
import { ArrowUp } from 'lucide-react'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -20,25 +21,34 @@ const logger = loggerService.withContext('VideoPanel')
|
||||
export const VideoPanel = ({ provider, video }: VideoPanelProps) => {
|
||||
const { t } = useTranslation()
|
||||
const [prompt, setPrompt] = useState('')
|
||||
const [isProcessing, setIsProcessing] = useState(false)
|
||||
const addOpenAIVideo = useAddOpenAIVideo(provider.id)
|
||||
|
||||
const sendRequest = useCallback(async () => {
|
||||
const result = await createVideo({
|
||||
type: 'openai',
|
||||
params: {
|
||||
prompt
|
||||
},
|
||||
provider
|
||||
})
|
||||
const video = result.video
|
||||
switch (result.type) {
|
||||
case 'openai':
|
||||
addOpenAIVideo(video)
|
||||
break
|
||||
default:
|
||||
logger.error(`Invalid video type ${result.type}.`)
|
||||
const handleCreateVideo = useCallback(async () => {
|
||||
if (isProcessing) return
|
||||
setIsProcessing(true)
|
||||
try {
|
||||
const result = await createVideo({
|
||||
type: 'openai',
|
||||
params: {
|
||||
prompt
|
||||
},
|
||||
provider
|
||||
})
|
||||
const video = result.video
|
||||
switch (result.type) {
|
||||
case 'openai':
|
||||
addOpenAIVideo(video)
|
||||
break
|
||||
default:
|
||||
logger.error(`Invalid video type ${result.type}.`)
|
||||
}
|
||||
} catch (e) {
|
||||
window.toast.error({ title: t('video.error.create'), description: getErrorMessage(e), timeout: 5000 })
|
||||
} finally {
|
||||
setIsProcessing(false)
|
||||
}
|
||||
}, [addOpenAIVideo, prompt, provider])
|
||||
}, [addOpenAIVideo, isProcessing, prompt, provider, t])
|
||||
|
||||
return (
|
||||
<div className="flex flex-1 flex-col p-2">
|
||||
@ -54,21 +64,23 @@ export const VideoPanel = ({ provider, video }: VideoPanelProps) => {
|
||||
value={prompt}
|
||||
onValueChange={setPrompt}
|
||||
isClearable
|
||||
isDisabled={isProcessing}
|
||||
classNames={{ inputWrapper: 'pb-8' }}
|
||||
onKeyDown={(e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.stopPropagation()
|
||||
sendRequest()
|
||||
e.preventDefault()
|
||||
handleCreateVideo()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
color="primary"
|
||||
radius="full"
|
||||
startContent={<ArrowUp size={16} className="text-primary-foreground" />}
|
||||
isIconOnly
|
||||
className="absolute right-1 bottom-1 h-6 w-6 min-w-0"
|
||||
/>
|
||||
isLoading={isProcessing}
|
||||
className="absolute right-2 bottom-2 h-6 w-6 min-w-0">
|
||||
<ArrowUp size={16} className="text-primary-foreground" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user