fix: playground edit message
This commit is contained in:
@@ -48,74 +48,75 @@ const ContentItem: React.FC<MessageItemProps> = ({
|
||||
});
|
||||
};
|
||||
|
||||
const getPasteContent = useCallback(async (event: any) => {
|
||||
const clipboardData = event.clipboardData || window.clipboardData;
|
||||
const items = clipboardData.items;
|
||||
const imgPromises: Promise<string>[] = [];
|
||||
const getPasteContent = useCallback(
|
||||
async (event: any) => {
|
||||
const clipboardData = event.clipboardData || window.clipboardData;
|
||||
const items = clipboardData.items;
|
||||
const imgPromises: Promise<string>[] = [];
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let item = items[i];
|
||||
console.log('item===========', item);
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let item = items[i];
|
||||
console.log('item===========', item);
|
||||
|
||||
if (item.kind === 'file' && item.type.indexOf('image') !== -1) {
|
||||
const file = item.getAsFile();
|
||||
const imgPromise = new Promise<string>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (event) {
|
||||
const base64String = event.target?.result as string;
|
||||
if (base64String) {
|
||||
resolve(base64String);
|
||||
} else {
|
||||
reject('Failed to convert image to base64');
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
imgPromises.push(imgPromise);
|
||||
} else if (item.kind === 'string') {
|
||||
// string
|
||||
if (item.kind === 'file' && item.type.indexOf('image') !== -1) {
|
||||
const file = item.getAsFile();
|
||||
const imgPromise = new Promise<string>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (event) {
|
||||
const base64String = event.target?.result as string;
|
||||
if (base64String) {
|
||||
resolve(base64String);
|
||||
} else {
|
||||
reject('Failed to convert image to base64');
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
imgPromises.push(imgPromise);
|
||||
} else if (item.kind === 'string') {
|
||||
// string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const imgs = await Promise.all(imgPromises);
|
||||
if (imgs.length) {
|
||||
const list = _.map(imgs, (img: string) => {
|
||||
imgCountRef.current += 1;
|
||||
return {
|
||||
uid: imgCountRef.current,
|
||||
dataUrl: img
|
||||
};
|
||||
});
|
||||
try {
|
||||
const imgs = await Promise.all(imgPromises);
|
||||
if (imgs.length) {
|
||||
const list = _.map(imgs, (img: string) => {
|
||||
imgCountRef.current += 1;
|
||||
return {
|
||||
uid: imgCountRef.current,
|
||||
dataUrl: img
|
||||
};
|
||||
});
|
||||
|
||||
updateMessage?.({
|
||||
role: data.role,
|
||||
content: data.content,
|
||||
uid: data.uid,
|
||||
imgs: [...(data.imgs || []), ...list]
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error processing images:', error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleOnPaste = useCallback(
|
||||
(e: any) => {
|
||||
const text = e.clipboardData.getData('text');
|
||||
if (text) {
|
||||
updateMessage?.({
|
||||
role: data.role,
|
||||
content: inputRef.current?.resizableTextArea?.textArea?.value || '',
|
||||
uid: data.uid
|
||||
});
|
||||
} else {
|
||||
getPasteContent(e);
|
||||
updateMessage?.({
|
||||
role: data.role,
|
||||
content: data.content,
|
||||
uid: data.uid,
|
||||
imgs: [...(data.imgs || []), ...list]
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error processing images:', error);
|
||||
}
|
||||
},
|
||||
[getPasteContent, data, updateMessage]
|
||||
[data]
|
||||
);
|
||||
|
||||
const handleOnPaste = (e: any) => {
|
||||
e.preventDefault();
|
||||
const text = e.clipboardData.getData('text');
|
||||
if (text) {
|
||||
updateMessage?.({
|
||||
role: data.role,
|
||||
content: data.content + text,
|
||||
uid: data.uid
|
||||
});
|
||||
} else {
|
||||
getPasteContent(e);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateImgList = useCallback(
|
||||
(list: { uid: number | string; dataUrl: string }[]) => {
|
||||
console.log('list===========', data.imgs, list);
|
||||
|
||||
@@ -111,16 +111,38 @@ const MultiCompare: React.FC<MultiCompareProps> = ({ modelList }) => {
|
||||
});
|
||||
};
|
||||
|
||||
const adjustSpan = () => {
|
||||
const count = spans.count - 1;
|
||||
if (spans.count === 6) {
|
||||
setSpans({
|
||||
span: 8,
|
||||
count: count
|
||||
});
|
||||
} else if (spans.count === 5) {
|
||||
setSpans({
|
||||
span: 12,
|
||||
count: count
|
||||
});
|
||||
} else if (spans.count === 4) {
|
||||
setSpans({
|
||||
span: 8,
|
||||
count: count
|
||||
});
|
||||
} else if (spans.count === 3) {
|
||||
setSpans({
|
||||
span: 12,
|
||||
count: count
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteModel = (instanceId: symbol) => {
|
||||
const newModelList = modelSelections.filter(
|
||||
(model) => model.instanceId !== instanceId
|
||||
);
|
||||
pruneInstanceSymbol(instanceId);
|
||||
const span = Math.floor(24 / (24 / spans.span - 1));
|
||||
setSpans({
|
||||
span,
|
||||
count: spans.count
|
||||
});
|
||||
|
||||
adjustSpan();
|
||||
setModelSelections(newModelList);
|
||||
};
|
||||
|
||||
@@ -143,6 +165,14 @@ const MultiCompare: React.FC<MultiCompareProps> = ({ modelList }) => {
|
||||
setModelSelections(updateList);
|
||||
};
|
||||
|
||||
const handleApplySystemChangeToAll = (message: string) => {
|
||||
const modelRefList = Object.getOwnPropertySymbols(modelRefs.current);
|
||||
modelRefList.forEach((instanceId: symbol) => {
|
||||
const ref = modelRefs.current[instanceId];
|
||||
ref?.setSystemMessage(message);
|
||||
});
|
||||
};
|
||||
|
||||
const handlePresetPrompt = (list: { role: string; content: string }[]) => {
|
||||
const sysMsg = list.filter((item) => item.role === 'system');
|
||||
const userMsg = list.filter((item) => item.role === 'user');
|
||||
@@ -227,6 +257,8 @@ const MultiCompare: React.FC<MultiCompareProps> = ({ modelList }) => {
|
||||
spans,
|
||||
globalParams,
|
||||
loadingStatus,
|
||||
modelFullList: modelList,
|
||||
handleApplySystemChangeToAll,
|
||||
setGlobalParams,
|
||||
setLoadingStatus: handleSetLoadingStatus,
|
||||
handleDeleteModel: handleDeleteModel
|
||||
@@ -252,7 +284,7 @@ const MultiCompare: React.FC<MultiCompareProps> = ({ modelList }) => {
|
||||
setModelSelections={handleUpdateModelSelections}
|
||||
presetPrompt={handlePresetPrompt}
|
||||
modelList={modelFullList}
|
||||
showModelSelection={true}
|
||||
showModelSelection={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -47,6 +47,8 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
||||
setGlobalParams,
|
||||
setLoadingStatus,
|
||||
handleDeleteModel,
|
||||
handleApplySystemChangeToAll,
|
||||
modelFullList,
|
||||
loadingStatus
|
||||
} = useContext(CompareContext);
|
||||
const intl = useIntl();
|
||||
@@ -224,7 +226,7 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
||||
isApplyToAllModels.current = e.target.checked;
|
||||
if (e.target.checked) {
|
||||
setGlobalParams({
|
||||
...params
|
||||
..._.omit(params, 'model')
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -289,10 +291,10 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
||||
};
|
||||
|
||||
const modelOptions = useMemo(() => {
|
||||
return modelList.filter((item) => {
|
||||
return modelFullList.filter((item) => {
|
||||
return item.type !== 'empty';
|
||||
});
|
||||
}, [modelList]);
|
||||
}, [modelFullList]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('globalParams:', globalParams.model, globalParams);
|
||||
@@ -326,9 +328,9 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
||||
<div className="header">
|
||||
<span className="title">
|
||||
<Select
|
||||
style={{ minWidth: '100px' }}
|
||||
style={{ minWidth: '120px' }}
|
||||
variant="borderless"
|
||||
options={modelOptions}
|
||||
options={modelFullList}
|
||||
onChange={handleModelChange}
|
||||
value={params.model}
|
||||
></Select>
|
||||
@@ -379,7 +381,9 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
||||
title={
|
||||
<div>
|
||||
<Checkbox onChange={handleApplyToAllModels}>
|
||||
Apply to all models
|
||||
{intl.formatMessage({
|
||||
id: 'playground.compare.applytoall'
|
||||
})}
|
||||
</Checkbox>
|
||||
</div>
|
||||
}
|
||||
@@ -401,7 +405,9 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
||||
</span>
|
||||
</div>
|
||||
<SystemMessage
|
||||
showApplyToAll={true}
|
||||
systemMessage={systemMessage}
|
||||
applyToAll={handleApplySystemChangeToAll}
|
||||
setSystemMessage={setSystemMessage}
|
||||
></SystemMessage>
|
||||
<SimpleBar style={{ maxHeight: maxHeight }}>
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
import { CloseOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Divider, Input, Tooltip } from 'antd';
|
||||
import { Button, Checkbox, Divider, Input, Tooltip } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import React, { useState } from 'react';
|
||||
import '../../style/sys-message.less';
|
||||
|
||||
interface SystemMessageProps {
|
||||
style?: React.CSSProperties;
|
||||
systemMessage: string;
|
||||
showApplyToAll?: boolean;
|
||||
applyToAll?: (e: any) => void;
|
||||
setSystemMessage: (value: string) => void;
|
||||
}
|
||||
|
||||
const SystemMessage: React.FC<SystemMessageProps> = (props) => {
|
||||
const { systemMessage, setSystemMessage, style } = props;
|
||||
const { systemMessage, showApplyToAll, setSystemMessage, style, applyToAll } =
|
||||
props;
|
||||
const intl = useIntl();
|
||||
const [isChange, setIsChange] = useState(false);
|
||||
const systemMessageRef = React.useRef<any>(null);
|
||||
const [autoSize, setAutoSize] = useState<{
|
||||
minRows: number;
|
||||
@@ -33,26 +38,51 @@ const SystemMessage: React.FC<SystemMessageProps> = (props) => {
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
const handleBlur = (e: any) => {
|
||||
setAutoSize({
|
||||
minRows: 1,
|
||||
maxRows: 1,
|
||||
focus: false
|
||||
});
|
||||
setIsChange(false);
|
||||
};
|
||||
|
||||
const handleOnChange = (e: any) => {
|
||||
setSystemMessage(e.target.value);
|
||||
setIsChange(true);
|
||||
};
|
||||
|
||||
const handleClearSystemMessage = () => {
|
||||
setSystemMessage('');
|
||||
};
|
||||
|
||||
const handleClickCheckbox = (e?: any) => {
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
const handleApplyToAllModels = (e: any) => {
|
||||
if (e.target.checked) {
|
||||
applyToAll?.(systemMessage);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="sys-message" style={{ ...style }}>
|
||||
<div
|
||||
className={classNames('sys-message', {
|
||||
focus: autoSize.focus
|
||||
})}
|
||||
style={{ ...style }}
|
||||
>
|
||||
{
|
||||
<div style={{ display: autoSize.focus ? 'block' : 'none' }}>
|
||||
<div
|
||||
style={{ display: autoSize.focus ? 'block' : 'none' }}
|
||||
className="textarea-wrapper"
|
||||
>
|
||||
<span className="system-label">
|
||||
{intl.formatMessage({ id: 'playground.systemMessage' })}
|
||||
</span>
|
||||
<Input.TextArea
|
||||
className="custome-scrollbar"
|
||||
ref={systemMessageRef}
|
||||
variant="filled"
|
||||
placeholder={intl.formatMessage({ id: 'playground.system.tips' })}
|
||||
@@ -68,8 +98,17 @@ const SystemMessage: React.FC<SystemMessageProps> = (props) => {
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
allowClear={false}
|
||||
onChange={(e) => setSystemMessage(e.target.value)}
|
||||
onChange={handleOnChange}
|
||||
></Input.TextArea>
|
||||
{isChange && showApplyToAll && (
|
||||
<span className="apply-check" onMouseDown={handleClickCheckbox}>
|
||||
<Checkbox onChange={handleApplyToAllModels}>
|
||||
{intl.formatMessage({
|
||||
id: 'playground.compare.applytoall'
|
||||
})}
|
||||
</Checkbox>
|
||||
</span>
|
||||
)}
|
||||
<Divider style={{ margin: '0' }}></Divider>
|
||||
</div>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user