Fix image generation count selector

This commit is contained in:
FengLee
2026-05-12 19:42:06 +08:00
parent 4d5ec0b6b5
commit b9a8521d1b
3 changed files with 41 additions and 56 deletions

View File

@@ -45,6 +45,7 @@ Use this guide when the user reports behavior. Start from the symptom row, inspe
| Reference image upload too large or fails | `src/components/create/image-to-image.tsx`, `src/components/create/image-to-video.tsx`, `src/lib/browser-image-compression.ts`, `src/lib/server-image-compression.ts`, `src/app/api/generate/image/route.ts`, `src/app/api/generate/video/route.ts` | Browser compression, `MAX_UPSTREAM_REFERENCE_IMAGE_BYTES`, data URL conversion. |
| Generated result previews but does not persist | `src/app/api/generate/image/route.ts`, `src/app/api/generate/video/route.ts`, `src/lib/local-storage.ts`, `src/app/api/creation-history/route.ts` | Media copied to local storage, presigned URL returned, history POST called. |
| Fullscreen/preview/download broken | `src/components/fullscreen-preview.tsx`, `src/components/lightbox.tsx`, `src/components/creation-detail-dialog.tsx`, `src/app/api/download/route.ts` | Dialog state, URL type, download proxy supports local/remote URL. |
| Image generation count dropdown too wide or options missing | `src/components/create/text-to-image.tsx`, `src/components/create/image-to-image.tsx` | Use the shared Radix `Select` pattern instead of browser `datalist`; keep the trigger narrow and verify options render in both text-to-image and image-to-image panels. |
| Reverse prompt option missing | `src/components/create/reverse-prompt-panel.tsx`, `src/app/api/generate/reverse-prompt/route.ts` | UI option list and server `outputMode` handling both updated, app rebuilt/restarted if deployed. |
| Prompt optimization fails | `src/app/api/generate/suggest-prompt/route.ts`, `src/lib/server-api-config.ts`, `src/lib/custom-api-fetch.ts` | Text-capable system/custom API, chat response shape, JSON parsing fallback. |

View File

@@ -2,7 +2,6 @@
import { useState, useCallback, useRef, useMemo, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Label } from '@/components/ui/label';
import { Slider } from '@/components/ui/slider';
@@ -49,19 +48,13 @@ import { compressImageFileForUpload } from '@/lib/browser-image-compression';
import { StylePresetSelector } from '@/components/create/style-preset-selector';
const IMAGE_TO_IMAGE_DRAFT_KEY = 'miaojing:image-to-image-draft';
const IMAGE_COUNT_DATALIST_OPTIONS = ['自动', '1', '2', '4'] as const;
function toCountInputValue(value: string): string {
return value === 'auto' ? '自动' : value;
}
function normalizeCountInputValue(value: string): string {
const trimmed = value.trim();
if (!trimmed || trimmed === '自动' || trimmed.toLowerCase() === 'auto') return 'auto';
const numeric = trimmed.match(/\d+/)?.[0];
if (!numeric) return trimmed;
return String(Math.min(10, Math.max(1, Math.floor(Number(numeric)))));
}
const IMAGE_COUNT_OPTIONS = [
{ value: 'auto', label: '自动' },
{ value: '1', label: '1 张' },
{ value: '2', label: '2 张' },
{ value: '3', label: '3 张' },
{ value: '4', label: '4 张' },
] as const;
interface RefImage {
id: string;
@@ -661,20 +654,19 @@ export function ImageToImagePanel() {
{/* Count */}
<div className="space-y-2">
<Label htmlFor="image-to-image-count"></Label>
<Input
id="image-to-image-count"
list="image-to-image-count-options"
inputMode="numeric"
value={toCountInputValue(count)}
onChange={e => setCount(normalizeCountInputValue(e.target.value))}
placeholder="自动"
/>
<datalist id="image-to-image-count-options">
{IMAGE_COUNT_DATALIST_OPTIONS.map(option => (
<option key={option} value={option} />
))}
</datalist>
<Label></Label>
<Select value={count} onValueChange={setCount}>
<SelectTrigger className="w-28">
<SelectValue placeholder="自动" />
</SelectTrigger>
<SelectContent align="start" className="min-w-28">
{IMAGE_COUNT_OPTIONS.map(option => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* Generate */}

View File

@@ -2,7 +2,6 @@
import { useState, useCallback, useRef, useMemo, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Label } from '@/components/ui/label';
import { Slider } from '@/components/ui/slider';
@@ -47,19 +46,13 @@ import { GenerationLoadingPanel } from '@/components/create/generation-loading-p
import { StylePresetSelector } from '@/components/create/style-preset-selector';
const TEXT_TO_IMAGE_DRAFT_KEY = 'miaojing:text-to-image-draft';
const IMAGE_COUNT_DATALIST_OPTIONS = ['自动', '1', '2', '4'] as const;
function toCountInputValue(value: string): string {
return value === 'auto' ? '自动' : value;
}
function normalizeCountInputValue(value: string): string {
const trimmed = value.trim();
if (!trimmed || trimmed === '自动' || trimmed.toLowerCase() === 'auto') return 'auto';
const numeric = trimmed.match(/\d+/)?.[0];
if (!numeric) return trimmed;
return String(Math.min(10, Math.max(1, Math.floor(Number(numeric)))));
}
const IMAGE_COUNT_OPTIONS = [
{ value: 'auto', label: '自动' },
{ value: '1', label: '1 张' },
{ value: '2', label: '2 张' },
{ value: '3', label: '3 张' },
{ value: '4', label: '4 张' },
] as const;
export function TextToImagePanel() {
const { user, accessToken } = useAuth();
@@ -481,20 +474,19 @@ export function TextToImagePanel() {
{/* Count */}
<div className="space-y-2">
<Label htmlFor="text-to-image-count"></Label>
<Input
id="text-to-image-count"
list="text-to-image-count-options"
inputMode="numeric"
value={toCountInputValue(count)}
onChange={e => setCount(normalizeCountInputValue(e.target.value))}
placeholder="自动"
/>
<datalist id="text-to-image-count-options">
{IMAGE_COUNT_DATALIST_OPTIONS.map(option => (
<option key={option} value={option} />
))}
</datalist>
<Label></Label>
<Select value={count} onValueChange={setCount}>
<SelectTrigger className="w-28">
<SelectValue placeholder="自动" />
</SelectTrigger>
<SelectContent align="start" className="min-w-28">
{IMAGE_COUNT_OPTIONS.map(option => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* Generate Button */}