fix: optimize agent style workspace rendering
This commit is contained in:
parent
31a697f491
commit
65b3e2f191
@ -9,6 +9,7 @@ import {
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
type CSSProperties,
|
||||
type ReactNode,
|
||||
type SyntheticEvent,
|
||||
} from "react";
|
||||
@ -489,6 +490,16 @@ function buildPreviewImageUrl(url: string, width: number) {
|
||||
return buildImageProxyUrl(url, { width, quality: 86, format: "webp" });
|
||||
}
|
||||
|
||||
const AGENT_DEFERRED_SECTION_STYLE = {
|
||||
contentVisibility: "auto",
|
||||
containIntrinsicSize: "1px 760px",
|
||||
} as CSSProperties;
|
||||
|
||||
const AGENT_DEFERRED_RESULTS_STYLE = {
|
||||
contentVisibility: "auto",
|
||||
containIntrinsicSize: "1px 900px",
|
||||
} as CSSProperties;
|
||||
|
||||
function handlePreviewImageLoadError(
|
||||
event: SyntheticEvent<HTMLImageElement, Event>,
|
||||
originalUrl: string
|
||||
@ -5381,6 +5392,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(attachment.url, 360)}
|
||||
alt={attachment.name || slot.label}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-full w-full object-cover"
|
||||
onError={(event) => handlePreviewImageLoadError(event, attachment.url)}
|
||||
/>
|
||||
@ -5527,9 +5540,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
|
||||
{visibleAttachmentUploadSlots.map((slot, index) => {
|
||||
return (
|
||||
<motion.div
|
||||
<div
|
||||
key={slot.label}
|
||||
whileHover={{ scale: 1.02 }}
|
||||
className={cn(
|
||||
"group relative aspect-square overflow-hidden rounded-[24px] transition-all",
|
||||
attachments[index]
|
||||
@ -5551,6 +5563,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(attachments[index]!.url, 256)}
|
||||
alt={attachments[index]!.name || slot.label}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-full w-full object-cover"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, attachments[index]!.url)
|
||||
@ -5589,7 +5603,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
{attachments[index] ? "更换" : "上传"}
|
||||
</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
@ -5677,10 +5691,15 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.06 }}
|
||||
className="rounded-[28px] border border-white/12 bg-white/[0.04] p-5 shadow-[inset_0_1px_0_rgba(255,255,255,0.03)]"
|
||||
style={AGENT_DEFERRED_SECTION_STYLE}
|
||||
>
|
||||
<div className="space-y-6">
|
||||
{hasBrandStoreStep ? (
|
||||
<section id="agent-anchor-brand" className="scroll-mt-24 rounded-[24px] border border-white/10 bg-black/20 p-4">
|
||||
<section
|
||||
id="agent-anchor-brand"
|
||||
className="scroll-mt-24 rounded-[24px] border border-white/10 bg-black/20 p-4"
|
||||
style={AGENT_DEFERRED_SECTION_STYLE}
|
||||
>
|
||||
<div className="mb-4 flex flex-col gap-4 border-b border-white/10 pb-4 lg:flex-row lg:items-start lg:justify-between">
|
||||
<div className="space-y-1">
|
||||
<div className="flex items-center gap-2">
|
||||
@ -5699,7 +5718,11 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
) : null}
|
||||
|
||||
{hasWorkflowStyleStep ? (
|
||||
<section id="agent-anchor-style" className="scroll-mt-24 rounded-[24px] border border-white/10 bg-black/20 p-5 md:p-6">
|
||||
<section
|
||||
id="agent-anchor-style"
|
||||
className="scroll-mt-24 rounded-[24px] border border-white/10 bg-black/20 p-5 md:p-6"
|
||||
style={AGENT_DEFERRED_SECTION_STYLE}
|
||||
>
|
||||
<div className="mb-5 space-y-1 border-b border-white/10 pb-5">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="rounded-full bg-emerald-500/18 px-2.5 py-1 text-[11px] font-semibold text-emerald-200">
|
||||
@ -5721,7 +5744,11 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
) : null}
|
||||
|
||||
{isBusinessModeStepEnabled ? (
|
||||
<section id="agent-anchor-mode" className="scroll-mt-24 rounded-[24px] border border-white/10 bg-black/20 p-4">
|
||||
<section
|
||||
id="agent-anchor-mode"
|
||||
className="scroll-mt-24 rounded-[24px] border border-white/10 bg-black/20 p-4"
|
||||
style={AGENT_DEFERRED_SECTION_STYLE}
|
||||
>
|
||||
<div className="mb-4 space-y-1 border-b border-white/10 pb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="rounded-full bg-emerald-500/18 px-2.5 py-1 text-[11px] font-semibold text-emerald-200">
|
||||
@ -5776,6 +5803,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={mode.customSvgUrl}
|
||||
alt={mode.title}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-7 w-7 object-contain"
|
||||
/>
|
||||
) : (
|
||||
@ -5819,7 +5848,11 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
) : null}
|
||||
|
||||
{hasMaterialStep ? (
|
||||
<section id="agent-anchor-materials" className="scroll-mt-24 rounded-[24px] border border-white/10 bg-black/20 p-4">
|
||||
<section
|
||||
id="agent-anchor-materials"
|
||||
className="scroll-mt-24 rounded-[24px] border border-white/10 bg-black/20 p-4"
|
||||
style={AGENT_DEFERRED_SECTION_STYLE}
|
||||
>
|
||||
<div className="mb-4 space-y-1 border-b border-white/10 pb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="rounded-full bg-emerald-500/18 px-2.5 py-1 text-[11px] font-semibold text-emerald-200">
|
||||
@ -5835,7 +5868,11 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
</section>
|
||||
) : null}
|
||||
|
||||
<section id="agent-anchor-generate" className="scroll-mt-24 rounded-[24px] border border-white/10 bg-black/20 p-4">
|
||||
<section
|
||||
id="agent-anchor-generate"
|
||||
className="scroll-mt-24 rounded-[24px] border border-white/10 bg-black/20 p-4"
|
||||
style={AGENT_DEFERRED_SECTION_STYLE}
|
||||
>
|
||||
<div className="mb-4 space-y-1 border-b border-white/10 pb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="rounded-full bg-emerald-500/18 px-2.5 py-1 text-[11px] font-semibold text-emerald-200">
|
||||
@ -6162,6 +6199,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
initial={{ opacity: 0, scale: 0.98 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ delay: 0.08 }}
|
||||
style={AGENT_DEFERRED_SECTION_STYLE}
|
||||
>
|
||||
<div className="border-b border-white/12 px-5 py-4">
|
||||
<div className="flex flex-wrap items-start justify-between gap-3">
|
||||
@ -6388,6 +6426,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(primaryPreviewUrl, 360)}
|
||||
alt={candidate.sceneName || candidate.taskNo || candidate.productModel || "候选整套"}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-full w-full object-contain object-top transition-transform duration-500 group-hover:scale-[1.02]"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, primaryPreviewUrl)
|
||||
@ -6471,6 +6511,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
initial={{ opacity: 0, scale: 0.98 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ delay: 0.12 }}
|
||||
style={AGENT_DEFERRED_RESULTS_STYLE}
|
||||
>
|
||||
<div className="flex items-center justify-between border-b border-white/12 px-5 py-4">
|
||||
<div>
|
||||
@ -6657,6 +6698,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(attachment!.url, 400)}
|
||||
alt={attachment!.name || `输入图 ${index + 1}`}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-full w-full object-cover"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, attachment!.url)
|
||||
@ -6685,6 +6728,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(selectedModelAttachment.url, 720)}
|
||||
alt={selectedModelAttachment.name || "模特图"}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-full w-full object-cover"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, selectedModelAttachment.url)
|
||||
@ -6777,6 +6822,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(card.imageUrl, 720)}
|
||||
alt={card.label}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="block h-auto w-full"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, card.imageUrl || "")
|
||||
@ -6866,6 +6913,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(card.resultUrl, 720)}
|
||||
alt={`结果图 ${card.index + 1}`}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="block h-auto w-full cursor-zoom-in"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, card.resultUrl!)
|
||||
@ -7020,6 +7069,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(attachment!.url, 400)}
|
||||
alt={attachment!.name || `输入图 ${index + 1}`}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-full w-full object-cover"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, attachment!.url)
|
||||
@ -7048,6 +7099,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(selectedModelAttachment.url, 720)}
|
||||
alt={selectedModelAttachment.name || "模特图"}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-full w-full object-cover"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, selectedModelAttachment.url)
|
||||
@ -7193,6 +7246,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(previewUrl, 640)}
|
||||
alt={candidate.sceneName || candidate.taskNo || candidate.productModel || "候选整套"}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-full w-full object-cover"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, previewUrl)
|
||||
@ -7277,6 +7332,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(card.imageUrl, 720)}
|
||||
alt={card.label}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-full w-full object-cover"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, card.imageUrl || "")
|
||||
@ -7384,6 +7441,8 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={buildPreviewImageUrl(card.resultUrl, 720)}
|
||||
alt={`结果图 ${card.index + 1}`}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
className="h-full w-full cursor-zoom-in object-cover"
|
||||
onError={(event) =>
|
||||
handlePreviewImageLoadError(event, card.resultUrl!)
|
||||
@ -7551,6 +7610,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
alt={`${getResultModeLabel(activeResultModeType)} 结果图 ${card.index + 1}`}
|
||||
className="h-full w-full object-contain p-2"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
{isSceneResultCard ? (
|
||||
<>
|
||||
@ -7873,6 +7933,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<img
|
||||
src={fullscreenPreview}
|
||||
alt="预览"
|
||||
decoding="async"
|
||||
className="max-h-[95vh] max-w-[95vw] object-contain"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
/>
|
||||
|
||||
@ -111,12 +111,12 @@ const VIRTUAL_OPTION_GRID_GAP = 16;
|
||||
const VIRTUAL_OPTION_GRID_MAX_HEIGHT = 640;
|
||||
const VIRTUAL_OPTION_GRID_MIN_CARD_HEIGHT = 122;
|
||||
const VIRTUAL_OPTION_GRID_THRESHOLD = 12;
|
||||
const WORKFLOW_OPTION_PREVIEW_WIDTH = 360;
|
||||
const WORKFLOW_OPTION_PREVIEW_QUALITY = 58;
|
||||
const WORKFLOW_OPTION_PREVIEW_EAGER_COUNT = 4;
|
||||
const WORKFLOW_OPTION_NEXT_PREVIEW_PREFETCH_COUNT = 6;
|
||||
const WORKFLOW_OPTION_PREFETCH_CACHE_LIMIT = 48;
|
||||
const WORKFLOW_OPTION_PREFETCH_BATCH_SIZE = 2;
|
||||
const WORKFLOW_OPTION_PREVIEW_WIDTH = 320;
|
||||
const WORKFLOW_OPTION_PREVIEW_QUALITY = 56;
|
||||
const WORKFLOW_OPTION_PREVIEW_EAGER_COUNT = 2;
|
||||
const WORKFLOW_OPTION_NEXT_PREVIEW_PREFETCH_COUNT = 3;
|
||||
const WORKFLOW_OPTION_PREFETCH_CACHE_LIMIT = 30;
|
||||
const WORKFLOW_OPTION_PREFETCH_BATCH_SIZE = 1;
|
||||
|
||||
function isLikelyStoredWorkflowPreview(url: string, sourceUrl?: string | null) {
|
||||
const source = String(sourceUrl || "").trim();
|
||||
@ -472,8 +472,8 @@ const StepOptionCard = memo(function StepOptionCard({
|
||||
handleWorkflowOptionPreviewError(event, option.previewImageUrl)
|
||||
}
|
||||
className={cn(
|
||||
"h-full w-full object-cover transition-transform duration-700",
|
||||
!disabled && "group-hover:scale-110"
|
||||
"h-full w-full object-cover transition-transform duration-500",
|
||||
!disabled && "group-hover:scale-[1.04]"
|
||||
)}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-transparent" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user