style: playground style

main
jialin 1 year ago
parent c04b9342b8
commit b041cdc766

@ -46,7 +46,9 @@ export default {
},
token: {
colorPrimary: '#007BFF',
borderRadius: 6,
colorSuccess: '#54cc98',
borderRadius: 4,
borderRadiusSM: 2,
fontSize: 12,
motion: true
}

@ -1,7 +1,7 @@
import { createFromIconfontCN } from '@ant-design/icons';
const IconFont = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/c/font_4613488_fcpq8y25444.js'
scriptUrl: '//at.alicdn.com/t/c/font_4613488_7vr8v36d7xp.js'
});
export default IconFont;

@ -77,7 +77,7 @@ const LabelItem: React.FC<LabelItemProps> = ({
title={intl.formatMessage({ id: 'resources.table.key.tips' })}
>
<SealInput.Input
label="Key"
label={intl.formatMessage({ id: 'common.input.key' })}
value={label.key}
onChange={handleOnKeyChange}
onBlur={handleKeyOnBlur}
@ -89,7 +89,7 @@ const LabelItem: React.FC<LabelItemProps> = ({
<div className="label-value">
{valueAddon ?? (
<SealInput.Input
label="Value"
label={intl.formatMessage({ id: 'common.input.value' })}
value={label.value}
onChange={handleOnValueChange}
></SealInput.Input>

@ -1,23 +1,26 @@
import { platformCall } from '@/utils';
const platform = platformCall();
const KeybindingsMap = {
CREATE: ['alt+ctrl+N', 'alt+meta+N'],
CLEAR: ['alt+ctrl+K', 'alt+meta+K'],
RIGHT: ['ctrl+RIGHT', 'meta+RIGHT'],
SAVE: ['ctrl+S', 'meta+S'],
SUBMIT: ['ctrl+enter', 'meta+enter'],
SAVEAS: ['alt+ctrl+S', 'alt+meta+S'],
OPEN: ['alt+ctrl+O', 'alt+meta+O'],
CANCEL: ['ctrl+W', 'meta+W'],
CREATE: ['Alt+Ctrl+N', 'Alt+Meta+N'],
CLEAR: ['Alt+Ctrl+K', 'Alt+Meta+K'],
RIGHT: ['Ctrl+RIGHT', 'Meta+RIGHT'],
SAVE: ['Ctrl+S', 'Meta+S'],
SUBMIT: ['Ctrl+Enter', 'Meta+Enter'],
SAVEAS: ['Alt+Ctrl+S', 'Alt+Meta+S'],
OPEN: ['Alt+Ctrl+O', 'Alt+Meta+O'],
CANCEL: ['Ctrl+W', 'Meta+W'],
DELETE: ['delete'],
COPY: ['ctrl+C', 'meta+C'],
REFRESH: ['ctrl+R', 'meta+R'],
EDIT: ['ctrl+E', 'meta+E'],
SEARCH: ['ctrl+K', 'meta+K'],
RESET: ['alt+ctrl+R', 'alt+meta+R'],
INPUT: ['ctrl+K', 'meta+K'],
NEW1: ['ctrl+1', 'meta+1'],
NEW2: ['ctrl+2', 'meta+2']
COPY: ['Ctrl+C', 'Meta+C'],
REFRESH: ['Ctrl+R', 'Meta+R'],
EDIT: ['Ctrl+E', 'Meta+E'],
SEARCH: ['Ctrl+K', 'Meta+K'],
RESET: ['Alt+Ctrl+R', 'Alt+Meta+R'],
INPUT: ['Ctrl+K', 'Meta+K'],
NEW1: ['Ctrl+1', 'Meta+1'],
NEW2: ['Ctrl+2', 'Meta+2'],
FOCUS: ['/', '/'],
ADD: ['Alt+Ctrl+Enter', 'Alt+Meta+Enter']
};
type KeyBindingType = keyof typeof KeybindingsMap;
@ -36,11 +39,11 @@ const KeybiningList: KeybindingValue[] = Object.entries(KeybindingsMap).map(
keybinding: keybinding,
command: key,
textKeybinding: platform.isMac
? keybinding.replace('meta', 'Cmd').replace('alt', 'Option')
: keybinding.replace('ctrl', 'Ctrl'),
? keybinding.replace('Meta', 'Cmd').replace('Alt', 'Option')
: keybinding.replace('Ctrl', 'Ctrl'),
iconKeybinding: platform.isMac
? keybinding.replace('meta', '⌘').replace('alt', '⌥')
: keybinding.replace('ctrl', 'Ctrl')
? keybinding.replace('Meta', '⌘').replace('Alt', '⌥')
: keybinding.replace('Ctrl', 'Ctrl')
} as KeybindingValue;
}
);

@ -5,7 +5,7 @@ html {
--ant-color-text-secondary: rgba(0, 0, 0, 65%);
--ant-color-text-tertiary: rgba(0, 0, 0, 45%);
--ant-color-text-quaternary: rgba(0, 0, 0, 25%);
--ant-color-fill: rgba(0, 0, 0, 15%);
--ant-color-fill: rgba(223, 168, 168, 15%);
--ant-color-fill-secondary: rgba(0, 0, 0, 6%);
--ant-color-fill-tertiary: rgba(0, 0, 0, 4%);
--ant-color-fill-quaternary: rgba(0, 0, 0, 2%);
@ -21,11 +21,12 @@ html {
--color-logs-text: #d4d4d4;
--layout-content-blockpadding: 32px;
--layout-content-inlinepadding: 32px;
--menu-border-radius-base: 6px;
--border-radius-base: 6px;
--border-radius-modal: 6px;
--menu-border-radius-base: 4px;
--border-radius-base: 4px;
--border-radius-middle: 20px;
--border-radius-small: 6px;
--border-radius-mdium: 6px;
--border-radius-small: 4px;
--border-radius-mdium: 4px;
--border-radius-mini: 4px;
--color-white-1: rgba(255, 255, 255, 100%);
--color-fill-sider: #f4f5f4;
@ -39,11 +40,11 @@ html {
--font-size-base: 12px;
--font-size-large: 16px;
--font-size-middle: 14px;
--table-td-radius: 6px;
--checkbox-border-radius: 4px;
--table-td-radius: 4px;
--checkbox-border-radius: 2px;
--ant-table-cell-padding-inline: 16px;
--ant-table-cell-padding-block: 6px;
--ant-table-header-border-radius: 6px;
--ant-table-header-border-radius: 4px;
--ant-table-header-split-color: #f0f0f0;
--ant-table-row-selected-bg: #e6f6ff;
--ant-table-row-selected-hover-bg: #e6f6ff;
@ -59,7 +60,7 @@ html {
--ant-input-active-border-color: #007bff;
--ant-input-hover-border-color: #2997ff;
--box-shadow-base: 0 4px 6px rgba(227, 232, 240, 70%);
--ant-border-radius-lg: 6px;
--ant-border-radius-lg: 4px;
--ant-menu-item-color: var(--color-text-1);
--color-selected-bg: rgba(230, 230, 230, 88%);
// --box-shadow-base: none;
@ -75,7 +76,7 @@ html {
&.ant-menu-css-var {
// --ant-menu-item-selected-bg: var(--color-white-1);
--ant-menu-item-border-radius: 6px;
--ant-menu-item-border-radius: 4px;
--ant-menu-item-selected-color: var(--ant-color-primary);
--ant-menu-item-color: var(--color-text-1);
}
@ -92,7 +93,7 @@ html {
--ant-font-size-xl: 20px;
--ant-font-size: var(--font-size-base);
--ant-padding-sm: 14px;
--ant-border-radius-lg: 6px;
--ant-border-radius-lg: 4px;
--ant-color-text: #000;
--ant-color-error: #ff4d4f;
--ant-color-bg-mask: rgba(0, 0, 0, 35%);
@ -113,6 +114,10 @@ html {
--ant-table-row-hover-bg: #e6e6e6;
}
&.ant-progress {
--ant-progress-line-border-radius: 2px;
}
&.ant-modal-css-var {
--ant-modal-title-font-size: 14px;
--ant-modal-header-margin-bottom: 20px;
@ -126,7 +131,7 @@ html {
.css-var-ri.ant-menu-css-var,
.css-var-rh.ant-menu-css-var {
--ant-menu-item-height: 46px;
--ant-menu-item-border-radius: 6px;
--ant-menu-item-border-radius: 4px;
--ant-menu-item-selected-color: var(--ant-color-primary);
--ant-menu-item-color: var(--color-text-1);
--ant-menu-item-active-bg: rgba(0, 0, 0, 4%);
@ -148,6 +153,9 @@ html {
body * {
font-weight: var(--font-weight-normal);
font-family: 'noto sans', sans-serif;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
}
body {
@ -305,7 +313,7 @@ body {
.collapse-wrap {
display: none;
position: absolute;
top: 8px;
top: 12px;
}
&:hover {
@ -460,7 +468,29 @@ body {
}
// ======== monaco editor style ============
.monaco-editor {
border-radius: 16px;
border-radius: 8px;
}
.custome-scrollbar {
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-thumb {
background-color: transparent;
border-radius: 4px;
}
&::-webkit-scrollbar-track {
background-color: transparent;
}
&:hover {
&::-webkit-scrollbar-thumb {
background-color: var(--color-scrollbar-thumb);
border-radius: 4px;
}
}
}
.ant-message-notice-wrapper {

@ -23,7 +23,7 @@ import {
} from '@umijs/max';
import { Button, Modal } from 'antd';
import { useAtom } from 'jotai';
import { useMemo, useState } from 'react';
import { useCallback, useMemo, useState } from 'react';
import Exception from './Exception';
import './Layout.css';
import { LogoIcon, SLogoIcon } from './Logo';
@ -93,6 +93,7 @@ export default (props: any) => {
const intl = useIntl();
const { clientRoutes, pluginManager } = useAppData();
const [collapsed, setCollapsed] = useState(false);
const [collapseValue, setCollapseValue] = useState(false);
const initialInfo = (useModel && useModel('@@initialState')) || {
initialState: undefined,
@ -167,6 +168,51 @@ export default (props: any) => {
() => matchRoutes(route?.children || [], location.pathname)?.pop?.()?.route,
[location.pathname]
);
const renderMenuHeader = useCallback(
(logo, title) => {
return (
<>
{logo}
<div className="collapse-wrap">
<Button
size="small"
type={collapsed ? 'default' : 'text'}
onClick={handleToggleCollapse}
>
<>
<MenuUnfoldOutlined
style={{ display: collapsed ? 'block' : 'none' }}
/>
<MenuFoldOutlined
style={{ display: !collapsed ? 'block' : 'none' }}
/>
</>
</Button>
</div>
</>
);
},
[collapsed]
);
const actionRender = useCallback(
(layoutProps) => {
const dom = getRightRenderContent({
runtimeConfig,
loading,
initialState,
setInitialState,
intl,
siderWidth: layoutProps.siderWidth,
collapsed: layoutProps.collapsed
});
return dom;
},
[intl]
);
return (
<div>
<div className="background"></div>
@ -183,21 +229,7 @@ export default (props: any) => {
e.preventDefault();
navigate('/');
}}
menuHeaderRender={(logo, title) => {
return (
<>
{logo}
<div className="collapse-wrap">
<Button
type={collapsed ? 'default' : 'text'}
onClick={handleToggleCollapse}
>
{collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
</Button>
</div>
</>
);
}}
menuHeaderRender={renderMenuHeader}
collapsed={collapsed}
onPageChange={(route) => {
const { location } = history;
@ -258,19 +290,7 @@ export default (props: any) => {
fixSiderbar
fixedHeader
{...runtimeConfig}
actionsRender={(layoutProps) => {
const dom = getRightRenderContent({
runtimeConfig,
loading,
initialState,
setInitialState,
intl,
siderWidth: layoutProps.siderWidth,
collapsed: layoutProps.collapsed
});
return dom;
}}
actionsRender={actionRender}
>
<Exception
route={matchedRoute}

@ -113,9 +113,9 @@ export default {
'common.button.logs': 'Logs',
'common.ws.close': 'The connection was lost, do you want to reconnect?',
'common.ws.reconnect': 'Reconnect',
'common.input.key': 'key',
'common.input.value': 'value',
'common.input.type': 'type',
'common.input.key': 'Key',
'common.input.value': 'Value',
'common.input.type': 'Type',
'common.input.visible': 'visibility',
'common.input.description': 'description',
'common.time.day': 'day',

@ -1,7 +1,8 @@
export default {
'playground.system.tips': 'Enter system message here',
'playground.system.tips': 'Type system instructions here',
'playground.title': 'Playground',
'playground.system': 'System',
'playground.systemMessage': 'System instructions',
'playground.user': 'User',
'playground.assistant': 'Assistant',
'playground.newMessage': 'New Message',

@ -2,6 +2,7 @@ export default {
'playground.system.tips': '在这里输入系统消息',
'playground.title': '试验场',
'playground.system': '系统',
'playground.systemMessage': '系统消息',
'playground.user': '用户',
'playground.assistant': '小助手',
'playground.newMessage': '新消息',

@ -136,6 +136,12 @@ export async function queryHuggingfaceModelDetail(
});
}
export async function queryModelScopeModels() {
return request(`https://www.modelscope.cn/api/v1/dolphin/models`, {
method: 'PUT'
});
}
export async function queryHuggingfaceModels(
params: {
search: {

@ -153,7 +153,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
paddingInline: 'var(--ant-table-cell-padding-inline)'
}}
>
<Tooltip title={renderWorkerInfo(item)} trigger={['click']}>
<Tooltip title={renderWorkerInfo(item)}>
<span className="m-r-5">{item.name}</span>
<InfoCircleOutlined />
</Tooltip>

@ -1,6 +1,6 @@
:local(.login-form-wrapper) {
margin: 0 auto;
border-radius: 8px;
border-radius: var(--border-radius-modal);
width: max-content;
height: max-content;
padding: 32px;

@ -1,9 +1,7 @@
import HotKeys from '@/config/hotkeys';
import useContainerScroll from '@/hooks/use-container-scorll';
import { fetchChunkedData, readStreamData } from '@/utils/fetch-chunk-data';
import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
import { useIntl, useSearchParams } from '@umijs/max';
import { Button, Tooltip } from 'antd';
import { Spin } from 'antd';
import classNames from 'classnames';
import _ from 'lodash';
import {
@ -14,7 +12,6 @@ import {
useRef,
useState
} from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import 'simplebar-react/dist/simplebar.min.css';
import { CHAT_API } from '../apis';
import { Roles } from '../config';
@ -25,6 +22,7 @@ import MessageInput from './message-input';
import MessageContent from './multiple-chat/message-content';
import SystemMessage from './multiple-chat/system-message';
import ParamsSettings from './params-settings';
import ReferenceParams from './reference-params';
import ViewCodeModal from './view-code-modal';
interface MessageProps {
@ -43,14 +41,12 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
const selectModel = searchParams.get('model') || '';
const [parameters, setParams] = useState<any>({});
const [systemMessage, setSystemMessage] = useState('');
const [collapsed, setCollapsed] = useState(true);
const [show, setShow] = useState(false);
const [loading, setLoading] = useState(false);
const [activeIndex, setActiveIndex] = useState(-1);
const [tokenResult, setTokenResult] = useState<any>(null);
const [currentIsFocus, setCurrentIsFocus] = useState(false);
const [collapse, setCollapse] = useState(false);
const systemRef = useRef<any>(null);
const contentRef = useRef<any>('');
const controllerRef = useRef<any>(null);
const scroller = useRef<any>(null);
@ -81,9 +77,6 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
}
};
});
const handleSystemMessageChange = (e: any) => {
setSystemMessage(e.target.value);
};
const setMessageId = () => {
messageId.current = messageId.current + 1;
@ -223,10 +216,7 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
}
setMessageId();
setMessageList([]);
};
const handleView = () => {
setShow(true);
setTokenResult(null);
};
const handleSendMessage = (message: { role: string; content: string }) => {
@ -235,53 +225,10 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
submitMessage(currentMessage);
};
const handleSubmit = () => {
submitMessage();
};
const handleCloseViewCode = () => {
setShow(false);
};
const handleDelete = (index: number) => {
messageList.splice(index, 1);
setMessageList([...messageList]);
};
const handleUpdateMessage = (index: number, message: MessageItem) => {
messageList[index] = message;
setMessageList([...messageList]);
};
const renderLabel = () => {
return (
<div className="system-message-wrap ">
<span className="title">
{intl.formatMessage({ id: 'playground.system' })}
</span>
<Tooltip
title={
collapsed
? intl.formatMessage({ id: 'common.button.collapse' })
: intl.formatMessage({ id: 'common.button.expand' })
}
>
<Button size="small">
{collapsed ? <EyeInvisibleOutlined /> : <EyeOutlined />}
</Button>
</Tooltip>
</div>
);
};
const handleFocus = () => {
setCurrentIsFocus(true);
};
const handleBlur = () => {
setCurrentIsFocus(false);
};
const handleSelectModel = () => {};
const handlePresetPrompt = (list: { role: string; content: string }[]) => {
@ -299,95 +246,30 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
setMessageList(userMsg);
};
useHotkeys(
HotKeys.SUBMIT,
() => {
handleSubmit();
},
{
enabled: currentIsFocus && !loading,
enableOnFormTags: currentIsFocus && !loading,
preventDefault: true
}
);
useHotkeys(
HotKeys.CREATE.join(','),
() => {
handleNewMessage();
},
{
enabled: !loading,
enableOnFormTags: !loading,
preventDefault: true
}
);
useHotkeys(
HotKeys.CLEAR.join(','),
() => {
handleClear();
},
{
enabled: !loading,
enableOnFormTags: !loading,
preventDefault: true
}
);
return (
<div className="ground-left-wrapper">
<div className="ground-left">
<div className="message-list-wrap" onWheel={handleContentWheel}>
<div
className="message-list-wrap"
onWheel={handleContentWheel}
ref={scroller}
>
<div
style={{
marginBottom: 20,
borderRadius: 'var(--border-radius-mini)',
overflow: 'hidden'
marginBottom: 20
}}
>
<SystemMessage
style={{
borderRadius: 'var(--border-radius-mini)',
overflow: 'hidden'
}}
systemMessage={systemMessage}
setSystemMessage={setSystemMessage}
></SystemMessage>
{/* <TransitionWrapper
header={renderLabel()}
variant="filled"
setCollapsed={setCollapsed}
ref={systemRef}
>
<Input.TextArea
value={systemMessage}
variant="filled"
autoSize={true}
onFocus={handleFocus}
onBlur={handleBlur}
style={{ minHeight: 40 }}
placeholder={intl.formatMessage({
id: 'playground.system.tips'
})}
onChange={handleSystemMessageChange}
></Input.TextArea>
</TransitionWrapper> */}
</div>
<div className="content">
{/* {messageList.map((item, index) => {
return (
<MessageItem
key={item.uid}
isFocus={index === activeIndex}
islast={index === messageList.length - 1}
loading={loading}
onDelete={() => handleDelete(index)}
updateMessage={(message: MessageItem) =>
handleUpdateMessage(index, message)
}
onSubmit={handleSubmit}
message={item}
/>
);
})} */}
<MessageContent
spans={{
span: 24,
@ -398,15 +280,21 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
editable={true}
loading={loading}
/>
{/* {loading && (
<Spin>
<div style={{ height: '46px' }}></div>
</Spin>
)} */}
{loading && (
<Spin size="small">
<div style={{ height: '46px' }}></div>
</Spin>
)}
</div>
</div>
{tokenResult && (
<div style={{ height: 40 }}>
<ReferenceParams usage={tokenResult}></ReferenceParams>
</div>
)}
<div className="ground-left-footer">
<MessageInput
scope="chat"
loading={loading}
disabled={!parameters.model}
isEmpty={!messageList.length}

@ -1,16 +1,16 @@
import IconFont from '@/components/icon-font';
import HotKeys from '@/config/hotkeys';
import HotKeys, { KeyMap } from '@/config/hotkeys';
import { platformCall } from '@/utils';
import {
ClearOutlined,
ControlOutlined,
EnterOutlined,
SendOutlined,
SwapOutlined
} from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Divider, Input, Select, Tooltip } from 'antd';
import _ from 'lodash';
import { useCallback, useRef, useState } from 'react';
import { useCallback, useMemo, useRef, useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { Roles } from '../config';
import { MessageItem } from '../config/types';
@ -77,6 +77,7 @@ interface MessageInputProps {
showModelSelection?: boolean;
disabled: boolean;
isEmpty?: boolean;
scope: string;
}
const MessageInput: React.FC<MessageInputProps> = ({
@ -91,19 +92,26 @@ const MessageInput: React.FC<MessageInputProps> = ({
modelList,
showModelSelection,
disabled,
isEmpty
isEmpty,
scope
}) => {
const { TextArea } = Input;
const intl = useIntl();
const platform = platformCall();
// const [disabled, setDisabled] = useState(false);
const [open, setOpen] = useState(false);
const [focused, setFocused] = useState(false);
const [message, setMessage] = useState<CurrentMessage>({
role: Roles.User,
content: '',
imgs: []
});
const imgCountRef = useRef(0);
const inputRef = useRef<any>(null);
const isDisabled = useMemo(() => {
return disabled ? true : !message.content && isEmpty;
}, [disabled, message.content, isEmpty]);
const resetMessage = () => {
setMessage({
@ -162,7 +170,7 @@ const MessageInput: React.FC<MessageInputProps> = ({
};
const handleAddMessage = () => {
console.log('add message');
console.log('add message=====1');
addMessage({ ...message });
resetMessage();
};
@ -279,12 +287,42 @@ const MessageInput: React.FC<MessageInputProps> = ({
);
useHotkeys(
HotKeys.SUBMIT.join(','),
HotKeys.SUBMIT,
() => {
console.log('submit message', loading);
inputRef.current?.blur?.();
handleSendMessage();
},
{ enabled: true }
{
enabled: !loading && !isDisabled,
enableOnFormTags: focused,
preventDefault: true
}
);
useHotkeys(
HotKeys.ADD,
(e: any) => {
e.preventDefault();
e.stopPropagation();
console.log('add message', loading);
inputRef.current?.blur?.();
handleAddMessage();
},
{
enabled: !loading,
enableOnFormTags: focused,
preventDefault: true
}
);
useHotkeys(
HotKeys.FOCUS,
() => {
inputRef.current?.focus?.({
cursor: 'end'
});
},
{ preventDefault: true }
);
return (
@ -357,37 +395,46 @@ const MessageInput: React.FC<MessageInputProps> = ({
></Select>
)}
<Button type="default" size="middle" onClick={handleAddMessage}>
{intl.formatMessage({ id: 'common.button.add' })}
</Button>
{!loading ? (
<Button
type="primary"
onClick={handleSendMessage}
size="middle"
disabled={disabled ? true : !message.content && isEmpty}
>
{intl.formatMessage({ id: 'common.button.submit' })}
<span className="m-l-5 opct-7">
{platform.isMac ? (
<>
<IconFont type="icon-command"></IconFont> +{' '}
<EnterOutlined />
</>
) : (
<>
CTRL + <EnterOutlined />
</>
)}
<Tooltip
title={
<span>
[{KeyMap.ADD.textKeybinding}]{' '}
{intl.formatMessage({ id: 'common.button.add' })}
</span>
}
>
<Button type="default" size="middle" onClick={handleAddMessage}>
{intl.formatMessage({ id: 'common.button.add' })}
</Button>
</Tooltip>
{!loading ? (
<Tooltip
title={
<span>
[{KeyMap.SUBMIT.textKeybinding}]{' '}
{intl.formatMessage({ id: 'common.button.submit' })}
</span>
}
>
<Button
style={{ width: 46 }}
type="primary"
onClick={handleSendMessage}
size="middle"
disabled={isDisabled}
>
<SendOutlined rotate={0} className="font-size-14" />
</Button>
</Tooltip>
) : (
<Button
style={{ width: 44 }}
style={{ width: 46 }}
type="primary"
onClick={onStop}
size="middle"
icon={<IconFont type="icon-stop1"></IconFont>}
icon={
<IconFont type="icon-stop1" className="font-size-14"></IconFont>
}
></Button>
)}
</div>
@ -396,16 +443,25 @@ const MessageInput: React.FC<MessageInputProps> = ({
dataList={message.imgs || []}
onDelete={handleDeleteImg}
></ThumbImg>
<TextArea
placeholder="Type your message here"
autoSize={{ minRows: 3, maxRows: 3 }}
onChange={(e) => handleInputChange(e.target.value)}
value={message.content}
size="large"
variant="borderless"
onKeyDown={handleKeyDown}
onPaste={handleOnPaste}
></TextArea>
<div className="input-box">
<TextArea
ref={inputRef}
autoSize={{ minRows: 3, maxRows: 3 }}
onChange={(e) => handleInputChange(e.target.value)}
value={message.content}
size="large"
variant="borderless"
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
onKeyDown={handleKeyDown}
onPaste={handleOnPaste}
></TextArea>
{!message.content && !focused && (
<span className="holder">
Type <kbd>/</kbd> to input message
</span>
)}
</div>
<PromptModal
open={open}
onCancel={() => setOpen(false)}

@ -1,11 +1,10 @@
import CopyButton from '@/components/copy-button';
import IconFont from '@/components/icon-font';
import { CloseOutlined, SwapOutlined, UserOutlined } from '@ant-design/icons';
import { MinusCircleOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Input, Tooltip } from 'antd';
import classNames from 'classnames';
import _ from 'lodash';
import React, { useCallback, useRef, useState } from 'react';
import React, { useCallback, useRef } from 'react';
import { Roles } from '../../config';
import { MessageItem } from '../../config/types';
import '../../style/content-item.less';
@ -30,9 +29,6 @@ const ContentItem: React.FC<MessageItemProps> = ({
const intl = useIntl();
const inputRef = useRef<any>(null);
const imgCountRef = useRef(0);
const [imgList, setImgList] = useState<
{ uid: number | string; dataUrl: string }[]
>([]);
const handleMessageChange = (e: any) => {
updateMessage?.({
@ -91,9 +87,7 @@ const ContentItem: React.FC<MessageItemProps> = ({
dataUrl: img
};
});
// setImgList((pre) => {
// return [...pre, ...list];
// });
updateMessage?.({
role: data.role,
content: data.content,
@ -124,9 +118,6 @@ const ContentItem: React.FC<MessageItemProps> = ({
const handleUpdateImgList = useCallback(
(list: { uid: number | string; dataUrl: string }[]) => {
// setImgList((preList) => {
// return [...preList, ...list];
// });
console.log('list===========', data.imgs, list);
updateMessage?.({
role: data.role,
@ -140,7 +131,6 @@ const ContentItem: React.FC<MessageItemProps> = ({
const handleDeleteImg = (uid: number | string) => {
const list = _.filter(data.imgs, (item: MessageItem) => item.uid !== uid);
// setImgList(list);
updateMessage?.({
role: data.role,
content: data.content,
@ -185,16 +175,8 @@ const ContentItem: React.FC<MessageItemProps> = ({
return (
<div className="content-item">
<div className="content-item-role">
<div className="role" onClick={handleToggleRole}>
<span className="m-r-5">
{Roles.User === data.role ? (
<UserOutlined></UserOutlined>
) : (
<IconFont type="icon-AIzhineng"></IconFont>
)}
</span>
<div className="role">
{intl.formatMessage({ id: `playground.${data.role}` })}
<SwapOutlined rotate={90} className="m-l-5" />
</div>
<div className="actions">
{editable && (
@ -215,7 +197,7 @@ const ContentItem: React.FC<MessageItemProps> = ({
size="small"
type="text"
onClick={onDelete}
icon={<CloseOutlined />}
icon={<MinusCircleOutlined />}
></Button>
</Tooltip>
)}

@ -242,6 +242,7 @@ const MultiCompare: React.FC<MultiCompareProps> = ({ modelList }) => {
</div>
<div>
<MessageInput
scope="compare"
loading={isLoading}
disabled={isLoading || modelSelections.length === 0}
handleSubmit={handleSubmit}

@ -104,7 +104,7 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
const submitMessage = async (currentParams: {
parameters: Record<string, any>;
currentMessage: { role: string; content: string };
currentMessage: Omit<MessageItem, 'uid'>;
}) => {
console.log('currentMessage==========3', currentParams);
const { parameters, currentMessage } = currentParams;
@ -278,17 +278,14 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
const handlePresetMessageList = (list: MessageItem[]) => {
currentMessageRef.current = {} as MessageItem;
const messages = _.map(
list,
(item: { role: string; content: string }) => {
setMessageId();
return {
role: item.role,
content: item.content,
uid: messageId.current
};
}
);
const messages = _.map(list, (item: Omit<MessageItem, 'uid'>) => {
setMessageId();
return {
role: item.role,
content: item.content,
uid: messageId.current
};
});
setTokenResult(null);
setMessageList(messages);
};

@ -1,15 +1,18 @@
import { CloseOutlined } from '@ant-design/icons';
import { Button, Divider, Input } from 'antd';
import { useIntl } from '@umijs/max';
import { Button, Divider, Input, Tooltip } from 'antd';
import React, { useState } from 'react';
import '../../style/sys-message.less';
interface SystemMessageProps {
style?: React.CSSProperties;
systemMessage: string;
setSystemMessage: (value: string) => void;
}
const SystemMessage: React.FC<SystemMessageProps> = (props) => {
const { systemMessage, setSystemMessage } = props;
const { systemMessage, setSystemMessage, style } = props;
const intl = useIntl();
const systemMessageRef = React.useRef<any>(null);
const [autoSize, setAutoSize] = useState<{
minRows: number;
@ -43,13 +46,16 @@ const SystemMessage: React.FC<SystemMessageProps> = (props) => {
};
return (
<div className="sys-message">
<div className="sys-message" style={{ ...style }}>
{
<div style={{ display: autoSize.focus ? 'block' : 'none' }}>
<span className="system-label">
{intl.formatMessage({ id: 'playground.systemMessage' })}
</span>
<Input.TextArea
ref={systemMessageRef}
variant="filled"
placeholder="Type system message here"
placeholder={intl.formatMessage({ id: 'playground.system.tips' })}
style={{
borderRadius: '0',
border: 'none'
@ -70,20 +76,25 @@ const SystemMessage: React.FC<SystemMessageProps> = (props) => {
{!autoSize.focus && (
<div className="sys-content-wrap" onClick={handleFocus}>
<div className="sys-content">
<span className="title">
{intl.formatMessage({ id: 'playground.systemMessage' })}
</span>
{systemMessage || (
<span style={{ color: 'var(--ant-color-text-tertiary)' }}>
Type system message here
{intl.formatMessage({ id: 'playground.system.tips' })}
</span>
)}
</div>
{systemMessage && (
<Button
className="clear-btn"
type="text"
icon={<CloseOutlined />}
size="small"
onClick={handleClearSystemMessage}
></Button>
<Tooltip title={intl.formatMessage({ id: 'common.button.clear' })}>
<Button
className="clear-btn"
type="text"
icon={<CloseOutlined />}
size="small"
onClick={handleClearSystemMessage}
></Button>
</Tooltip>
)}
</div>
)}

@ -1,4 +1,4 @@
import { CloseCircleOutlined } from '@ant-design/icons';
import { CloseCircleOutlined, EyeOutlined } from '@ant-design/icons';
import { Image } from 'antd';
import _ from 'lodash';
import React, { useCallback } from 'react';
@ -25,7 +25,14 @@ const ThumbImg: React.FC<{
return (
<span key={item.uid} className="thumb-img">
<span className="img">
<Image src={item.dataUrl} width={56} height={56} />
<Image
src={item.dataUrl}
width={56}
height={56}
preview={{
mask: <EyeOutlined />
}}
/>
</span>
<span className="del" onClick={() => handleOnDelete(item.uid)}>

@ -109,9 +109,7 @@ const Playground: React.FC = () => {
useHotkeys(
HotKeys.RIGHT.join(','),
() => {
setCollapse((pre) => {
return !pre;
});
groundLeftRef.current?.setCollapse?.();
},
{
preventDefault: true
@ -136,7 +134,8 @@ const Playground: React.FC = () => {
}}
extra={renderExtra()}
className={classNames('playground-container', {
compare: activeKey === 'compare'
compare: activeKey === 'compare',
chat: activeKey === 'chat'
})}
>
<div className="play-ground">

@ -15,10 +15,6 @@
cursor: pointer;
padding: 2px 4px;
border-radius: var(--border-radius-mini);
&:hover {
background-color: var(--ant-color-fill-secondary);
}
}
.actions {

@ -7,6 +7,7 @@
border-left: 1px solid var(--ant-color-split);
transition: width 0.3s ease;
height: calc(100vh - 72px);
padding-top: 16px;
overflow-y: auto;
.box {
@ -42,6 +43,7 @@
flex-direction: column;
padding-inline: var(--layout-content-inlinepadding);
overflow-y: auto;
padding-top: 16px;
.content {
flex: 1;

@ -68,4 +68,24 @@
justify-content: flex-end;
}
}
.input-box {
width: 100%;
display: flex;
position: relative;
.holder {
pointer-events: none;
position: absolute;
top: 0;
left: 6px;
color: var(--ant-color-text-quaternary);
kbd {
border: 1px solid var(--ant-color-border);
border-radius: 3px;
padding: 0 2px;
}
}
}
}

@ -78,6 +78,25 @@
padding-block: 0;
}
.ant-page-header {
position: relative;
height: 72px;
}
&.chat {
.ant-page-header {
&::after {
position: absolute;
content: '';
left: 32px;
right: 32px;
bottom: 0;
height: 1px;
background-color: var(--ant-color-split);
}
}
}
&.compare {
.ant-pro-page-container-children-container {
padding-inline: 0;

@ -24,12 +24,26 @@
top: 6px;
}
.system-label {
font-weight: var(--font-weight-bold);
padding-left: 16px;
}
.sys-content {
flex: 1;
height: 38px;
width: 300px;
line-height: 18px;
padding: 10px 14px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
color: var(--ant-color-text-secondary);
.title {
font-weight: var(--font-weight-bold);
padding-right: 10px;
color: var(--ant-color-text);
}
}
}

@ -11,10 +11,6 @@
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 {
@ -26,12 +22,22 @@
background-color: var(--color-white-1);
display: none;
border-radius: 50%;
height: 16px;
width: 16px;
overflow: hidden;
pointer-events: all;
}
&:hover {
.ant-image .ant-image-mask {
opacity: 1;
transition: opacity var(--ant-motion-duration-slow);
}
.del {
display: block;
display: flex;
justify-content: center;
align-items: center;
}
}
}

Loading…
Cancel
Save