fix(canvas): block invalid video duration confirmation

This commit is contained in:
2026-08-18 11:32:38 +08:00
parent 566f99f5ed
commit 11b19832a3
3 changed files with 39 additions and 1 deletions

View File

@@ -268,6 +268,20 @@ type EditableGenerationParameters = Partial<Pick<
const MIN_VIDEO_DURATION_SECONDS = 2;
const MAX_VIDEO_DURATION_SECONDS = 6;
function hasSelectableVideoDuration(
quote: DesignGenerationQuote,
parameters: DesignGenerationParameters,
): boolean {
if (quote.medium !== 'video') return true;
const durationSeconds = parameters.durationSeconds;
return durationSeconds !== null
&& durationSeconds >= MIN_VIDEO_DURATION_SECONDS
&& durationSeconds <= MAX_VIDEO_DURATION_SECONDS
&& quote.generationOptions.durations.some((option) => (
!option.disabled && option.value === durationSeconds
));
}
function quoteDraftFromQuote(quote: DesignGenerationQuote): GenerationQuoteDraft {
return {
quoteId: quote.quoteId,
@@ -740,6 +754,10 @@ function QuoteCard({
const selectedDuration = availableDurations.some(
(option) => option.value === draft.generationParameters.durationSeconds,
) ? String(draft.generationParameters.durationSeconds) : '';
const durationSelectionValid = hasSelectableVideoDuration(
quote,
draft.generationParameters,
);
const updateParameters = (next: EditableGenerationParameters) => {
onDraftChange({
...draft,
@@ -867,7 +885,7 @@ function QuoteCard({
size="sm"
className="h-8 rounded-full bg-brand px-3 text-xs font-semibold text-primary-foreground"
onClick={onConfirm}
disabled={busy || dirty || repricing}
disabled={busy || dirty || repricing || !durationSelectionValid}
>
{busy || repricing
? <Loader2 className="mr-1.5 h-3.5 w-3.5 animate-spin" />
@@ -1153,6 +1171,7 @@ export function ImageCanvas() {
setQuoteDirty(true);
setRepricingQuoteId(quote.quoteId);
setQuoteUpdateError(null);
setActionError(null);
quoteDraftVersionRef.current += 1;
const version = quoteDraftVersionRef.current;
if (quoteRepriceTimerRef.current !== null) clearTimeout(quoteRepriceTimerRef.current);
@@ -1189,6 +1208,11 @@ export function ImageCanvas() {
setActionError('当前报价正在更新,请等待重新报价完成后再确认。');
return;
}
if (!quote || quote.quoteId !== quoteId
|| !hasSelectableVideoDuration(quote, draft.generationParameters)) {
setActionError('请选择 2 至 6 秒的视频时长,等待重新报价完成后再确认。');
return;
}
const requestedWorkspaceId = workspace.workspaceId;
const requestedConversationId = conversation.conversationId;
setConfirmingQuoteId(quoteId);