mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-08 22:39:36 +08:00
refactor(video): improve video status update handling with ref
- Use useRef to track videos state to avoid stale closures - Add error handling for video status updates - Remove hardcoded openai provider check in favor of dynamic provider
This commit is contained in:
parent
dced99ce57
commit
de10a7fd6c
@ -9,18 +9,21 @@ import {
|
|||||||
setVideosAction,
|
setVideosAction,
|
||||||
updateVideoAction
|
updateVideoAction
|
||||||
} from '@renderer/store/video'
|
} from '@renderer/store/video'
|
||||||
import { SystemProviderIds } from '@renderer/types'
|
|
||||||
import { Video } from '@renderer/types/video'
|
import { Video } from '@renderer/types/video'
|
||||||
import { video } from 'notion-helper'
|
import { useCallback, useEffect, useRef } from 'react'
|
||||||
import { useCallback, useEffect } from 'react'
|
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
|
|
||||||
const logger = loggerService.withContext('useVideo')
|
const logger = loggerService.withContext('useVideo')
|
||||||
|
|
||||||
export const useVideos = (providerId: string) => {
|
export const useVideos = (providerId: string) => {
|
||||||
const videos = useAppSelector((state) => state.video.videoMap[providerId])
|
const videos = useAppSelector((state) => state.video.videoMap[providerId])
|
||||||
|
const videosRef = useRef(videos)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
videosRef.current = videos
|
||||||
|
}, [videos])
|
||||||
|
|
||||||
const addVideo = useCallback(
|
const addVideo = useCallback(
|
||||||
(video: Video) => {
|
(video: Video) => {
|
||||||
if (videos && videos.every((v) => v.id !== video.id)) {
|
if (videos && videos.every((v) => v.id !== video.id)) {
|
||||||
@ -65,17 +68,27 @@ export const useVideos = (providerId: string) => {
|
|||||||
}, [setVideos, videos])
|
}, [setVideos, videos])
|
||||||
|
|
||||||
// update videos from api
|
// update videos from api
|
||||||
const openai = getProviderById(SystemProviderIds.openai)
|
// NOTE: This provider should support openai videos endpoint. No runtime check here.
|
||||||
|
const provider = getProviderById(providerId)
|
||||||
const fetcher = async () => {
|
const fetcher = async () => {
|
||||||
if (!videos || !openai) return []
|
if (!videos || !provider) return []
|
||||||
const openaiVideos = videos.filter((v) => v.type === 'openai')
|
const openaiVideos = videos.filter((v) => v.type === 'openai')
|
||||||
const jobs = openaiVideos.map((v) => retrieveVideo({ type: 'openai', videoId: v.id, provider: openai }))
|
const jobs = openaiVideos.map((v) => retrieveVideo({ type: 'openai', videoId: v.id, provider }))
|
||||||
const result = await Promise.allSettled(jobs)
|
const result = await Promise.allSettled(jobs)
|
||||||
return result.filter((p) => p.status === 'fulfilled').map((p) => p.value)
|
return result.filter((p) => p.status === 'fulfilled').map((p) => p.value)
|
||||||
}
|
}
|
||||||
const { data, isLoading, error } = useSWR('video/openai/videos', fetcher, { refreshInterval: 3000 })
|
const { data, error } = useSWR('video/openai/videos', fetcher, { refreshInterval: 3000 })
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
logger.debug('effect', { data, videos })
|
if (error) {
|
||||||
|
logger.error('Failed to fetch video status updates', error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!provider) {
|
||||||
|
logger.warn(`Provider ${providerId} not found.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const videos = videosRef.current
|
||||||
|
|
||||||
if (!data || !videos) return
|
if (!data || !videos) return
|
||||||
data.forEach((v) => {
|
data.forEach((v) => {
|
||||||
const retrievedVideo = v.video
|
const retrievedVideo = v.video
|
||||||
@ -100,15 +113,9 @@ export const useVideos = (providerId: string) => {
|
|||||||
if (storeVideo.status === 'in_progress' || storeVideo.status === 'queued') {
|
if (storeVideo.status === 'in_progress' || storeVideo.status === 'queued') {
|
||||||
setVideo({ ...storeVideo, status: 'completed', thumbnail: null, metadata: retrievedVideo })
|
setVideo({ ...storeVideo, status: 'completed', thumbnail: null, metadata: retrievedVideo })
|
||||||
// try to request thumbnail here.
|
// try to request thumbnail here.
|
||||||
if (!openai) {
|
|
||||||
logger.warn(
|
|
||||||
`Try to fetch thumbnail for video ${retrievedVideo.id}, but provider ${providerId} not found.`
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
retrieveVideoContent({
|
retrieveVideoContent({
|
||||||
type: 'openai',
|
type: 'openai',
|
||||||
provider: openai,
|
provider,
|
||||||
videoId: retrievedVideo.id,
|
videoId: retrievedVideo.id,
|
||||||
query: { variant: 'thumbnail' }
|
query: { variant: 'thumbnail' }
|
||||||
})
|
})
|
||||||
@ -130,7 +137,7 @@ export const useVideos = (providerId: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, [data])
|
}, [data, error, provider, providerId, setVideo])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
videos: videos ?? [],
|
videos: videos ?? [],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user