fix(style): image size cache'

main
jialin 1 year ago
parent 50c740d219
commit b1d13f5a71

@ -14,7 +14,7 @@ const isProduction = env === 'production';
const t = Date.now();
export default defineConfig({
proxy: {
...proxy('http://192.168.50.4')
...proxy('http://192.168.50.5')
},
history: {
type: 'hash'

@ -11,3 +11,9 @@
image-rendering: crisp-edges;
}
}
.scroller-wrapper {
width: 100%;
height: 100%;
overflow: hidden;
}

@ -1,5 +1,5 @@
import useResizeObserver from '@/components/logs-viewer/use-size';
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import './index.less';
interface AudioAnimationProps {
@ -7,6 +7,7 @@ interface AudioAnimationProps {
height: number;
scaleFactor?: number;
maxBarCount?: number;
fixedHeight?: boolean;
analyserData: {
data: Uint8Array;
analyser: any;
@ -17,20 +18,22 @@ const AudioAnimation: React.FC<AudioAnimationProps> = (props) => {
const {
scaleFactor = 1.2,
maxBarCount = 128,
fixedHeight = true,
analyserData,
width,
height
width: initialWidth,
height: initialHeight
} = props;
const canvasRef = React.useRef<HTMLCanvasElement>(null);
const animationId = React.useRef<number>(0);
const isScaled = React.useRef<boolean>(false);
const oscillationOffset = React.useRef(0);
const direction = React.useRef(1);
// const [width, setWidth] = useState(props.width);
// const [height, setHeight] = useState(props.height);
const scrollerRef = React.useRef<HTMLDivElement>(null);
const [width, setWidth] = useState(initialWidth);
const [height, setHeight] = useState(initialHeight);
const containerRef = React.useRef<any>(null);
const size = useResizeObserver(containerRef);
const size = useResizeObserver(scrollerRef);
const calculateJitter = (
i: number,
@ -128,26 +131,14 @@ const AudioAnimation: React.FC<AudioAnimationProps> = (props) => {
draw(performance.now());
};
// const handleResizeThrottle = React.useCallback(
// throttle(() => {
// console.log('size:', size);
// if (size.width && size.width !== width) {
// setWidth(size.width);
// }
// if (size.height && size.height !== height) {
// setHeight(size.height);
// }
// }, 100),
// [size, width, height]
// );
// useEffect(() => {
// handleResizeThrottle();
// window.addEventListener('resize', handleResizeThrottle);
// return () => {
// handleResizeThrottle.cancel();
// };
// }, [size, width, height]);
React.useEffect(() => {
if (size) {
setWidth(size?.width || 0);
if (!fixedHeight) {
setHeight(size?.height || 0);
}
}
}, [size]);
useEffect(() => {
if (!canvasRef.current) return;
@ -175,14 +166,17 @@ const AudioAnimation: React.FC<AudioAnimationProps> = (props) => {
return (
<div
ref={containerRef}
className="canvas-wrap"
style={{
width: '100%',
height: height
}}
className="scroller-wrapper"
ref={scrollerRef}
style={{ width: '100%', height: '100%' }}
>
<canvas ref={canvasRef} style={{ width, height }}></canvas>
<div
ref={containerRef}
className="canvas-wrap"
style={{ width: '100%', height: '100%' }}
>
<canvas ref={canvasRef} style={{ display: 'block' }}></canvas>
</div>
</div>
);
};

@ -3,7 +3,7 @@ import { Progress } from 'antd';
import classNames from 'classnames';
import * as Vibrant from 'node-vibrant';
import ResizeObserver from 'rc-resize-observer';
import React from 'react';
import React, { useCallback } from 'react';
import AutoImage from './index';
import './single-image.less';
@ -20,6 +20,7 @@ interface SingleImageProps {
onDelete: (uid: number) => void;
autoBgColor?: boolean;
editable?: boolean;
style?: React.CSSProperties;
}
const SingleImage: React.FC<SingleImageProps> = (props) => {
@ -35,6 +36,7 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
maxHeight,
maxWidth,
dataUrl,
style,
autoBgColor
} = props;
@ -49,36 +51,29 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
return loading ? { width: '100%', height: '100%' } : {};
}, [loading, imgSize]);
const handleResize = React.useCallback(
async (size: { width: number; height: number }) => {
if (!autoSize || !dataUrl) return;
const handleResize = useCallback(
(size: { width: number; height: number }) => {
if (!autoSize) return;
const { width: containerWidth, height: containerHeight } = size;
const { width: originalWidth, height: originalHeight } = props;
console.log('size:', size, originalWidth, originalHeight);
if (!originalWidth || !originalHeight) return;
const imageAspectRatio = originalWidth / originalHeight;
const containerAspectRatio = containerWidth / containerHeight;
const widthRatio = containerWidth / originalWidth;
const heightRatio = containerHeight / originalHeight;
let newWidth, newHeight;
const scale = Math.min(widthRatio, heightRatio, 1);
const newWidth = originalWidth * scale;
const newHeight = originalHeight * scale;
if (containerAspectRatio > imageAspectRatio) {
newHeight = containerHeight;
newWidth = containerHeight * imageAspectRatio;
} else {
newWidth = containerWidth;
newHeight = containerWidth / imageAspectRatio;
}
console.log('size++++++++=', size, newWidth, newHeight);
setImgSize({
width: newWidth,
height: newHeight
});
},
[autoSize, dataUrl, props]
[autoSize, props.width, props.height]
);
const handleOnLoad = React.useCallback(async () => {
@ -129,6 +124,7 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
return (
<ResizeObserver onResize={handleResize}>
<div
style={{ ...style }}
key={uid}
className={classNames('single-image', {
'auto-bg-color': autoBgColor,

@ -106,6 +106,12 @@ const AudioPlayer: React.FC<
}
};
const seekTo = (value: number) => {
if (wavesurfer.current) {
wavesurfer.current.seekTo(value);
}
};
const duration = () => {
if (wavesurfer.current) {
return wavesurfer.current.getDuration();
@ -123,7 +129,8 @@ const AudioPlayer: React.FC<
return {
play,
pause,
duration
duration,
seekTo
};
});
@ -135,7 +142,13 @@ const AudioPlayer: React.FC<
destroyWavesurfer();
};
}, [audioUrl, container.current]);
return <div ref={container} className="audio-container"></div>;
return (
<div
ref={container}
className="audio-container"
style={{ display: 'none' }}
></div>
);
});
export default React.memo(AudioPlayer);

@ -1,3 +1,4 @@
import AudioAnimation from '@/components/audio-animation';
import useResizeObserver from '@/components/logs-viewer/use-size';
import {
DownloadOutlined,
@ -5,12 +6,13 @@ import {
PlayCircleOutlined
} from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Tooltip } from 'antd';
import { Button, Slider, Tooltip } from 'antd';
import dayjs from 'dayjs';
import _ from 'lodash';
import _, { throttle } from 'lodash';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import AudioPlayer from './audio-player';
import './styles/index.less';
import './styles/slider-progress.less';
const audioFormat = {
'audio/mpeg': 'mp3',
@ -72,10 +74,18 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
setIsPlay(false);
}, []);
const handleOnAudioprocess = useCallback((current: number) => {
setCurrentTime(() => current);
console.log('current:', current, duration);
}, []);
const throttleUpdateCurrentTime = throttle((current: number) => {
setCurrentTime(current);
}, 100);
const handleOnAudioprocess = useCallback(
(current: number) => {
console.log('current:', current);
// setCurrentTime(() => current);
throttleUpdateCurrentTime(current);
},
[throttleUpdateCurrentTime]
);
const handleReay = useCallback((duration: number) => {
setIsPlay(props.autoplay);
@ -87,13 +97,17 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
}, []);
const handleAnimationResize = useCallback((size: any) => {
console.log('size:=======', size);
setAnimationSize({
width: size.width,
height: size.height
});
}, []);
const handleSliderChange = (value: number) => {
ref.current?.seekTo(value);
setCurrentTime(value);
};
useEffect(() => {
console.log('width:', size);
}, [size]);
@ -112,7 +126,6 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
return (
<div>
<div className="speech-item">
<div style={{}}></div>
<div
className="wrapper"
style={{ height: 82, width: '100%' }}
@ -128,22 +141,31 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
onAudioprocess={handleOnAudioprocess}
ref={ref}
></AudioPlayer>
{/* {!isPlay && (
{isPlay && (
<AudioAnimation
maxBarCount={180}
fixedHeight={true}
height={82}
width={800}
analyserData={audioChunks}
></AudioAnimation>
)} */}
)}
</div>
</div>
{/* <Slider value={currentTime} max={duration} step={0.01}></Slider> */}
<Slider
className="slider-progress"
value={currentTime}
max={duration}
step={0.01}
onChange={handleSliderChange}
></Slider>
<div className="speech-actions">
<span className="tags">
<span className="item">{props.format}</span>
</span>
<span className="duration">{_.round(duration, 2)}</span>
<span className="duration">
{_.round(currentTime, 2) || _.round(duration, 2)}
</span>
<div className="actions">
<Tooltip
title={

@ -69,6 +69,12 @@
}
}
.duration {
display: flex;
justify-content: center;
width: 100px;
}
.tags {
display: flex;
justify-content: flex-start;

@ -0,0 +1,21 @@
.slider-progress {
&:hover {
.ant-slider-track {
background-color: var(--ant-blue-5);
}
}
.ant-slider-rail {
border-radius: var(--border-radius-base);
height: 2px;
}
.ant-slider-track {
background-color: var(--ant-blue-5);
height: 2px;
}
.ant-slider-handle {
display: none;
}
}

@ -58,7 +58,7 @@ export default {
'models.table.layers': 'Layers',
'models.form.backend': 'Backend',
'models.form.backend_parameters': 'Backend Parameters',
'models.search.gguf.tips': '1. GGUF model backend is llama-box(llama.cpp).',
'models.search.gguf.tips': '1. GGUF model backend is llama-box.',
'models.search.vllm.tips': '2. Non-GGUF model backend is vLLM.',
'models.form.ollamalink': 'Find More in Ollama Library',
'models.form.backend_parameters.llamabox.placeholder':

@ -57,7 +57,7 @@ export default {
'models.table.layers': '层',
'models.form.backend': '后端',
'models.form.backend_parameters': '后端参数',
'models.search.gguf.tips': '1. GGUF 模型后端为 llama-box(llama.cpp)',
'models.search.gguf.tips': '1. GGUF 模型后端为 llama-box',
'models.search.vllm.tips': '2. 非 GGUF 模型后端为 vLLM',
'models.form.ollamalink': '在 Ollama Library 中查找',
'models.form.backend_parameters.llamabox.placeholder':

@ -255,7 +255,7 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
label={intl.formatMessage({ id: 'models.form.backend' })}
options={[
{
label: `llama-box(llama.cpp)`,
label: `llama-box`,
value: backendOptionsMap.llamaBox,
disabled:
source === modelSourceMap.local_path_value ? false : !isGGUF

@ -196,7 +196,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
height: imgSize[1],
width: imgSize[0],
loading: true,
uid: index
uid: setMessageId()
};
});
setImageList(newImageList);

@ -232,6 +232,7 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
if (isRecording) {
return (
<AudioAnimation
fixedHeight={true}
height={82}
width={500}
analyserData={audioChunks}

@ -338,7 +338,7 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
return (
<div className="ground-left-wrapper">
<div className="ground-left">
<div className="message-list-wrap" ref={scroller}>
<div className="message-list-wrap">
<div
style={{
height: '100%',

@ -1,7 +1,7 @@
import SingleImage from '@/components/auto-image/single-image';
import { Col, Row } from 'antd';
import _ from 'lodash';
import React, { useCallback } from 'react';
import React, { useCallback, useMemo } from 'react';
import '../style/thumb-img.less';
const ThumbImg: React.FC<{
@ -32,13 +32,67 @@ const ThumbImg: React.FC<{
[onDelete]
);
if (!dataList?.length) {
return null;
}
const responseableStyle: Record<number, any> = useMemo(() => {
if (!responseable) return {};
if (dataList.length === 1) {
return {
0: {
justifyContent: 'center',
alignItems: 'center'
}
};
}
if (dataList.length === 2) {
return {
0: {
justifyContent: 'flex-end',
alignItems: 'center'
},
1: {
justifyContent: 'flex-start',
alignItems: 'center'
}
};
}
if (dataList.length === 3) {
return {
0: {
justifyContent: 'flex-end',
alignItems: 'flex-end'
},
1: {
justifyContent: 'flex-start',
alignItems: 'flex-end'
},
2: {
justifyContent: 'flex-end',
alignItems: 'flex-start'
}
};
}
return {
0: {
justifyContent: 'flex-end',
alignItems: 'flex-end'
},
1: {
justifyContent: 'flex-start',
alignItems: 'flex-end'
},
2: {
justifyContent: 'flex-end',
alignItems: 'flex-start'
},
3: {
justifyContent: 'flex-start',
alignItems: 'flex-start'
}
};
}, [dataList, responseable]);
return (
<>
{
{dataList?.length ? (
<div className="thumb-list-wrap" style={{ ...style }}>
{responseable ? (
<>
@ -53,7 +107,7 @@ const ThumbImg: React.FC<{
dataList.length === 1 ? 'center' : 'flex-start'
}}
>
{_.map(_.slice(dataList, 0, 2), (item: any, index: string) => {
{_.map(_.slice(dataList, 0, 2), (item: any, index: number) => {
return (
<Col
span={item.span}
@ -63,6 +117,7 @@ const ThumbImg: React.FC<{
>
<SingleImage
{...item}
style={{ ...(responseableStyle[index] || {}) }}
autoSize={autoSize}
editable={editable}
autoBgColor={autoBgColor}
@ -84,7 +139,8 @@ const ThumbImg: React.FC<{
}}
className="flex-center"
>
{_.map(_.slice(dataList, 2), (item: any, index: string) => {
{_.map(_.slice(dataList, 2), (item: any, index: number) => {
console.log('index=======', index);
return (
<Col
span={item.span}
@ -94,6 +150,7 @@ const ThumbImg: React.FC<{
>
<SingleImage
{...item}
style={{ ...(responseableStyle[index + 2] || {}) }}
loading={item.loading}
autoSize={autoSize}
editable={editable}
@ -122,7 +179,7 @@ const ThumbImg: React.FC<{
</>
)}
</div>
}
) : null}
</>
);
};

Loading…
Cancel
Save