import { setRouteCache } from '@/atoms/route-cache'; import AlertInfo from '@/components/alert-info'; import IconFont from '@/components/icon-font'; import routeCachekey from '@/config/route-cachekey'; import ThumbImg from '@/pages/playground/components/thumb-img'; import { generateRandomNumber } from '@/utils'; import { FileImageOutlined, SwapOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { Button, Tooltip } from 'antd'; import classNames from 'classnames'; import _ from 'lodash'; import 'overlayscrollbars/overlayscrollbars.css'; import React, { forwardRef, memo, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react'; import { CREAT_IMAGE_API } from '../apis'; import { useInitImageMeta } from '../hooks/use-init-meta'; import useTextImage from '../hooks/use-text-image'; import '../style/ground-left.less'; import '../style/system-message-wrap.less'; import { generateImageCode, generateOpenaiImageCode } from '../view-code/image'; import DynamicParams from './dynamic-params'; import MessageInput from './message-input'; import ViewCommonCode from './view-common-code'; interface MessageProps { modelList: Global.BaseOption[]; loaded?: boolean; ref?: any; } const GroundImages: React.FC = forwardRef((props, ref) => { const { modelList } = props; const intl = useIntl(); const [show, setShow] = useState(false); const [collapse, setCollapse] = useState(false); const scroller = useRef(null); const paramsRef = useRef(null); const inputRef = useRef(null); const { handleOnValuesChange, handleToggleParamsStyle, setParams, form, paramsConfig, initialValues, parameters, isOpenaiCompatible } = useInitImageMeta(props); const { loading, tokenResult, imageList, promptList, currentPrompt, setCurrentPrompt, handleClear, handleStopConversation, submitMessage } = useTextImage({ scroller, paramsRef, chunkFields: ['stream_options', 'chunk_results'], API: CREAT_IMAGE_API }); useImperativeHandle(ref, () => { return { viewCode() { setShow(true); }, setCollapse() { setCollapse(!collapse); }, collapse: collapse }; }); const generateNumber = (min: number, max: number) => { return Math.floor(Math.random() * (max - min + 1) + min); }; const handleRandomPrompt = useCallback(() => { const randomIndex = generateNumber(0, promptList.length - 1); const randomPrompt = promptList[randomIndex]; inputRef.current?.handleInputChange({ target: { value: randomPrompt } }); }, []); const finalParameters = useMemo(() => { if (parameters.size === 'custom') { return { ..._.omit(parameters, ['width', 'height', 'preview']), size: parameters.width && parameters.height ? `${parameters.width}x${parameters.height}` : '' }; } return { ..._.omit(parameters, ['width', 'height', 'random_seed', 'preview']) }; }, [parameters]); const viewCodeContent = useMemo(() => { if (isOpenaiCompatible) { return generateOpenaiImageCode({ api: CREAT_IMAGE_API, parameters: { ...finalParameters, prompt: currentPrompt } }); } return generateImageCode({ api: CREAT_IMAGE_API, parameters: { ...finalParameters, prompt: currentPrompt } }); }, [finalParameters, isOpenaiCompatible, currentPrompt]); const handleInputChange = (e: any) => { setCurrentPrompt(e.target.value); }; const generateParams = () => { // preview let stream_options: Record = { chunk_size: 16 * 1024, chunk_results: true }; if (parameters.preview === 'preview') { stream_options = { preview: true }; } if (parameters.preview === 'preview_faster') { stream_options = { preview_faster: true }; } const params = { ..._.omitBy( parameters, (value: string, key: string) => !value || ['width', 'height', 'seed'].includes(key) ), seed: parameters.random_seed ? generateRandomNumber() : parameters.seed, stream: true, stream_options: { ...stream_options }, prompt: currentPrompt }; return params; }; const handleSendMessage = async () => { try { await form.current?.form?.validateFields(); if (!parameters.model) return; const params = generateParams(); setParams({ ...params, seed: params.seed }); form.current?.form?.setFieldValue('seed', params.seed); console.log('params:', params, parameters); submitMessage(params); setRouteCache(routeCachekey['/playground/text-to-image'], true); } catch (error) { // console.log('error:', error); } finally { console.log('finally---------'); setRouteCache(routeCachekey['/playground/text-to-image'], false); } }; const handleCloseViewCode = () => { setShow(false); }; return (
<>
{!imageList.length && (
{intl.formatMessage({ id: 'playground.params.empty.tips' })}
)}
{tokenResult && (
)}
{intl.formatMessage({ id: 'playground.image.prompt' })} } loading={loading} disabled={!parameters.model} isEmpty={!imageList.length} handleSubmit={handleSendMessage} handleAbortFetch={handleStopConversation} onInputChange={handleInputChange} shouldResetMessage={false} clearAll={handleClear} tools={ <> } />
{intl.formatMessage({ id: 'playground.parameters' })}
} onValuesChange={handleOnValuesChange} paramsConfig={paramsConfig} initialValues={initialValues} modelList={modelList} />
); }); export default memo(GroundImages);