From 28965a1fa8d01c03f327ffbc06bc7622a21cd09f Mon Sep 17 00:00:00 2001 From: admin Date: Tue, 23 Jun 2026 05:21:40 +0800 Subject: [PATCH] fix: popover within image bounds, translate quality/style, copy prompt only, group label fix --- .../src/features/image-playground/api.ts | 2 +- .../components/image-results.tsx | 80 +++++++++---------- web/default/src/i18n/locales/zh.json | 8 +- 3 files changed, 48 insertions(+), 42 deletions(-) diff --git a/web/default/src/features/image-playground/api.ts b/web/default/src/features/image-playground/api.ts index 5fabad991..ad86d3775 100644 --- a/web/default/src/features/image-playground/api.ts +++ b/web/default/src/features/image-playground/api.ts @@ -197,7 +197,7 @@ export async function getUserGroups(): Promise { } return Object.entries(groupsMap).map(([key, val]) => ({ - label: val?.desc || key, + label: key, value: key, ratio: typeof val?.ratio === 'number' ? val.ratio : undefined, desc: val?.desc, diff --git a/web/default/src/features/image-playground/components/image-results.tsx b/web/default/src/features/image-playground/components/image-results.tsx index 8d9349545..02aaa2bff 100644 --- a/web/default/src/features/image-playground/components/image-results.tsx +++ b/web/default/src/features/image-playground/components/image-results.tsx @@ -13,6 +13,7 @@ import { PopoverTrigger, } from '@/components/ui/popover' import { useState } from 'react' +import { QUALITY_OPTIONS, STYLE_OPTIONS } from '../types' import type { GeneratedImage, GeneratedImageParams } from '../types' type ImageResultsProps = { @@ -31,17 +32,14 @@ function formatDuration(ms: number): string { return `${(ms / 1000).toFixed(1)}s` } -function formatParamsText(params: GeneratedImageParams): string { - const lines = [ - `Prompt: ${params.prompt}`, - `Model: ${params.model}`, - `Group: ${params.group}`, - `Size: ${params.size}`, - `Quality: ${params.quality}`, - `Style: ${params.style}`, - `Count: ${params.n}`, - ] - return lines.join('\n') +function getTranslatedOptionLabel( + options: readonly { value: string; label: string }[], + value: string, + t: (key: string) => string +): string { + const opt = options.find((o) => o.value === value) + if (!opt) return value + return t(opt.label) } function ImageParamsPopover({ image, onFillParams }: { image: GeneratedImage; onFillParams?: (params: GeneratedImageParams) => void }) { @@ -49,9 +47,9 @@ function ImageParamsPopover({ image, onFillParams }: { image: GeneratedImage; on const params = image.params if (!params) return null - const handleCopy = async () => { + const handleCopyPrompt = async () => { try { - await navigator.clipboard.writeText(formatParamsText(params)) + await navigator.clipboard.writeText(params.prompt) toast.success(t('Copied')) } catch { toast.error(t('Copy failed')) @@ -71,13 +69,15 @@ function ImageParamsPopover({ image, onFillParams }: { image: GeneratedImage; on e.preventDefault()} > -
+
{t('Generation Parameters')}
@@ -85,9 +85,9 @@ function ImageParamsPopover({ image, onFillParams }: { image: GeneratedImage; on type='button' variant='ghost' size='icon' - className='size-6' - onClick={handleCopy} - title={t('Copy')} + className='size-5' + onClick={handleCopyPrompt} + title={t('Copy prompt')} > @@ -96,7 +96,7 @@ function ImageParamsPopover({ image, onFillParams }: { image: GeneratedImage; on type='button' variant='ghost' size='icon' - className='size-6' + className='size-5' onClick={handleFill} title={t('Reuse parameters')} > @@ -106,38 +106,38 @@ function ImageParamsPopover({ image, onFillParams }: { image: GeneratedImage; on
-
+
{t('Prompt')}: {params.prompt}
-
+
{t('Model')}: - {params.model} + {params.model}
-
+
{t('Group')}: - {params.group} + {params.group}
-
+
{t('Size')}: {params.size}
-
+
{t('Quality')}: - {params.quality} + {getTranslatedOptionLabel(QUALITY_OPTIONS, params.quality, t)}
-
+
{t('Style')}: - {params.style} + {getTranslatedOptionLabel(STYLE_OPTIONS, params.style, t)}
-
+
{t('Count')}: {params.n}
{image.revisedPrompt && ( -
+
{t('Revised Prompt')}: {image.revisedPrompt}
@@ -266,14 +266,14 @@ export function ImageResults({ {images.map((image) => (
{image.status === 'pending' ? ( -
+
) : image.status === 'failed' ? ( -
+
{onDeleteImage && (
- +
)}
))} diff --git a/web/default/src/i18n/locales/zh.json b/web/default/src/i18n/locales/zh.json index 4564e1a54..8a4a0d44c 100644 --- a/web/default/src/i18n/locales/zh.json +++ b/web/default/src/i18n/locales/zh.json @@ -4904,6 +4904,12 @@ "Click or drag to upload reference images": "点击或拖拽上传参考图", "Generation Parameters": "生成参数", "Reuse parameters": "填入参数", - "Revised Prompt": "修订提示词" + "Copy prompt": "复制提示词", + "Revised Prompt": "修订提示词", + "Standard": "标准", + "HD": "高清", + "Default": "默认", + "Vivid": "生动", + "Natural": "自然" } }