fix: jump to playground from model list
This commit is contained in:
@@ -19,6 +19,7 @@ const AutoImage: React.FC<
|
||||
height: number | string;
|
||||
width?: number | string;
|
||||
autoSize?: boolean;
|
||||
onLoad?: () => void;
|
||||
}
|
||||
> = (props) => {
|
||||
const { height = 100, width: w, autoSize, ...rest } = props;
|
||||
@@ -62,6 +63,10 @@ const AutoImage: React.FC<
|
||||
link.remove();
|
||||
};
|
||||
|
||||
const handleImgLoad = useCallback(() => {
|
||||
props.onLoad?.();
|
||||
}, [props.onLoad]);
|
||||
|
||||
const handleOnError = () => {
|
||||
setIsError(true);
|
||||
};
|
||||
@@ -76,7 +81,9 @@ const AutoImage: React.FC<
|
||||
height={isError ? 'auto' : height}
|
||||
width={isError ? '100%' : width}
|
||||
onError={handleOnError}
|
||||
onLoad={handleImgLoad}
|
||||
fallback={fallbackImg}
|
||||
crossOrigin="anonymous"
|
||||
preview={{
|
||||
mask: <EyeOutlined />,
|
||||
toolbarRender: (
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
.thumb-img {
|
||||
position: relative;
|
||||
display: flex;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: var(--border-radius-base);
|
||||
overflow: hidden;
|
||||
|
||||
.img {
|
||||
display: flex;
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
border-radius: var(--border-radius-base);
|
||||
cursor: pointer;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.del {
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
right: -2px;
|
||||
font-size: var(--font-size-middle);
|
||||
cursor: pointer;
|
||||
background-color: var(--color-white-1);
|
||||
display: none;
|
||||
border-radius: 50%;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
overflow: hidden;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.ant-image .ant-image-mask {
|
||||
opacity: 1;
|
||||
transition: opacity var(--ant-motion-duration-slow);
|
||||
}
|
||||
|
||||
.del {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.single-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
border-radius: var(--border-radius-base);
|
||||
|
||||
&.auto-bg-color {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
backdrop-filter: blur(100px);
|
||||
backdrop-filter: blur(100px);
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.thumb-img {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
border-radius: 0;
|
||||
|
||||
.img {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-image {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||
import { Progress } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import * as Vibrant from 'node-vibrant';
|
||||
import React from 'react';
|
||||
import AutoImage from './index';
|
||||
import './single-image.less';
|
||||
|
||||
interface SingleImageProps {
|
||||
loading?: boolean;
|
||||
width?: number;
|
||||
height?: number;
|
||||
progress?: number;
|
||||
maxHeight?: number;
|
||||
maxWidth?: number;
|
||||
dataUrl: string;
|
||||
uid: number;
|
||||
autoSize?: boolean;
|
||||
onDelete: (uid: number) => void;
|
||||
autoBgColor?: boolean;
|
||||
editable?: boolean;
|
||||
}
|
||||
|
||||
const SingleImage: React.FC<SingleImageProps> = (props) => {
|
||||
const {
|
||||
editable,
|
||||
onDelete: handleOnDelete,
|
||||
autoSize,
|
||||
uid,
|
||||
loading,
|
||||
width,
|
||||
height,
|
||||
progress,
|
||||
maxHeight,
|
||||
maxWidth,
|
||||
dataUrl,
|
||||
autoBgColor
|
||||
} = props;
|
||||
|
||||
const [color, setColor] = React.useState<string>('');
|
||||
const imgWrapper = React.useRef<HTMLSpanElement>(null);
|
||||
|
||||
const thumImgWrapStyle = React.useMemo(() => {
|
||||
return loading ? { width: width, height: height } : {};
|
||||
}, [loading, width, height]);
|
||||
|
||||
const handleOnLoad = React.useCallback(async () => {
|
||||
if (!autoBgColor) {
|
||||
return;
|
||||
}
|
||||
const img = imgWrapper.current?.querySelector('img');
|
||||
if (!img) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vibrant.from(img.src).getPalette((err: any, palette: any) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
const color = palette?.Vibrant?.rgb;
|
||||
const rgba = color
|
||||
? `rgba(${color[0]}, ${color[1]}, ${color[2]},0.7)`
|
||||
: '';
|
||||
setColor(rgba);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
key={uid}
|
||||
className={classNames('single-image', { 'auto-bg-color': autoBgColor })}
|
||||
>
|
||||
{autoBgColor && (
|
||||
<div
|
||||
className="mask"
|
||||
style={{
|
||||
background: `url(${dataUrl}) center center / cover no-repeat`
|
||||
}}
|
||||
></div>
|
||||
)}
|
||||
<span
|
||||
className="thumb-img"
|
||||
style={{
|
||||
...thumImgWrapStyle
|
||||
}}
|
||||
ref={imgWrapper}
|
||||
>
|
||||
<>
|
||||
{loading ? (
|
||||
<span
|
||||
className="progress-wrap"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
border: '1px solid var(--ant-color-split)',
|
||||
borderRadius: 'var(--border-radius-base)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
padding: '10px',
|
||||
overflow: 'hidden'
|
||||
}}
|
||||
>
|
||||
<Progress percent={progress} type="circle" />
|
||||
</span>
|
||||
) : (
|
||||
<span
|
||||
className="img"
|
||||
style={{
|
||||
maxHeight: `min(${maxHeight}, 100%)`,
|
||||
maxWidth: `min(${maxWidth}, 100%)`
|
||||
}}
|
||||
>
|
||||
<AutoImage
|
||||
autoSize={autoSize}
|
||||
src={dataUrl}
|
||||
width={width || 100}
|
||||
height={height || 100}
|
||||
onLoad={handleOnLoad}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
|
||||
{editable && (
|
||||
<span className="del" onClick={() => handleOnDelete(uid)}>
|
||||
<CloseCircleOutlined />
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(SingleImage);
|
||||
Reference in New Issue
Block a user