chore: create, edit image handler
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||
import { Progress, ProgressProps } from 'antd';
|
||||
import { CloseCircleOutlined, LoadingOutlined } from '@ant-design/icons';
|
||||
import { Progress, ProgressProps, Spin } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { round } from 'lodash';
|
||||
import ResizeObserver from 'rc-resize-observer';
|
||||
@@ -94,6 +94,17 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
|
||||
|
||||
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 (
|
||||
<ResizeObserver onResize={handleResize}>
|
||||
<div
|
||||
@@ -135,15 +146,8 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
|
||||
overflow: 'hidden'
|
||||
}}
|
||||
>
|
||||
<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)"
|
||||
<Spin
|
||||
indicator={<LoadingOutlined style={{ fontSize: 32 }} spin />}
|
||||
/>
|
||||
</span>
|
||||
) : (
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { GPUSTACK_API_BASE_URL } from '@/config/settings';
|
||||
import { createFormData, errorHandler } from '@/utils/fetch-chunk-data';
|
||||
import { request } from '@umijs/max';
|
||||
|
||||
export const OPENAI_COMPATIBLE = 'v1-openai';
|
||||
@@ -94,6 +95,41 @@ export const createImages = async (
|
||||
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 ============
|
||||
export const textToSpeech = async (params: any, options?: any) => {
|
||||
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 { extractErrorMessage, promptList } from '@/pages/playground/config';
|
||||
import {
|
||||
fetchChunkedData,
|
||||
fetchChunkedDataPostFormData
|
||||
} from '@/utils/fetch-chunk-data';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import _ from 'lodash';
|
||||
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===';
|
||||
|
||||
@@ -126,21 +127,21 @@ export default function useTextImage(props: any) {
|
||||
|
||||
let result: any = {};
|
||||
if (API === CREAT_IMAGE_API) {
|
||||
result = await fetchChunkedData({
|
||||
result = await createImage({
|
||||
data: parameters,
|
||||
url: `${API}?t=${Date.now()}`,
|
||||
signal: requestToken.current.signal
|
||||
});
|
||||
}
|
||||
|
||||
if (API === EDIT_IMAGE_API) {
|
||||
result = await fetchChunkedDataPostFormData({
|
||||
result = await editImage({
|
||||
data: parameters,
|
||||
url: `${API}?t=${Date.now()}`,
|
||||
signal: requestToken.current.signal
|
||||
});
|
||||
}
|
||||
|
||||
console.log('result:', result);
|
||||
|
||||
if (result.error) {
|
||||
setTokenResult({
|
||||
error: true,
|
||||
@@ -149,18 +150,19 @@ export default function useTextImage(props: any) {
|
||||
setImageList([]);
|
||||
return;
|
||||
}
|
||||
console.log('result:', result);
|
||||
|
||||
// If the request ID has changed, ignore this chunk
|
||||
if (requestIdRef.current !== currentRequestId) {
|
||||
// If the request ID has changed, ignore this chunk
|
||||
// return;
|
||||
return;
|
||||
}
|
||||
// if (result?.error) {
|
||||
// setTokenResult({
|
||||
// error: true,
|
||||
// errorMessage: extractErrorMessage(result)
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
if (result?.error) {
|
||||
setTokenResult({
|
||||
error: true,
|
||||
errorMessage: extractErrorMessage(result)
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
result?.data?.forEach((item: any, index: number) => {
|
||||
const imgItem = newImageList[index];
|
||||
|
||||
@@ -168,8 +170,6 @@ export default function useTextImage(props: any) {
|
||||
imgItem.dataUrl = `data:image/png;base64,${item.b64_json}`;
|
||||
}
|
||||
|
||||
const progress = 100;
|
||||
|
||||
newImageList[index] = {
|
||||
dataUrl: imgItem.dataUrl,
|
||||
height: imgSize[1],
|
||||
@@ -178,76 +178,13 @@ export default function useTextImage(props: any) {
|
||||
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
|
||||
loading: false,
|
||||
preview: true,
|
||||
progress: 100
|
||||
};
|
||||
});
|
||||
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]);
|
||||
// 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) {
|
||||
console.log('error:', error);
|
||||
updateRequestId();
|
||||
|
||||
@@ -32,7 +32,7 @@ const extractJSON = (
|
||||
return { results, remaining };
|
||||
};
|
||||
|
||||
const errorHandler = async (res: any) => {
|
||||
export const errorHandler = async (res: any) => {
|
||||
try {
|
||||
const data = await res.json();
|
||||
return {
|
||||
@@ -78,10 +78,17 @@ export const fetchChunkedData = async (params: {
|
||||
if (!response.ok) {
|
||||
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 appendToFormData = (key: string, value: any) => {
|
||||
|
||||
Reference in New Issue
Block a user