feat: add force option to project generation for reprocessing completed segments

This commit is contained in:
2026-03-12 17:19:37 +08:00
parent 7f25dd09f6
commit afb6830a6d
5 changed files with 21 additions and 8 deletions

View File

@@ -737,7 +737,7 @@ function ChaptersPanel({
generatingChapterIndices: Set<number>
sequentialPlayingId: number | null
onParseChapter: (chapterId: number, title?: string) => void
onGenerate: (chapterIndex?: number) => void
onGenerate: (chapterIndex?: number, force?: boolean) => void
onParseAll: () => void
onGenerateAll: () => void
onProcessAll: () => void
@@ -921,6 +921,12 @@ function ChaptersPanel({
{ch.status === 'ready' && chAllDone && (
<>
<span className="text-[11px] text-muted-foreground">{t('projectCard.chapters.doneBadge', { count: chDone })}</span>
<Button size="sm" variant="ghost" className="h-5 text-[11px] px-1.5 text-muted-foreground" disabled={loadingAction} onClick={() => {
setExpandedChapters(prev => { const n = new Set(prev); n.add(ch.id); return n })
onGenerate(ch.chapter_index, true)
}}>
<RefreshCw className="h-3 w-3 mr-1" />{t('projectCard.chapters.generate')}
</Button>
<Button size="sm" variant="ghost" className="h-5 w-5 p-0" onClick={() => onDownload(ch.chapter_index)} title={t('projectCard.downloadAll')}>
<Download className="h-3 w-3" />
</Button>
@@ -1179,7 +1185,7 @@ export default function Audiobook() {
}
}, [segments, generatingChapterIndices])
const shouldPoll = isPolling || ['analyzing', 'generating'].includes(status) || hasParsingChapter || generatingChapterIndices.size > 0
const shouldPoll = isPolling || ['analyzing', 'generating'].includes(status) || hasParsingChapter || generatingChapterIndices.size > 0 || segments.some(s => s.status === 'generating')
useEffect(() => {
if (!shouldPoll || !selectedProjectId) return
@@ -1235,7 +1241,7 @@ export default function Audiobook() {
}
}
const handleGenerate = async (chapterIndex?: number) => {
const handleGenerate = async (chapterIndex?: number, force?: boolean) => {
if (!selectedProject) return
setLoadingAction(true)
if (chapterIndex !== undefined) {
@@ -1244,7 +1250,7 @@ export default function Audiobook() {
setIsPolling(true)
}
try {
await audiobookApi.generate(selectedProject.id, chapterIndex)
await audiobookApi.generate(selectedProject.id, chapterIndex, force)
toast.success(chapterIndex !== undefined
? t('projectCard.chapters.generateStarted', { index: chapterIndex + 1 })
: t('projectCard.chapters.generateAllStarted'))
@@ -1365,7 +1371,6 @@ export default function Audiobook() {
if (!selectedProject) return
try {
await audiobookApi.regenerateSegment(selectedProject.id, segmentId)
setIsPolling(true)
fetchSegments()
} catch (e: any) {
toast.error(formatApiError(e))