oss请求处理
This commit is contained in:
@@ -5,6 +5,7 @@ import { Download, Eye, ImageIcon, Info, Loader2, Music, RefreshCw, Trash2, X }
|
||||
import { clampPage, pageItems, Pagination } from "@/components/pagination";
|
||||
import { modalEnter, modalExit, pulseFeedback, revealChildren, runScopedMotion } from "@/lib/ui/motion";
|
||||
import { formatBillingAmount } from "@/lib/billing";
|
||||
import { assetPreviewUrl } from "@/lib/client/asset-urls";
|
||||
import type { Asset, GenerationJob } from "@/lib/types";
|
||||
|
||||
type AssetView = "assets" | "tasks";
|
||||
@@ -386,10 +387,10 @@ function renderAssetPreview(asset: Asset) {
|
||||
);
|
||||
}
|
||||
if (asset.kind === "video" || isVideo(asset)) {
|
||||
return <video className="asset-thumb" src={asset.url} muted playsInline preload="metadata" />;
|
||||
return <video className="asset-thumb" src={assetPreviewUrl(asset)} muted playsInline preload="metadata" />;
|
||||
}
|
||||
if (asset.kind === "image" || asset.kind === "mask" || asset.kind === "reference" || isImage(asset)) {
|
||||
return <img className="asset-thumb" src={asset.url} alt={asset.name} />;
|
||||
return <img className="asset-thumb" src={assetPreviewUrl(asset)} alt={asset.name} />;
|
||||
}
|
||||
return (
|
||||
<div className="asset-placeholder asset-kind-placeholder">
|
||||
@@ -400,10 +401,10 @@ function renderAssetPreview(asset: Asset) {
|
||||
}
|
||||
|
||||
function renderAssetPreviewLarge(asset: Asset) {
|
||||
if (isAudio(asset)) return <audio src={asset.url} controls />;
|
||||
if (asset.kind === "video" || isVideo(asset)) return <video src={asset.url} controls playsInline />;
|
||||
if (isAudio(asset)) return <audio src={assetPreviewUrl(asset)} controls />;
|
||||
if (asset.kind === "video" || isVideo(asset)) return <video src={assetPreviewUrl(asset)} controls playsInline />;
|
||||
if (asset.kind === "image" || asset.kind === "mask" || asset.kind === "reference" || isImage(asset)) {
|
||||
return <img src={asset.url} alt={asset.name} />;
|
||||
return <img src={assetPreviewUrl(asset)} alt={asset.name} />;
|
||||
}
|
||||
return (
|
||||
<div className="asset-placeholder asset-kind-placeholder">
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from "@/lib/prompt/material-draft";
|
||||
import { extractMaterialPlaceholders } from "@/lib/prompt/material-placeholders";
|
||||
import { formatBillingAmount } from "@/lib/billing";
|
||||
import { assetPreviewUrl, materialPreviewUrl, storedAssetPreviewUrl } from "@/lib/client/asset-urls";
|
||||
import type { BillingQuote } from "@/lib/types";
|
||||
|
||||
type GenerateMode = "image" | "video";
|
||||
@@ -217,6 +218,7 @@ export function CreateStudio({ initialMode = "image" }: { initialMode?: Generate
|
||||
() => recentJobs.find((job) => job.id === taskDetailJobId) || null,
|
||||
[recentJobs, taskDetailJobId]
|
||||
);
|
||||
const previewTemplateImageURL = storedAssetPreviewUrl(previewTemplate?.previewImageUrl, taskAssets);
|
||||
const hasLiveTasks = useMemo(() => recentJobs.some((job) => !isTerminalStatus(job.status)), [recentJobs]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -476,7 +478,7 @@ export function CreateStudio({ initialMode = "image" }: { initialMode?: Generate
|
||||
const [asset] = await uploadAssetFiles([file]);
|
||||
setTemplateForm((form) => ({
|
||||
...form,
|
||||
previewImageUrl: asset.url,
|
||||
previewImageUrl: assetPreviewUrl(asset),
|
||||
name: form.name || asset.name.replace(/\.[^.]+$/, "")
|
||||
}));
|
||||
} catch (err) {
|
||||
@@ -608,7 +610,10 @@ export function CreateStudio({ initialMode = "image" }: { initialMode?: Generate
|
||||
}
|
||||
|
||||
function openTemplateEditor(template: ImageTemplate) {
|
||||
setTemplateForm(formFromTemplate(template));
|
||||
setTemplateForm({
|
||||
...formFromTemplate(template),
|
||||
previewImageUrl: storedAssetPreviewUrl(template.previewImageUrl, taskAssets)
|
||||
});
|
||||
setEditingTemplateId(template.id);
|
||||
setTemplateError(null);
|
||||
setMaterialDraft(null);
|
||||
@@ -919,7 +924,7 @@ export function CreateStudio({ initialMode = "image" }: { initialMode?: Generate
|
||||
aria-label={`放大预览 ${template.name}`}
|
||||
onClick={() => setPreviewTemplate(template)}
|
||||
>
|
||||
{renderImageTemplatePreview(template)}
|
||||
{renderImageTemplatePreview(template, taskAssets)}
|
||||
</button>
|
||||
<div className="image-template-card-footer">
|
||||
<div className="image-template-card-copy">
|
||||
@@ -1363,11 +1368,11 @@ export function CreateStudio({ initialMode = "image" }: { initialMode?: Generate
|
||||
</button>
|
||||
</div>
|
||||
<div className="template-preview-dialog-media">
|
||||
{previewTemplate.previewImageUrl ? <img src={previewTemplate.previewImageUrl} alt="" /> : <ImagePlus size={40} />}
|
||||
{previewTemplateImageURL ? <img src={previewTemplateImageURL} alt="" /> : <ImagePlus size={40} />}
|
||||
</div>
|
||||
<div className="template-preview-dialog-actions">
|
||||
{previewTemplate.previewImageUrl ? (
|
||||
<a className="button" href={previewTemplate.previewImageUrl} download>
|
||||
{previewTemplateImageURL ? (
|
||||
<a className="button" href={previewTemplateImageURL} download>
|
||||
<Download size={16} />
|
||||
下载图片
|
||||
</a>
|
||||
@@ -1495,8 +1500,8 @@ function renderTaskThumbnail(job: GenerationJob, assetById: Map<string, Asset>)
|
||||
}
|
||||
const isVideo = asset.kind === "video" || materialTypeForAsset(asset) === "video";
|
||||
const media = isVideo
|
||||
? <video src={asset.url} muted playsInline preload="metadata" />
|
||||
: <img src={asset.url} alt="" />;
|
||||
? <video src={assetPreviewUrl(asset)} muted playsInline preload="metadata" />
|
||||
: <img src={assetPreviewUrl(asset)} alt="" />;
|
||||
return <div className="create-task-thumb" aria-hidden="true">{media}</div>;
|
||||
}
|
||||
|
||||
@@ -1698,9 +1703,9 @@ function BillingEstimate({
|
||||
|
||||
function renderTaskAssetMedia(asset: Asset, size: "thumb" | "large" = "large") {
|
||||
const type = materialTypeForAsset(asset);
|
||||
if (type === "video") return <video className={`task-detail-media ${size}`} src={asset.url} controls={size === "large"} muted={size === "thumb"} playsInline preload="metadata" />;
|
||||
if (type === "audio") return <audio className="task-detail-audio" src={asset.url} controls />;
|
||||
return <img className={`task-detail-media ${size}`} src={asset.url} alt={asset.name} />;
|
||||
if (type === "video") return <video className={`task-detail-media ${size}`} src={assetPreviewUrl(asset)} controls={size === "large"} muted={size === "thumb"} playsInline preload="metadata" />;
|
||||
if (type === "audio") return <audio className="task-detail-audio" src={assetPreviewUrl(asset)} controls />;
|
||||
return <img className={`task-detail-media ${size}`} src={assetPreviewUrl(asset)} alt={asset.name} />;
|
||||
}
|
||||
|
||||
function renderMaterialUrlPreview(url: string, type: MaterialKind) {
|
||||
@@ -1892,10 +1897,11 @@ function formatDuration(ms: number) {
|
||||
}
|
||||
|
||||
function renderMaterialPreview(material: PromptMaterial, size: "normal" | "tiny" | "large" = "normal") {
|
||||
const previewURL = materialPreviewUrl(material);
|
||||
return (
|
||||
<span className={clsx("material-preview", size, material.type)} aria-hidden="true">
|
||||
{material.type === "image" ? <img src={material.url} alt="" /> : null}
|
||||
{material.type === "video" ? <video src={material.url} muted playsInline preload="metadata" /> : null}
|
||||
{material.type === "image" ? <img src={previewURL} alt="" /> : null}
|
||||
{material.type === "video" ? <video src={previewURL} muted playsInline preload="metadata" /> : null}
|
||||
{material.type === "audio" ? <Music size={size === "tiny" ? 13 : size === "large" ? 20 : 15} /> : null}
|
||||
</span>
|
||||
);
|
||||
@@ -1966,10 +1972,11 @@ function sortTemplates(a: ImageTemplate, b: ImageTemplate) {
|
||||
return (b.updatedAt || "").localeCompare(a.updatedAt || "");
|
||||
}
|
||||
|
||||
function renderImageTemplatePreview(template: ImageTemplate) {
|
||||
function renderImageTemplatePreview(template: ImageTemplate, assets: Asset[]) {
|
||||
const previewURL = storedAssetPreviewUrl(template.previewImageUrl, assets);
|
||||
return (
|
||||
<span className="image-template-preview" aria-hidden="true">
|
||||
{template.previewImageUrl ? <img src={template.previewImageUrl} alt="" /> : <ImagePlus size={22} />}
|
||||
{previewURL ? <img src={previewURL} alt="" /> : <ImagePlus size={22} />}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user