chore: audio page keepalive

This commit is contained in:
jialin
2024-12-31 11:04:30 +08:00
parent aed7267253
commit e4b1dfc77a
13 changed files with 65 additions and 22 deletions
+1 -1
View File
@@ -90,7 +90,7 @@ export default defineConfig({
model: {}, model: {},
initialState: {}, initialState: {},
request: {}, request: {},
keepalive: ['/playground/text-to-image'], keepalive: ['/playground/text-to-image', '/playground/speech'],
locale: { locale: {
antd: true, antd: true,
baseNavigator: true, baseNavigator: true,
+13 -5
View File
@@ -4,6 +4,7 @@ import {
SyncOutlined, SyncOutlined,
UndoOutlined UndoOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Slider, Tooltip } from 'antd'; import { Button, Slider, Tooltip } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import React, { useCallback, useEffect, useRef, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
@@ -33,6 +34,7 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
onSave, onSave,
uploadButton uploadButton
}) => { }) => {
const intl = useIntl();
const canvasRef = useRef<HTMLCanvasElement>(null); const canvasRef = useRef<HTMLCanvasElement>(null);
const overlayCanvasRef = useRef<HTMLCanvasElement>(null); const overlayCanvasRef = useRef<HTMLCanvasElement>(null);
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
@@ -541,7 +543,9 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
}} }}
title={ title={
<div className="flex-column" style={{ width: '100%' }}> <div className="flex-column" style={{ width: '100%' }}>
<span className="text-secondary">Brush Size</span> <span className="text-secondary">
{intl.formatMessage({ id: 'playground.image.brushSize' })}
</span>
<Slider <Slider
disabled={disabled} disabled={disabled}
style={{ marginBlock: '4px 6px', marginLeft: 0, flex: 1 }} style={{ marginBlock: '4px 6px', marginLeft: 0, flex: 1 }}
@@ -558,7 +562,7 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
<FormatPainterOutlined className="font-size-14" /> <FormatPainterOutlined className="font-size-14" />
</Button> </Button>
</Tooltip> </Tooltip>
<Tooltip title="Undo"> <Tooltip title={intl.formatMessage({ id: 'common.button.undo' })}>
<Button <Button
onClick={undo} onClick={undo}
size="middle" size="middle"
@@ -569,7 +573,7 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
</Button> </Button>
</Tooltip> </Tooltip>
{uploadButton} {uploadButton}
<Tooltip title="Reset"> <Tooltip title={intl.formatMessage({ id: 'common.button.reset' })}>
<Button <Button
onClick={onReset} onClick={onReset}
size="middle" size="middle"
@@ -581,12 +585,16 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
</Tooltip> </Tooltip>
</div> </div>
<div className="tools"> <div className="tools">
<Tooltip title="Save Mask"> <Tooltip
title={intl.formatMessage({ id: 'playground.image.saveMask' })}
>
<Button onClick={downloadMask} size="middle" type="text"> <Button onClick={downloadMask} size="middle" type="text">
<IconFont className="font-size-14" type="icon-save2"></IconFont> <IconFont className="font-size-14" type="icon-save2"></IconFont>
</Button> </Button>
</Tooltip> </Tooltip>
<Tooltip title="Download"> <Tooltip
title={intl.formatMessage({ id: 'playground.image.download' })}
>
<Button onClick={download} size="middle" type="text"> <Button onClick={download} size="middle" type="text">
<DownloadOutlined className="font-size-14" /> <DownloadOutlined className="font-size-14" />
</Button> </Button>
+2 -1
View File
@@ -1,3 +1,4 @@
export default { export default {
'/playground/text-to-image': '/playground/text-to-image' '/playground/text-to-image': '/playground/text-to-image',
'/playground/speech': '/playground/speech'
}; };
+3
View File
@@ -291,6 +291,9 @@ export default (props: any) => {
layout="side" layout="side"
openKeys={false} openKeys={false}
disableMobile={true} disableMobile={true}
header={{
title: <div style={{ fontSize: 36 }}> gpuStack </div>
}}
siderWidth={220} siderWidth={220}
onCollapse={(collapsed) => { onCollapse={(collapsed) => {
setCollapsed(collapsed); setCollapsed(collapsed);
+7 -3
View File
@@ -126,9 +126,13 @@ export default {
'playground.documents.verify.embedding': 'At least add two pieces of text.', 'playground.documents.verify.embedding': 'At least add two pieces of text.',
'playground.documents.verify.rerank': 'The documents cannot be empty.', 'playground.documents.verify.rerank': 'The documents cannot be empty.',
'playground.image.guidance.tip': 'playground.image.guidance.tip':
'The lower the value, the higher the diversity, and the lower the adherence to the prompt.', 'Guidance scale, affecting the quality and diversity of the image.',
'playground.image.cfg_scale.tip': 'playground.image.cfg_scale.tip':
'The lower the value, the higher the diversity.', "Classifier-free guidance scale, affecting the image's adherence to the prompt.",
'playground.image.strength.tip': 'playground.image.strength.tip':
'The higher the value, the greater the modification to the original image.' 'The higher the value, the greater the modification to the original image.',
'playground.image.edit.tips': 'Click or drag image to this area to upload',
'playground.image.saveMask': 'Save Mask',
'playground.image.brushSize': 'Brush Size',
'playground.image.download': 'Download Image'
}; };
+8 -3
View File
@@ -122,7 +122,12 @@ export default {
'图片生成的最大尺寸受控于模型的部署参数。<a href="https://github.com/gpustack/llama-box" target="_blank">参考文档</a>', '图片生成的最大尺寸受控于模型的部署参数。<a href="https://github.com/gpustack/llama-box" target="_blank">参考文档</a>',
'playground.documents.verify.embedding': '至少输入两条文本', 'playground.documents.verify.embedding': '至少输入两条文本',
'playground.documents.verify.rerank': '文档不能为空', 'playground.documents.verify.rerank': '文档不能为空',
'playground.image.guidance.tip': '值越低,多样性越高,对提示词的贴合度越低', 'playground.image.guidance.tip': '引导比例,影响图片的质量和多样性',
'playground.image.cfg_scale.tip': '值越低,多样性越高', 'playground.image.cfg_scale.tip':
'playground.image.strength.tip': '值越高,它对原图的修改越大' '无分类器引导比例,影响图片的对Prompt的贴合度',
'playground.image.strength.tip': '值越高,它对原图的修改越大',
'playground.image.edit.tips': '点击或拖动图片到此区域上传',
'playground.image.saveMask': '保存遮罩',
'playground.image.brushSize': '画笔大小',
'playground.image.download': '下载图片'
}; };
@@ -186,6 +186,7 @@ const ParamsSettings: React.FC<ParamsSettingsProps> = forwardRef(
[intl] [intl]
); );
const renderFields = useMemo(() => { const renderFields = useMemo(() => {
console.log('paramsConfig++++++++++++');
if (!paramsConfig?.length) { if (!paramsConfig?.length) {
return null; return null;
} }
@@ -94,6 +94,7 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
}; };
const joinMessage = (chunk: any) => { const joinMessage = (chunk: any) => {
console.log('chunk:', chunk);
setTokenResult({ setTokenResult({
...(chunk?.usage ?? {}) ...(chunk?.usage ?? {})
}); });
@@ -1,9 +1,11 @@
import { setRouteCache } from '@/atoms/route-cache';
import AlertInfo from '@/components/alert-info'; import AlertInfo from '@/components/alert-info';
import AudioAnimation from '@/components/audio-animation'; import AudioAnimation from '@/components/audio-animation';
import AudioPlayer from '@/components/audio-player'; import AudioPlayer from '@/components/audio-player';
import CopyButton from '@/components/copy-button'; import CopyButton from '@/components/copy-button';
import IconFont from '@/components/icon-font'; import IconFont from '@/components/icon-font';
import UploadAudio from '@/components/upload-audio'; import UploadAudio from '@/components/upload-audio';
import routeCachekey from '@/config/route-cachekey';
import useOverlayScroller from '@/hooks/use-overlay-scroller'; import useOverlayScroller from '@/hooks/use-overlay-scroller';
import { useCancelToken } from '@/hooks/use-request-token'; import { useCancelToken } from '@/hooks/use-request-token';
import { readAudioFile } from '@/utils/load-audio-file'; import { readAudioFile } from '@/utils/load-audio-file';
@@ -116,6 +118,8 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
cancelRequest(); cancelRequest();
updateCancelToken(); updateCancelToken();
setRouteCache(routeCachekey['/playground/speech'], true);
const params = { const params = {
...parameters, ...parameters,
file: new File([audioData.data], audioData.name, { file: new File([audioData.data], audioData.name, {
@@ -169,6 +173,7 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
} finally { } finally {
setLoading(false); setLoading(false);
setIsRecording(false); setIsRecording(false);
setRouteCache(routeCachekey['/playground/speech'], false);
} }
}; };
const handleClear = () => { const handleClear = () => {
@@ -1,7 +1,9 @@
import { setRouteCache } from '@/atoms/route-cache';
import AlertInfo from '@/components/alert-info'; import AlertInfo from '@/components/alert-info';
import IconFont from '@/components/icon-font'; import IconFont from '@/components/icon-font';
import SealSelect from '@/components/seal-form/seal-select'; import SealSelect from '@/components/seal-form/seal-select';
import SpeechContent from '@/components/speech-content'; import SpeechContent from '@/components/speech-content';
import routeCachekey from '@/config/route-cachekey';
import useOverlayScroller from '@/hooks/use-overlay-scroller'; import useOverlayScroller from '@/hooks/use-overlay-scroller';
import { SendOutlined } from '@ant-design/icons'; import { SendOutlined } from '@ant-design/icons';
import { getLocale, useIntl, useSearchParams } from '@umijs/max'; import { getLocale, useIntl, useSearchParams } from '@umijs/max';
@@ -157,6 +159,8 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
setCurrentPrompt(current?.content || ''); setCurrentPrompt(current?.content || '');
setMessageList([]); setMessageList([]);
setRouteCache(routeCachekey['/playground/speech'], true);
controllerRef.current?.abort?.(); controllerRef.current?.abort?.();
controllerRef.current = new AbortController(); controllerRef.current = new AbortController();
const signal = controllerRef.current.signal; const signal = controllerRef.current.signal;
@@ -214,6 +218,7 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
} }
} finally { } finally {
setLoading(false); setLoading(false);
setRouteCache(routeCachekey['/playground/speech'], false);
} }
}; };
const handleClear = () => { const handleClear = () => {
@@ -643,7 +643,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
type="icon-upload_image" type="icon-upload_image"
className="font-size-24" className="font-size-24"
></IconFont> ></IconFont>
<h3>Click or drag image to this area to upload</h3> <h3>{intl.formatMessage({ id: 'playground.image.edit.tips' })}</h3>
</div> </div>
</UploadImg> </UploadImg>
); );
+8 -4
View File
@@ -102,13 +102,15 @@ const Playground: React.FC = () => {
const getTextToSpeechModels = async () => { const getTextToSpeechModels = async () => {
try { try {
const params = { const params = {
categories: 'text_to_speech' categories: 'text_to_speech',
with_meta: true
}; };
const res = await queryModelsList(params); const res = await queryModelsList(params);
const list = _.map(res.data || [], (item: any) => { const list = _.map(res.data || [], (item: any) => {
return { return {
value: item.id, value: item.id,
label: item.id label: item.id,
meta: item.meta
}; };
}) as Global.BaseOption<string>[]; }) as Global.BaseOption<string>[];
return list; return list;
@@ -120,13 +122,15 @@ const Playground: React.FC = () => {
const getSpeechToText = async () => { const getSpeechToText = async () => {
try { try {
const params = { const params = {
categories: 'speech_to_text' categories: 'speech_to_text',
with_meta: true
}; };
const res = await queryModelsList(params); const res = await queryModelsList(params);
const list = _.map(res.data || [], (item: any) => { const list = _.map(res.data || [], (item: any) => {
return { return {
value: item.id, value: item.id,
label: item.id label: item.id,
meta: item.meta
}; };
}) as Global.BaseOption<string>[]; }) as Global.BaseOption<string>[];
return list; return list;
+10 -4
View File
@@ -8,7 +8,6 @@ const extractJSON = (dataStr: string) => {
if (!dataStr) { if (!dataStr) {
return results; return results;
} }
while ((match = extractStreamRegx.exec(dataStr)) !== null) { while ((match = extractStreamRegx.exec(dataStr)) !== null) {
try { try {
const jsonData = JSON.parse(match[1]); const jsonData = JSON.parse(match[1]);
@@ -131,9 +130,16 @@ export const readStreamData = async (
let chunk = decoder.decode(value, { stream: true }); let chunk = decoder.decode(value, { stream: true });
extractJSON(chunk).forEach((data) => { if (chunk.startsWith('error:')) {
callback?.(data); const errorStr = chunk.slice(7).trim();
}); const jsonData = JSON.parse(errorStr);
callback({ error: jsonData });
} else {
extractJSON(chunk).forEach((data) => {
callback?.(data);
});
}
await readStreamData(reader, decoder, callback); await readStreamData(reader, decoder, callback);
}; };