chore: playground mutilmodel input
This commit is contained in:
@@ -3,10 +3,12 @@ import HotKeys from '@/config/hotkeys';
|
||||
import { MinusCircleOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Input, Space, Tooltip } from 'antd';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import _ from 'lodash';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { Roles } from '../config';
|
||||
import '../style/message-item.less';
|
||||
import ThumbImg from './thumb-img';
|
||||
interface MessageItemProps {
|
||||
role: string;
|
||||
content: string;
|
||||
@@ -26,6 +28,11 @@ const MessageItem: React.FC<{
|
||||
const [isTyping, setIsTyping] = useState(false);
|
||||
const [isAnimating, setIsAnimating] = useState(false);
|
||||
const [currentIsFocus, setCurrentIsFocus] = useState(isFocus);
|
||||
const [imgList, setImgList] = useState<{ uid: number; dataUrl: string }[]>(
|
||||
[]
|
||||
);
|
||||
const imgCountRef = useRef(0);
|
||||
|
||||
const inputRef = useRef<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -61,6 +68,63 @@ const MessageItem: React.FC<{
|
||||
uid: message.uid
|
||||
});
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
};
|
||||
});
|
||||
setImgList((pre) => {
|
||||
return [...pre, ...list];
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error processing images:', error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleDeleteImg = useCallback(
|
||||
(uid: number) => {
|
||||
const list = imgList.filter((item) => item.uid !== uid);
|
||||
setImgList(list);
|
||||
},
|
||||
[imgList]
|
||||
);
|
||||
|
||||
const handleMessageChange = (e: any) => {
|
||||
// setIsTyping(true);
|
||||
handleUpdateMessage({ role: message.role, message: e.target.value });
|
||||
@@ -86,6 +150,16 @@ const MessageItem: React.FC<{
|
||||
onDelete();
|
||||
};
|
||||
|
||||
const handleOnPaste = (e: any) => {
|
||||
e.preventDefault();
|
||||
const text = e.clipboardData.getData('text');
|
||||
if (text) {
|
||||
handleUpdateMessage({ role: message.role, message: text });
|
||||
} else {
|
||||
getPasteContent(e);
|
||||
}
|
||||
};
|
||||
|
||||
useHotkeys(
|
||||
HotKeys.SUBMIT,
|
||||
() => {
|
||||
@@ -107,6 +181,7 @@ const MessageItem: React.FC<{
|
||||
</Button>
|
||||
</div>
|
||||
<div className="message-content-input">
|
||||
<ThumbImg dataList={imgList} onDelete={handleDeleteImg}></ThumbImg>
|
||||
<Input.TextArea
|
||||
ref={inputRef}
|
||||
style={{ paddingBlock: '12px' }}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||
import { Space } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import '../style/thumb-img.less';
|
||||
|
||||
const ThumbImg: React.FC<{
|
||||
dataList: any[];
|
||||
onDelete: (uid: number) => void;
|
||||
}> = ({ dataList, onDelete }) => {
|
||||
const handleOnDelete = (uid: number) => {
|
||||
onDelete(uid);
|
||||
};
|
||||
|
||||
return (
|
||||
<Space wrap size={10} className="thumb-list-wrap">
|
||||
{_.map(dataList, (item: any) => {
|
||||
return (
|
||||
<span key={item.uid} className="thumb-img">
|
||||
<span
|
||||
style={{ backgroundImage: `url(${item.dataUrl})` }}
|
||||
className="img"
|
||||
></span>
|
||||
<span className="del" onClick={() => handleOnDelete(item.uid)}>
|
||||
<CloseCircleOutlined />
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</Space>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThumbImg;
|
||||
@@ -1,7 +1,7 @@
|
||||
import IconFont from '@/components/icon-font';
|
||||
import { PageContainer } from '@ant-design/pro-components';
|
||||
import { useIntl, useSearchParams } from '@umijs/max';
|
||||
import { Button, Divider } from 'antd';
|
||||
import { Button, Divider, Space } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { useRef, useState } from 'react';
|
||||
import GroundLeft from './components/ground-left';
|
||||
@@ -24,7 +24,7 @@ const Playground: React.FC = () => {
|
||||
<PageContainer
|
||||
ghost
|
||||
extra={[
|
||||
<>
|
||||
<Space key="buttons">
|
||||
<Button
|
||||
size="middle"
|
||||
onClick={handleViewCode}
|
||||
@@ -45,7 +45,7 @@ const Playground: React.FC = () => {
|
||||
></IconFont>
|
||||
}
|
||||
></Button>
|
||||
</>
|
||||
</Space>
|
||||
]}
|
||||
className="playground-container"
|
||||
>
|
||||
@@ -58,14 +58,6 @@ const Playground: React.FC = () => {
|
||||
collapse: collapse
|
||||
})}
|
||||
>
|
||||
{/* <Button
|
||||
onClick={() => setCollapse(!collapse)}
|
||||
icon={collapse ? <MenuFoldOutlined /> : <MenuUnfoldOutlined />}
|
||||
style={{ color: 'var(--ant-color-text-tertiary)' }}
|
||||
size="small"
|
||||
type="text"
|
||||
className="collapse-btn"
|
||||
></Button> */}
|
||||
<div
|
||||
className={classNames('divider-line', {
|
||||
collapse: collapse
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
.thumb-img {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
|
||||
.img {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border-radius: var(--border-radius-base);
|
||||
cursor: pointer;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
border: 1px solid var(--ant-color-border);
|
||||
}
|
||||
|
||||
.del {
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
right: -2px;
|
||||
font-size: var(--font-size-middle);
|
||||
cursor: pointer;
|
||||
background-color: var(--color-white-1);
|
||||
display: none;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.del {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.thumb-list-wrap {
|
||||
padding: 10px;
|
||||
// background-color: var(--color-fill-1);
|
||||
}
|
||||
Reference in New Issue
Block a user