chore: create, edit image handler
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
import { CloseCircleOutlined, LoadingOutlined } from '@ant-design/icons';
|
||||||
import { Progress, ProgressProps } from 'antd';
|
import { Progress, ProgressProps, Spin } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { round } from 'lodash';
|
import { round } from 'lodash';
|
||||||
import ResizeObserver from 'rc-resize-observer';
|
import ResizeObserver from 'rc-resize-observer';
|
||||||
@@ -94,6 +94,17 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
|
|||||||
|
|
||||||
const handleOnLoad = React.useCallback(async () => {}, []);
|
const handleOnLoad = React.useCallback(async () => {}, []);
|
||||||
|
|
||||||
|
const renderProgress = () => {
|
||||||
|
<Progress
|
||||||
|
percent={round(progress, 0)}
|
||||||
|
type="dashboard"
|
||||||
|
size={loadingSize}
|
||||||
|
steps={{ count: 50, gap: 2 }}
|
||||||
|
format={() => <span className="font-size-20">{round(progress, 0)}%</span>}
|
||||||
|
trailColor="var(--ant-color-fill-secondary)"
|
||||||
|
/>;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ResizeObserver onResize={handleResize}>
|
<ResizeObserver onResize={handleResize}>
|
||||||
<div
|
<div
|
||||||
@@ -135,15 +146,8 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
|
|||||||
overflow: 'hidden'
|
overflow: 'hidden'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Progress
|
<Spin
|
||||||
percent={round(progress, 0)}
|
indicator={<LoadingOutlined style={{ fontSize: 32 }} spin />}
|
||||||
type="dashboard"
|
|
||||||
size={loadingSize}
|
|
||||||
steps={{ count: 50, gap: 2 }}
|
|
||||||
format={() => (
|
|
||||||
<span className="font-size-20">{round(progress, 0)}%</span>
|
|
||||||
)}
|
|
||||||
trailColor="var(--ant-color-fill-secondary)"
|
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { GPUSTACK_API_BASE_URL } from '@/config/settings';
|
import { GPUSTACK_API_BASE_URL } from '@/config/settings';
|
||||||
|
import { createFormData, errorHandler } from '@/utils/fetch-chunk-data';
|
||||||
import { request } from '@umijs/max';
|
import { request } from '@umijs/max';
|
||||||
|
|
||||||
export const OPENAI_COMPATIBLE = 'v1-openai';
|
export const OPENAI_COMPATIBLE = 'v1-openai';
|
||||||
@@ -94,6 +95,41 @@ export const createImages = async (
|
|||||||
return res.json();
|
return res.json();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// =========== edit image ============
|
||||||
|
export const editImage = async (params: {
|
||||||
|
data?: any;
|
||||||
|
signal?: AbortSignal;
|
||||||
|
}) => {
|
||||||
|
const response = await fetch(EDIT_IMAGE_API, {
|
||||||
|
method: 'POST',
|
||||||
|
body: createFormData(params.data),
|
||||||
|
signal: params.signal
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
return await errorHandler(response);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createImage = async (params: {
|
||||||
|
data?: any;
|
||||||
|
signal?: AbortSignal;
|
||||||
|
}) => {
|
||||||
|
const response = await fetch(CREAT_IMAGE_API, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(params.data),
|
||||||
|
signal: params.signal,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
return await errorHandler(response);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
// ============ audio ============
|
// ============ audio ============
|
||||||
export const textToSpeech = async (params: any, options?: any) => {
|
export const textToSpeech = async (params: any, options?: any) => {
|
||||||
const res = await fetch(AUDIO_TEXT_TO_SPEECH_API, {
|
const res = await fetch(AUDIO_TEXT_TO_SPEECH_API, {
|
||||||
|
|||||||
@@ -213,4 +213,4 @@ const ThumbImg: React.FC<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default React.memo(ThumbImg);
|
export default ThumbImg;
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
||||||
import { extractErrorMessage, promptList } from '@/pages/playground/config';
|
import { extractErrorMessage, promptList } from '@/pages/playground/config';
|
||||||
import {
|
|
||||||
fetchChunkedData,
|
|
||||||
fetchChunkedDataPostFormData
|
|
||||||
} from '@/utils/fetch-chunk-data';
|
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { CREAT_IMAGE_API, EDIT_IMAGE_API } from '../apis';
|
import {
|
||||||
|
CREAT_IMAGE_API,
|
||||||
|
EDIT_IMAGE_API,
|
||||||
|
createImage,
|
||||||
|
editImage
|
||||||
|
} from '../apis';
|
||||||
|
|
||||||
const ODD_STRING = 'AAAABJRU5ErkJgg===';
|
const ODD_STRING = 'AAAABJRU5ErkJgg===';
|
||||||
|
|
||||||
@@ -126,21 +127,21 @@ export default function useTextImage(props: any) {
|
|||||||
|
|
||||||
let result: any = {};
|
let result: any = {};
|
||||||
if (API === CREAT_IMAGE_API) {
|
if (API === CREAT_IMAGE_API) {
|
||||||
result = await fetchChunkedData({
|
result = await createImage({
|
||||||
data: parameters,
|
data: parameters,
|
||||||
url: `${API}?t=${Date.now()}`,
|
|
||||||
signal: requestToken.current.signal
|
signal: requestToken.current.signal
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (API === EDIT_IMAGE_API) {
|
if (API === EDIT_IMAGE_API) {
|
||||||
result = await fetchChunkedDataPostFormData({
|
result = await editImage({
|
||||||
data: parameters,
|
data: parameters,
|
||||||
url: `${API}?t=${Date.now()}`,
|
|
||||||
signal: requestToken.current.signal
|
signal: requestToken.current.signal
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('result:', result);
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
setTokenResult({
|
setTokenResult({
|
||||||
error: true,
|
error: true,
|
||||||
@@ -149,18 +150,19 @@ export default function useTextImage(props: any) {
|
|||||||
setImageList([]);
|
setImageList([]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('result:', result);
|
|
||||||
if (requestIdRef.current !== currentRequestId) {
|
|
||||||
// If the request ID has changed, ignore this chunk
|
// If the request ID has changed, ignore this chunk
|
||||||
// return;
|
if (requestIdRef.current !== currentRequestId) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// if (result?.error) {
|
if (result?.error) {
|
||||||
// setTokenResult({
|
setTokenResult({
|
||||||
// error: true,
|
error: true,
|
||||||
// errorMessage: extractErrorMessage(result)
|
errorMessage: extractErrorMessage(result)
|
||||||
// });
|
});
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
result?.data?.forEach((item: any, index: number) => {
|
result?.data?.forEach((item: any, index: number) => {
|
||||||
const imgItem = newImageList[index];
|
const imgItem = newImageList[index];
|
||||||
|
|
||||||
@@ -168,8 +170,6 @@ export default function useTextImage(props: any) {
|
|||||||
imgItem.dataUrl = `data:image/png;base64,${item.b64_json}`;
|
imgItem.dataUrl = `data:image/png;base64,${item.b64_json}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const progress = 100;
|
|
||||||
|
|
||||||
newImageList[index] = {
|
newImageList[index] = {
|
||||||
dataUrl: imgItem.dataUrl,
|
dataUrl: imgItem.dataUrl,
|
||||||
height: imgSize[1],
|
height: imgSize[1],
|
||||||
@@ -178,76 +178,13 @@ export default function useTextImage(props: any) {
|
|||||||
maxWidth: `${imgSize[0]}px`,
|
maxWidth: `${imgSize[0]}px`,
|
||||||
uid: imgItem.uid,
|
uid: imgItem.uid,
|
||||||
span: imgItem.span,
|
span: imgItem.span,
|
||||||
loading: _.get(parameters, chunkFields) ? progress < 100 : false,
|
loading: false,
|
||||||
preview: API === CREAT_IMAGE_API ? progress >= 100 : false,
|
preview: true,
|
||||||
progress: progress
|
progress: 100
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
console.log('newImageList:', newImageList);
|
console.log('newImageList:', newImageList);
|
||||||
// if (
|
|
||||||
// done &&
|
|
||||||
// !chunk?.error &&
|
|
||||||
// newImageList.some((item) => item.progress < 100)
|
|
||||||
// ) {
|
|
||||||
// setTokenResult({
|
|
||||||
// error: true,
|
|
||||||
// errorMessage: intl.formatMessage({
|
|
||||||
// id: 'playground.image.generate.error'
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
setImageList([...newImageList]);
|
setImageList([...newImageList]);
|
||||||
// const { reader, decoder } = result;
|
|
||||||
// streamReaderRef.current = reader;
|
|
||||||
// await readStreamData(reader, decoder, (chunk: any, done?: boolean) => {
|
|
||||||
// console.log('chunk done:', chunk, done);
|
|
||||||
// if (requestIdRef.current !== currentRequestId) {
|
|
||||||
// // If the request ID has changed, ignore this chunk
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if (chunk?.error) {
|
|
||||||
// setTokenResult({
|
|
||||||
// error: true,
|
|
||||||
// errorMessage: extractErrorMessage(chunk)
|
|
||||||
// });
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// chunk?.data?.forEach((item: any) => {
|
|
||||||
// const imgItem = newImageList[item.index];
|
|
||||||
// if (item.b64_json && _.get(parameters, chunkFields)) {
|
|
||||||
// imgItem.dataUrl += removeBase64Suffix(item.b64_json, ODD_STRING);
|
|
||||||
// } else if (item.b64_json) {
|
|
||||||
// imgItem.dataUrl = `data:image/png;base64,${removeBase64Suffix(item.b64_json, ODD_STRING)}`;
|
|
||||||
// }
|
|
||||||
// const progress = item.progress;
|
|
||||||
|
|
||||||
// newImageList[item.index] = {
|
|
||||||
// dataUrl: imgItem.dataUrl,
|
|
||||||
// height: imgSize[1],
|
|
||||||
// width: imgSize[0],
|
|
||||||
// maxHeight: `${imgSize[1]}px`,
|
|
||||||
// maxWidth: `${imgSize[0]}px`,
|
|
||||||
// uid: imgItem.uid,
|
|
||||||
// span: imgItem.span,
|
|
||||||
// loading: _.get(parameters, chunkFields) ? progress < 100 : false,
|
|
||||||
// preview: API === CREAT_IMAGE_API ? progress >= 100 : false,
|
|
||||||
// progress: progress
|
|
||||||
// };
|
|
||||||
// });
|
|
||||||
// if (
|
|
||||||
// done &&
|
|
||||||
// !chunk?.error &&
|
|
||||||
// newImageList.some((item) => item.progress < 100)
|
|
||||||
// ) {
|
|
||||||
// setTokenResult({
|
|
||||||
// error: true,
|
|
||||||
// errorMessage: intl.formatMessage({
|
|
||||||
// id: 'playground.image.generate.error'
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// setImageList([...newImageList]);
|
|
||||||
// });
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('error:', error);
|
console.log('error:', error);
|
||||||
updateRequestId();
|
updateRequestId();
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const extractJSON = (
|
|||||||
return { results, remaining };
|
return { results, remaining };
|
||||||
};
|
};
|
||||||
|
|
||||||
const errorHandler = async (res: any) => {
|
export const errorHandler = async (res: any) => {
|
||||||
try {
|
try {
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
return {
|
return {
|
||||||
@@ -78,10 +78,17 @@ export const fetchChunkedData = async (params: {
|
|||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
return await errorHandler(response);
|
return await errorHandler(response);
|
||||||
}
|
}
|
||||||
return response.json();
|
const reader = response?.body?.getReader();
|
||||||
|
const decoder = new TextDecoder('utf-8', {
|
||||||
|
fatal: true
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
reader,
|
||||||
|
decoder
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const createFormData = (data: any): FormData => {
|
export const createFormData = (data: any): FormData => {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
const appendToFormData = (key: string, value: any) => {
|
const appendToFormData = (key: string, value: any) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user