f67d228c02
新增精选素材分组模型,按素材包、角色、UI、音乐、美宣等分类组合展示素材 补齐素材卡片和预览弹窗中的提示词、作者与生成总成本展示 新增接近全屏的素材预览弹窗,支持底部外置缩略图导航切换 让私有图片、视频和音频预览携带 objectKey 换签读取 补充创作主页素材展示文档和聚焦测试
73 lines
1.7 KiB
TypeScript
73 lines
1.7 KiB
TypeScript
import React, { type ImgHTMLAttributes, useEffect, useState } from 'react';
|
|
|
|
import { useResolvedAssetReadUrl } from '../hooks/useResolvedAssetReadUrl';
|
|
import { RuntimeResourcePendingMarker } from './common/RuntimeResourcePendingMarker';
|
|
|
|
type ResolvedAssetImageProps = Omit<
|
|
ImgHTMLAttributes<HTMLImageElement>,
|
|
'src'
|
|
> & {
|
|
src?: string | null;
|
|
objectKey?: string | null;
|
|
fallbackSrc?: string | null;
|
|
refreshKey?: string | number | null;
|
|
};
|
|
|
|
export function ResolvedAssetImage({
|
|
src,
|
|
objectKey,
|
|
fallbackSrc,
|
|
alt,
|
|
refreshKey,
|
|
onError,
|
|
...rest
|
|
}: ResolvedAssetImageProps) {
|
|
const { resolvedUrl, isResolving, shouldResolve } = useResolvedAssetReadUrl(src, {
|
|
objectKey,
|
|
refreshKey,
|
|
});
|
|
const normalizedSource = src?.trim() ?? '';
|
|
const normalizedFallbackSrc = fallbackSrc?.trim() ?? '';
|
|
const [useFallbackSrc, setUseFallbackSrc] = useState(false);
|
|
const finalSrc =
|
|
useFallbackSrc && normalizedFallbackSrc
|
|
? normalizedFallbackSrc
|
|
: resolvedUrl || normalizedFallbackSrc;
|
|
const pendingMarker = (
|
|
<RuntimeResourcePendingMarker
|
|
source={normalizedSource}
|
|
kind="image"
|
|
isPending={shouldResolve && isResolving}
|
|
/>
|
|
);
|
|
|
|
useEffect(() => {
|
|
setUseFallbackSrc(false);
|
|
}, [normalizedFallbackSrc, resolvedUrl]);
|
|
|
|
if (!finalSrc) {
|
|
return pendingMarker;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{pendingMarker}
|
|
<img
|
|
{...rest}
|
|
src={finalSrc}
|
|
alt={alt}
|
|
onError={(event) => {
|
|
if (
|
|
normalizedFallbackSrc &&
|
|
!useFallbackSrc &&
|
|
finalSrc !== normalizedFallbackSrc
|
|
) {
|
|
setUseFallbackSrc(true);
|
|
}
|
|
onError?.(event);
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
}
|