69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
import { useState } from 'react'
|
|
import { useToast } from '@/components/shared/Toast'
|
|
import { imageGenerationService } from '@/lib/services/imageGeneration'
|
|
import { flashcardsService, type Flashcard } from '@/lib/services/flashcards'
|
|
|
|
interface UseImageGenerationOptions {
|
|
flashcard: Flashcard | null
|
|
onFlashcardUpdate: (updatedCard: Flashcard) => void
|
|
}
|
|
|
|
export function useImageGeneration({
|
|
flashcard,
|
|
onFlashcardUpdate
|
|
}: UseImageGenerationOptions) {
|
|
const toast = useToast()
|
|
const [isGenerating, setIsGenerating] = useState(false)
|
|
const [progress, setProgress] = useState<string>('')
|
|
|
|
const generateImage = async () => {
|
|
if (!flashcard || isGenerating) return
|
|
|
|
try {
|
|
setIsGenerating(true)
|
|
setProgress('啟動生成中...')
|
|
toast.info(`開始為「${flashcard.word}」生成例句圖片...`)
|
|
|
|
const generateResult = await imageGenerationService.generateImage(flashcard.id)
|
|
if (!generateResult.success || !generateResult.data) {
|
|
throw new Error(generateResult.error || '啟動生成失敗')
|
|
}
|
|
|
|
const requestId = generateResult.data.requestId
|
|
setProgress('Gemini 生成描述中...')
|
|
|
|
const finalStatus = await imageGenerationService.pollUntilComplete(
|
|
requestId,
|
|
(status: any) => {
|
|
const stage = status.stages.gemini.status === 'completed'
|
|
? 'Replicate 生成圖片中...' : 'Gemini 生成描述中...'
|
|
setProgress(stage)
|
|
},
|
|
5
|
|
)
|
|
|
|
if (finalStatus.overallStatus === 'completed') {
|
|
setProgress('生成完成,載入中...')
|
|
// 重新載入詞卡資料
|
|
const result = await flashcardsService.getFlashcard(flashcard.id)
|
|
if (result.success && result.data) {
|
|
onFlashcardUpdate(result.data)
|
|
}
|
|
toast.success(`「${flashcard.word}」的例句圖片生成完成!`)
|
|
} else {
|
|
throw new Error('圖片生成未完成')
|
|
}
|
|
} catch (error: any) {
|
|
toast.error(`圖片生成失敗: ${error.message || '未知錯誤'}`)
|
|
} finally {
|
|
setIsGenerating(false)
|
|
setProgress('')
|
|
}
|
|
}
|
|
|
|
return {
|
|
generateImage,
|
|
isGenerating,
|
|
progress
|
|
}
|
|
} |