fix: image edit ux

This commit is contained in:
jialin
2025-01-06 20:45:32 +08:00
parent 5c401f3858
commit 39a71d51cf
12 changed files with 164 additions and 72 deletions
+1
View File
@@ -18,6 +18,7 @@ export default function createProxyTable(target?: string) {
changeOrigin: true, changeOrigin: true,
secure: false, secure: false,
ws: true, ws: true,
log: 'debug',
pathRewrite: (pth: string) => pth.replace(`/^/${api}`, `/${api}`), pathRewrite: (pth: string) => pth.replace(`/^/${api}`, `/${api}`),
// onProxyRes: (proxyRes: any, req: any, res: any) => { // onProxyRes: (proxyRes: any, req: any, res: any) => {
// console.log('headers=========', { // console.log('headers=========', {
+1
View File
@@ -14,5 +14,6 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
overflow: hidden;
} }
} }
+80 -27
View File
@@ -11,7 +11,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
import IconFont from '../icon-font'; import IconFont from '../icon-font';
import './index.less'; import './index.less';
type Point = { x: number; y: number }; type Point = { x: number; y: number; lineWidth: number };
type Stroke = Point[]; type Stroke = Point[];
type CanvasImageEditorProps = { type CanvasImageEditorProps = {
@@ -48,6 +48,13 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
const cursorRef = useRef<HTMLDivElement>(null); const cursorRef = useRef<HTMLDivElement>(null);
const [imgLoaded, setImgLoaded] = useState(false); const [imgLoaded, setImgLoaded] = useState(false);
let scale = 1;
let offsetX = 0;
let offsetY = 0;
const MIN_SCALE = 0.5;
const MAX_SCALE = 5;
const getTransformedPoint = (event: React.MouseEvent<HTMLCanvasElement>) => { const getTransformedPoint = (event: React.MouseEvent<HTMLCanvasElement>) => {
const overlayCanvas = overlayCanvasRef.current!; const overlayCanvas = overlayCanvasRef.current!;
const rect = overlayCanvas.getBoundingClientRect(); const rect = overlayCanvas.getBoundingClientRect();
@@ -187,13 +194,12 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
ctx: CanvasRenderingContext2D, ctx: CanvasRenderingContext2D,
stroke: Stroke | Point[], stroke: Stroke | Point[],
options: { options: {
lineWidth: number; lineWidth?: number;
color: string; color: string;
compositeOperation: 'source-over' | 'destination-out'; compositeOperation: 'source-over' | 'destination-out';
} }
) => { ) => {
const { lineWidth, color, compositeOperation } = options; const { color, compositeOperation } = options;
ctx.lineWidth = lineWidth;
ctx.lineCap = 'round'; ctx.lineCap = 'round';
ctx.lineJoin = 'round'; ctx.lineJoin = 'round';
ctx.globalCompositeOperation = compositeOperation; ctx.globalCompositeOperation = compositeOperation;
@@ -201,6 +207,7 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
ctx.beginPath(); ctx.beginPath();
stroke.forEach((point, i) => { stroke.forEach((point, i) => {
ctx.lineWidth = point.lineWidth;
if (i === 0) { if (i === 0) {
ctx.moveTo(point.x, point.y); ctx.moveTo(point.x, point.y);
} else { } else {
@@ -248,7 +255,8 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
console.log('Drawing:', e.nativeEvent, { x, y }); console.log('Drawing:', e.nativeEvent, { x, y });
currentStroke.current.push({ currentStroke.current.push({
x, x,
y y,
lineWidth
}); });
const ctx = overlayCanvasRef.current!.getContext('2d'); const ctx = overlayCanvasRef.current!.getContext('2d');
@@ -257,12 +265,12 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
drawLine( drawLine(
ctx!, ctx!,
{ x, y }, { x, y, lineWidth },
{ lineWidth, color: COLOR, compositeOperation: 'destination-out' } { lineWidth, color: COLOR, compositeOperation: 'destination-out' }
); );
drawLine( drawLine(
ctx!, ctx!,
{ x, y }, { x, y, lineWidth },
{ lineWidth, color: COLOR, compositeOperation: 'source-over' } { lineWidth, color: COLOR, compositeOperation: 'source-over' }
); );
@@ -276,7 +284,8 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
const { x, y } = getTransformedPoint(e); const { x, y } = getTransformedPoint(e);
currentStroke.current.push({ currentStroke.current.push({
x, x,
y y,
lineWidth
}); });
const ctx = overlayCanvasRef.current!.getContext('2d'); const ctx = overlayCanvasRef.current!.getContext('2d');
@@ -367,20 +376,18 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
strokes?.forEach((stroke: Point[], index) => { strokes?.forEach((stroke: Point[], index) => {
overlayCtx.save(); overlayCtx.save();
drawStroke(overlayCtx, stroke, { drawStroke(overlayCtx, stroke, {
lineWidth,
color: COLOR, color: COLOR,
compositeOperation: 'destination-out' compositeOperation: 'destination-out'
}); });
drawStroke(overlayCtx, stroke, { drawStroke(overlayCtx, stroke, {
lineWidth,
color: COLOR, color: COLOR,
compositeOperation: 'source-over' compositeOperation: 'source-over'
}); });
overlayCtx.restore(); overlayCtx.restore();
}); });
}, },
[lineWidth, drawStroke] [drawStroke]
); );
const undo = () => { const undo = () => {
@@ -408,7 +415,8 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
return stroke.map((point) => { return stroke.map((point) => {
return { return {
x: point.x * scale, x: point.x * scale,
y: point.y * scale y: point.y * scale,
lineWidth: point.lineWidth
}; };
}); });
}); });
@@ -466,7 +474,6 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
const contentRect = entries[0].contentRect; const contentRect = entries[0].contentRect;
if (!contentRect.width || !contentRect.height || !imgLoaded) return; if (!contentRect.width || !contentRect.height || !imgLoaded) return;
await drawImage(); await drawImage();
console.log('Image Loaded:', imageStatus, strokesRef.current);
if (imageStatus.isOriginal) { if (imageStatus.isOriginal) {
redrawStrokes(strokesRef.current, 'resize'); redrawStrokes(strokesRef.current, 'resize');
} }
@@ -486,24 +493,70 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
} }
}, [drawImage, onReset, redrawStrokes, imageStatus]); }, [drawImage, onReset, redrawStrokes, imageStatus]);
const calcTransformedPoint = (event: React.MouseEvent<HTMLCanvasElement>) => {
const overlayCanvas = overlayCanvasRef.current!;
const rect = overlayCanvas.getBoundingClientRect();
// 获取鼠标在画布上的原始坐标
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
// 考虑缩放比例和偏移量
const transformedX = (x - offsetX) / scale;
const transformedY = (y - offsetY) / scale;
return { x: transformedX, y: transformedY };
};
const handleOnWheel = (event: WheelEvent) => {
event.preventDefault();
const zoomFactor = event.deltaY < 0 ? 1.1 : 0.9;
const newScale = Math.min(
MAX_SCALE,
Math.max(MIN_SCALE, scale * zoomFactor)
);
const rect = canvasRef.current!.getBoundingClientRect();
const mouseX = event.clientX - rect.left;
const mouseY = event.clientY - rect.top;
// 计算新的偏移量
offsetX = mouseX - (mouseX - offsetX) * (newScale / scale);
offsetY = mouseY - (mouseY - offsetY) * (newScale / scale);
// 更新缩放比例
scale = newScale;
// 设置画布的变换
const overlayCtx = overlayCanvasRef.current!.getContext('2d')!;
overlayCtx.setTransform(scale, 0, 0, scale, offsetX, offsetY);
const canvasCtx = canvasRef.current!.getContext('2d')!;
canvasCtx.setTransform(scale, 0, 0, scale, offsetX, offsetY);
overlayCanvasRef.current!.style.transform = `scale(${scale})`;
canvasRef.current!.style.transform = `scale(${scale})`;
console.log('Zoom:', scale, offsetX, offsetY);
};
useEffect(() => { useEffect(() => {
initializeImage(); initializeImage();
}, [initializeImage]); }, [initializeImage]);
useEffect(() => { // useEffect(() => {
const container = containerRef.current; // const container = containerRef.current;
if (!container) return; // if (!container) return;
if (container) { // if (container) {
resizeObserver.current = new ResizeObserver( // resizeObserver.current = new ResizeObserver(
_.throttle(handleResize, 100) // _.throttle(handleResize, 100)
); // );
resizeObserver.current.observe(container); // resizeObserver.current.observe(container);
} // }
return () => { // return () => {
resizeObserver.current?.disconnect(); // resizeObserver.current?.disconnect();
}; // };
}, [handleResize, containerRef.current]); // }, [handleResize, containerRef.current]);
useEffect(() => { useEffect(() => {
createOffscreenCanvas(); createOffscreenCanvas();
@@ -551,7 +604,7 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
style={{ marginBlock: '4px 6px', marginLeft: 0, flex: 1 }} style={{ marginBlock: '4px 6px', marginLeft: 0, flex: 1 }}
vertical={false} vertical={false}
defaultValue={lineWidth} defaultValue={lineWidth}
min={1} min={10}
max={60} max={60}
onChange={(value) => setLineWidth(value)} onChange={(value) => setLineWidth(value)}
/> />
+9 -5
View File
@@ -7,8 +7,12 @@ interface ChunkedCollection {
collection: any[]; collection: any[];
type: string | number; type: string | number;
} }
type EventsType = 'CREATE' | 'UPDATE' | 'DELETE' | 'INSERT';
// Only used to update lists without nested state // Only used to update lists without nested state
export function useUpdateChunkedList(options: { export function useUpdateChunkedList(options: {
events?: EventsType[];
dataList?: any[]; dataList?: any[];
limit?: number; limit?: number;
setDataList: (args: any, opts?: any) => void; setDataList: (args: any, opts?: any) => void;
@@ -17,10 +21,10 @@ export function useUpdateChunkedList(options: {
mapFun?: (args: any) => any; mapFun?: (args: any) => any;
computedID?: (d: object) => string; computedID?: (d: object) => string;
}) { }) {
const { events = ['CREATE', 'DELETE', 'UPDATE', 'INSERT'] } = options;
const deletedIdsRef = useRef<Set<number | string>>(new Set()); const deletedIdsRef = useRef<Set<number | string>>(new Set());
const cacheDataListRef = useRef<any[]>(options.dataList || []); const cacheDataListRef = useRef<any[]>(options.dataList || []);
const timerRef = useRef<any>(null); const timerRef = useRef<any>(null);
const countRef = useRef<number>(0);
const limit = options.limit || 10; const limit = options.limit || 10;
useEffect(() => { useEffect(() => {
@@ -57,7 +61,7 @@ export function useUpdateChunkedList(options: {
} }
const ids: any[] = data?.ids || []; const ids: any[] = data?.ids || [];
// CREATE // CREATE
if (data?.type === WatchEventType.CREATE) { if (data?.type === WatchEventType.CREATE && events.includes('CREATE')) {
const newDataList = collections.reduce((acc: any[], item: any) => { const newDataList = collections.reduce((acc: any[], item: any) => {
const updateIndex = cacheDataListRef.current?.findIndex( const updateIndex = cacheDataListRef.current?.findIndex(
(sItem: any) => sItem.id === item.id (sItem: any) => sItem.id === item.id
@@ -77,7 +81,7 @@ export function useUpdateChunkedList(options: {
].slice(0, limit); ].slice(0, limit);
} }
// DELETE // DELETE
if (data?.type === WatchEventType.DELETE) { if (data?.type === WatchEventType.DELETE && events.includes('DELETE')) {
cacheDataListRef.current = cacheDataListRef.current?.filter( cacheDataListRef.current = cacheDataListRef.current?.filter(
(item: any) => { (item: any) => {
return !ids?.includes(item.id); return !ids?.includes(item.id);
@@ -89,7 +93,7 @@ export function useUpdateChunkedList(options: {
}); });
} }
// UPDATE // UPDATE
if (data?.type === WatchEventType.UPDATE) { if (data?.type === WatchEventType.UPDATE && events.includes('UPDATE')) {
collections?.forEach((item: any) => { collections?.forEach((item: any) => {
const updateIndex = cacheDataListRef.current?.findIndex( const updateIndex = cacheDataListRef.current?.findIndex(
(sItem: any) => sItem.id === item.id (sItem: any) => sItem.id === item.id
@@ -97,7 +101,7 @@ export function useUpdateChunkedList(options: {
const updateItem = { ...item }; const updateItem = { ...item };
if (updateIndex > -1) { if (updateIndex > -1) {
cacheDataListRef.current[updateIndex] = updateItem; cacheDataListRef.current[updateIndex] = updateItem;
} else if (updateIndex === -1) { } else if (updateIndex === -1 && events.includes('INSERT')) {
cacheDataListRef.current = [ cacheDataListRef.current = [
updateItem, updateItem,
...cacheDataListRef.current.slice(0, limit - 1) ...cacheDataListRef.current.slice(0, limit - 1)
+1 -1
View File
@@ -88,5 +88,5 @@ export default {
'models.form.search.gguftips': 'models.form.search.gguftips':
'If using macOS or Windows as a worker, check GGUF (uncheck for audio models).', 'If using macOS or Windows as a worker, check GGUF (uncheck for audio models).',
'models.form.button.addlabel': 'Add Label', 'models.form.button.addlabel': 'Add Label',
'models.filter.category': 'Filter by Category' 'models.filter.category': 'Filter by category'
}; };
-3
View File
@@ -22,7 +22,6 @@ import { ListItem } from './config/types';
const { Column } = Table; const { Column } = Table;
const APIKeys: React.FC = () => { const APIKeys: React.FC = () => {
console.log('APIKeys========');
const rowSelection = useTableRowSelection(); const rowSelection = useTableRowSelection();
const { sortOrder, setSortOrder } = useTableSort({ const { sortOrder, setSortOrder } = useTableSort({
defaultSortOrder: 'descend' defaultSortOrder: 'descend'
@@ -47,7 +46,6 @@ const APIKeys: React.FC = () => {
}); });
const handlePageChange = (page: number, pageSize: number) => { const handlePageChange = (page: number, pageSize: number) => {
console.log('handlePageChange====', page, pageSize);
setQueryParams({ setQueryParams({
...queryParams, ...queryParams,
page: page, page: page,
@@ -56,7 +54,6 @@ const APIKeys: React.FC = () => {
}; };
const handleTableChange = (pagination: any, filters: any, sorter: any) => { const handleTableChange = (pagination: any, filters: any, sorter: any) => {
console.log('handleTableChange=======', pagination, filters, sorter);
setSortOrder(sorter.order); setSortOrder(sorter.order);
}; };
+4 -1
View File
@@ -30,6 +30,7 @@ const Catalog: React.FC = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const [span, setSpan] = React.useState(8); const [span, setSpan] = React.useState(8);
const [activeId, setActiveId] = React.useState(-1); const [activeId, setActiveId] = React.useState(-1);
const [isFirst, setIsFirst] = React.useState(true);
const [dataSource, setDataSource] = useState<{ const [dataSource, setDataSource] = useState<{
dataList: CatalogItemType[]; dataList: CatalogItemType[];
loading: boolean; loading: boolean;
@@ -102,6 +103,8 @@ const Catalog: React.FC = () => {
total: dataSource.total total: dataSource.total
}); });
console.log('error', error); console.log('error', error);
} finally {
setIsFirst(false);
} }
}, [queryParams]); }, [queryParams]);
@@ -297,7 +300,7 @@ const Catalog: React.FC = () => {
style={{ width: '100%' }} style={{ width: '100%' }}
wrapperClassName="skelton-wrapper" wrapperClassName="skelton-wrapper"
> >
<CatalogSkelton span={span}></CatalogSkelton> {isFirst && <CatalogSkelton span={span}></CatalogSkelton>}
</Spin> </Spin>
</div> </div>
)} )}
@@ -7,7 +7,12 @@ import { Button, Drawer } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import { memo, useCallback, useEffect, useRef, useState } from 'react'; import { memo, useCallback, useEffect, useRef, useState } from 'react';
import { queryCatalogItemSpec } from '../apis'; import { queryCatalogItemSpec } from '../apis';
import { backendOptionsMap, modelSourceMap, sourceOptions } from '../config'; import {
backendOptionsMap,
modelCategoriesMap,
modelSourceMap,
sourceOptions
} from '../config';
import { CatalogSpec, FormData, ListItem } from '../config/types'; import { CatalogSpec, FormData, ListItem } from '../config/types';
import ColumnWrapper from './column-wrapper'; import ColumnWrapper from './column-wrapper';
import DataForm from './data-form'; import DataForm from './data-form';
@@ -40,6 +45,7 @@ const backendOptions = [
]; ];
const defaultQuant = ['Q4_K_M']; const defaultQuant = ['Q4_K_M'];
const EmbeddingRerankFirstQuant = ['FP16'];
const AddModal: React.FC<AddModalProps> = (props) => { const AddModal: React.FC<AddModalProps> = (props) => {
const { const {
title, title,
@@ -51,7 +57,6 @@ const AddModal: React.FC<AddModalProps> = (props) => {
current, current,
width = 600 width = 600
} = props || {}; } = props || {};
const SEARCH_SOURCE = [];
const form = useRef<any>({}); const form = useRef<any>({});
const intl = useIntl(); const intl = useIntl();
@@ -69,6 +74,16 @@ const AddModal: React.FC<AddModalProps> = (props) => {
form.current?.submit?.(); form.current?.submit?.();
}; };
const getDefaultQuant = (data: { category: string; quantOption: string }) => {
if (
data.category === modelCategoriesMap.embedding ||
data.category === modelCategoriesMap.reranker
) {
return EmbeddingRerankFirstQuant.includes(data.quantOption);
}
return defaultQuant.includes(data.quantOption);
};
const getModelFile = (spec: CatalogSpec) => { const getModelFile = (spec: CatalogSpec) => {
let modelInfo = {}; let modelInfo = {};
if (spec.source === modelSourceMap.huggingface_value) { if (spec.source === modelSourceMap.huggingface_value) {
@@ -234,7 +249,10 @@ const AddModal: React.FC<AddModalProps> = (props) => {
size: _.get(sizeList, '0.value', 0), size: _.get(sizeList, '0.value', 0),
quantization: quantization:
_.find(quantizaList, (item: { label: string; value: string }) => _.find(quantizaList, (item: { label: string; value: string }) =>
defaultQuant.includes(item.value) getDefaultQuant({
category: _.get(current, 'categories.0', ''),
quantOption: item.value
})
)?.value || _.get(quantizaList, '0.value', '') )?.value || _.get(quantizaList, '0.value', '')
}); });
@@ -264,7 +282,10 @@ const AddModal: React.FC<AddModalProps> = (props) => {
const source = _.get(sources, '0.value', ''); const source = _.get(sources, '0.value', '');
const defaultSpec = const defaultSpec =
_.find(groupList[source], (item: CatalogSpec) => { _.find(groupList[source], (item: CatalogSpec) => {
return defaultQuant.includes(item.quantization); return getDefaultQuant({
category: _.get(current, 'categories.0', ''),
quantOption: item.quantization
});
}) || _.get(groupList, `${source}.0`, {}); }) || _.get(groupList, `${source}.0`, {});
setSourceList(sources); setSourceList(sources);
@@ -320,7 +341,10 @@ const AddModal: React.FC<AddModalProps> = (props) => {
size: val, size: val,
quantization: quantization:
_.find(list, (item: { label: string; value: string }) => _.find(list, (item: { label: string; value: string }) =>
defaultQuant.includes(item.value) getDefaultQuant({
category: _.get(current, 'categories.0', ''),
quantOption: item.value
})
)?.value || _.get(list, '0.value', '') )?.value || _.get(list, '0.value', '')
}); });
+5 -2
View File
@@ -56,7 +56,7 @@ import UpdateModel from './update-modal';
import ViewLogsModal from './view-logs-modal'; import ViewLogsModal from './view-logs-modal';
interface ModelsProps { interface ModelsProps {
handleSearch: (e: any) => void; handleSearch: () => void;
handleNameChange: (e: any) => void; handleNameChange: (e: any) => void;
handleShowSizeChange?: (page: number, size: number) => void; handleShowSizeChange?: (page: number, size: number) => void;
handlePageChange: (page: number, pageSize: number | undefined) => void; handlePageChange: (page: number, pageSize: number | undefined) => void;
@@ -337,7 +337,6 @@ const Models: React.FC<ModelsProps> = ({
const handleModalOk = useCallback( const handleModalOk = useCallback(
async (data: FormData) => { async (data: FormData) => {
try { try {
console.log('data:', data, openDeployModal);
const result = getSourceRepoConfigValue(currentData?.source, data); const result = getSourceRepoConfigValue(currentData?.source, data);
await updateModel({ await updateModel({
data: { data: {
@@ -348,6 +347,7 @@ const Models: React.FC<ModelsProps> = ({
}); });
setOpenAddModal(false); setOpenAddModal(false);
message.success(intl.formatMessage({ id: 'common.message.success' })); message.success(intl.formatMessage({ id: 'common.message.success' }));
handleSearch();
} catch (error) {} } catch (error) {}
}, },
[currentData] [currentData]
@@ -385,6 +385,7 @@ const Models: React.FC<ModelsProps> = ({
updateExpandedRowKeys([modelData.id, ...expandedRowKeys]); updateExpandedRowKeys([modelData.id, ...expandedRowKeys]);
}, 300); }, 300);
message.success(intl.formatMessage({ id: 'common.message.success' })); message.success(intl.formatMessage({ id: 'common.message.success' }));
handleSearch?.();
} catch (error) {} } catch (error) {}
}, },
[openDeployModal] [openDeployModal]
@@ -405,6 +406,7 @@ const Models: React.FC<ModelsProps> = ({
removeExpandedRowKey([row.id]); removeExpandedRowKey([row.id]);
rowSelection.removeSelectedKey(row.id); rowSelection.removeSelectedKey(row.id);
handleDeleteSuccess(); handleDeleteSuccess();
handleSearch();
} }
}); });
}; };
@@ -419,6 +421,7 @@ const Models: React.FC<ModelsProps> = ({
rowSelection.clearSelections(); rowSelection.clearSelections();
removeExpandedRowKey(rowSelection.selectedRowKeys); removeExpandedRowKey(rowSelection.selectedRowKeys);
handleDeleteSuccess(); handleDeleteSuccess();
handleSearch();
} }
}); });
}; };
+16 -16
View File
@@ -45,6 +45,7 @@ const Models: React.FC = () => {
const { updateChunkedList, cacheDataListRef, deletedIdsRef } = const { updateChunkedList, cacheDataListRef, deletedIdsRef } =
useUpdateChunkedList({ useUpdateChunkedList({
events: ['UPDATE'],
dataList: dataSource.dataList, dataList: dataSource.dataList,
setDataList(list, opts?: any) { setDataList(list, opts?: any) {
setDataSource((pre) => { setDataSource((pre) => {
@@ -118,8 +119,6 @@ const Models: React.FC = () => {
_.each(list, (data: any) => { _.each(list, (data: any) => {
updateChunkedList(data); updateChunkedList(data);
}); });
console.log('deletedIdsRef=======', deletedIdsRef.current);
}; };
const updateInstanceHandler = (list: any) => { const updateInstanceHandler = (list: any) => {
@@ -129,14 +128,19 @@ const Models: React.FC = () => {
const createModelsChunkRequest = useCallback(async () => { const createModelsChunkRequest = useCallback(async () => {
chunkRequedtRef.current?.current?.cancel?.(); chunkRequedtRef.current?.current?.cancel?.();
try { try {
const query = {
search: queryParams.search,
categories: queryParams.categories
};
chunkRequedtRef.current = setChunkRequest({ chunkRequedtRef.current = setChunkRequest({
url: `${MODELS_API}?${qs.stringify(_.pickBy(queryParams, (val: any) => !!val))}`, url: `${MODELS_API}?${qs.stringify(_.pickBy(query, (val: any) => !!val))}`,
handler: updateHandler handler: updateHandler
}); });
} catch (error) { } catch (error) {
// ignore // ignore
} }
}, [queryParams]); }, [queryParams.categories, queryParams.search]);
const createModelsInstanceChunkRequest = useCallback(async () => { const createModelsInstanceChunkRequest = useCallback(async () => {
chunkInstanceRequedtRef.current?.current?.cancel?.(); chunkInstanceRequedtRef.current?.current?.cancel?.();
try { try {
@@ -150,11 +154,6 @@ const Models: React.FC = () => {
} }
}, []); }, []);
const getList = async () => {
await fetchData();
await createModelsChunkRequest();
};
const handleOnViewLogs = useCallback(() => { const handleOnViewLogs = useCallback(() => {
isPageHidden.current = true; isPageHidden.current = true;
chunkRequedtRef.current?.current?.cancel?.(); chunkRequedtRef.current?.current?.cancel?.();
@@ -173,12 +172,9 @@ const Models: React.FC = () => {
}, 100); }, 100);
}, [fetchData, createModelsChunkRequest, createModelsInstanceChunkRequest]); }, [fetchData, createModelsChunkRequest, createModelsInstanceChunkRequest]);
const handleSearch = useCallback( const handleSearch = useCallback(async () => {
async (e: any) => { await fetchData();
await fetchData(); }, [fetchData]);
},
[fetchData]
);
const debounceUpdateFilter = _.debounce((e: any) => { const debounceUpdateFilter = _.debounce((e: any) => {
setQueryParams({ setQueryParams({
@@ -202,12 +198,16 @@ const Models: React.FC = () => {
); );
useEffect(() => { useEffect(() => {
getList(); fetchData();
return () => { return () => {
axiosToken?.cancel?.(); axiosToken?.cancel?.();
}; };
}, [queryParams]); }, [queryParams]);
useEffect(() => {
createModelsChunkRequest();
}, [createModelsChunkRequest]);
useEffect(() => { useEffect(() => {
getWorkerList(); getWorkerList();
createModelsInstanceChunkRequest(); createModelsInstanceChunkRequest();
+16 -10
View File
@@ -63,7 +63,7 @@ const METAKEYS = [
]; ];
const advancedFieldsDefaultValus = { const advancedFieldsDefaultValus = {
seed: 1, seed: null,
sample_method: 'euler_a', sample_method: 'euler_a',
cfg_scale: 4.5, cfg_scale: 4.5,
guidance: 3.5, guidance: 3.5,
@@ -278,6 +278,14 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
setMessageId(); setMessageId();
setTokenResult(null); setTokenResult(null);
setCurrentPrompt(current?.content || ''); setCurrentPrompt(current?.content || '');
setUploadList((pre) => {
return pre.map((item) => {
return {
...item,
dataUrl: image
};
});
});
setRouteCache(routeCachekey['/playground/text-to-image'], true); setRouteCache(routeCachekey['/playground/text-to-image'], true);
const imgSize = _.split(finalParameters.size, 'x').map((item: string) => const imgSize = _.split(finalParameters.size, 'x').map((item: string) =>
@@ -338,8 +346,8 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
const result: any = await fetchChunkedData({ const result: any = await fetchChunkedData({
data: params, data: params,
// url: `http:///v1/images/edits?t=${Date.now()}`, // url: 'http://192.168.50.174:40053/v1/images/edits',
url: `${EDIT_IMAGE_API}?t=${Date.now()}`, url: EDIT_IMAGE_API,
signal: requestToken.current.signal signal: requestToken.current.signal
}); });
@@ -372,6 +380,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
imgItem.dataUrl = `data:image/png;base64,${item.b64_json}`; imgItem.dataUrl = `data:image/png;base64,${item.b64_json}`;
} }
const progress = _.round(item.progress, 0); const progress = _.round(item.progress, 0);
console.log('progress:', item, progress);
newImageList[item.index] = { newImageList[item.index] = {
dataUrl: imgItem.dataUrl, dataUrl: imgItem.dataUrl,
height: imgSize[1], height: imgSize[1],
@@ -381,7 +390,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
uid: imgItem.uid, uid: imgItem.uid,
span: imgItem.span, span: imgItem.span,
loading: stream_options.chunk_results ? progress < 100 : false, loading: stream_options.chunk_results ? progress < 100 : false,
preview: progress >= 100, preview: false,
progress: progress progress: progress
}; };
}); });
@@ -588,6 +597,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
); );
const handleUpdateImageList = useCallback((base64List: any) => { const handleUpdateImageList = useCallback((base64List: any) => {
console.log('updateimagelist=========', base64List);
const img = _.get(base64List, '[0].dataUrl', ''); const img = _.get(base64List, '[0].dataUrl', '');
setUploadList(base64List); setUploadList(base64List);
setImage(img); setImage(img);
@@ -667,7 +677,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
{...uploadList[0]} {...uploadList[0]}
height={125} height={125}
maxHeight={125} maxHeight={125}
preview={true} preview={false}
loading={false} loading={false}
autoSize={false} autoSize={false}
editable={false} editable={false}
@@ -728,11 +738,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
return ( return (
<div className="ground-left-wrapper"> <div className="ground-left-wrapper">
<div className="ground-left"> <div className="ground-left">
<div <div className="message-list-wrap" style={{ paddingBottom: 16 }}>
className="message-list-wrap"
ref={scroller}
style={{ paddingBottom: 16 }}
>
<> <>
<div className="content" style={{ height: '100%' }}> <div className="content" style={{ height: '100%' }}>
{ {
+2 -2
View File
@@ -74,8 +74,8 @@ const createFormData = (data: any): FormData => {
formData.append(key, value); formData.append(key, value);
} else if (typeof value === 'object' && value !== null) { } else if (typeof value === 'object' && value !== null) {
formData.append(key, JSON.stringify(value)); formData.append(key, JSON.stringify(value));
} else { } else if (value !== undefined && value !== null) {
formData.append(key, String(value)); formData.append(key, value);
} }
}; };