general-assistant
Version:
General Assistant components
615 lines (614 loc) • 41.1 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import classNames from 'classnames';
import { Button, Divider, Flex, Input, Progress } from 'datastellar-chatui';
import { debounce, defaultsDeep, each, extend, find, set } from 'lodash';
import Upload from 'rc-upload';
import { forwardRef, useEffect, useRef, useState, useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { useStore } from 'zustand';
import StoreContext from '../_store/StoreContext';
import { blobToFile, getFileGeneralSize, getFileName, getFileTypeIcon, getMedia, RandomString, sendRequestWithConfig, } from '../_utils/tools';
import { placeholder as en_placeholder } from '../i18n/en-us.json';
import { placeholder as zh_placeholder } from '../i18n/zh-cn.json';
import StreamWave from '../StreamWave';
import Tooltip from '../Tooltips';
import { IoIosWarning } from "react-icons/io";
import ComposerRightAddition from './component/RightAddition';
import ComposerLeftAddition from './component/LeftAddition';
import ComposerToast from './component/ToastInfo';
import ComposerCitationContent from './component/CitationContent';
import ComposerCautionContent from './component/CautionContent';
const defaultVoiceProps = { minduration: 150, maxduration: 30000, warnduration: 3000 };
let isWaitToText = false;
let controller = null;
let assistantMediaRecorder = null;
let chunks = [];
let assistantTimer = null;
let isObsolete = false;
let effectiveTime = 0;
const InputComposer = forwardRef(({ onSend, inputOptions }, inputRef) => {
const { t, i18n: i18nContext } = useTranslation();
const dataStore = useContext(StoreContext);
const { MyHandlers, getDeviceInfo, getRequestConfig, getConfig, GlobalCtxs, sourceList, setSourceList, stopBroadAudio, getCitation, setCitationInfo, selectedAite, setSelectedAite, confirmAite, setConfirmAite, getConfirmAite, isShowAite, getShowAite, setShowAite, } = useStore(dataStore, (state) => ({
MyHandlers: state.MyHandlers,
getDeviceInfo: state.getDeviceInfo,
getRequestConfig: state.getRequestConfig,
getConfig: state.getConfig,
GlobalCtxs: state.GlobalCtxs,
sourceList: state.sourceList,
setSourceList: state.updateList,
stopBroadAudio: state.stopBroadAudio,
getCitation: state.getCitation,
setCitationInfo: state.setCitationInfo,
selectedAite: state.selectedAite,
setSelectedAite: state.setSelectedAite,
confirmAite: state.confirmAite,
setConfirmAite: state.setConfirmAite,
getConfirmAite: state.getConfirmAite,
isShowAite: state.isShowAite,
getShowAite: state.getShowAite,
setShowAite: state.setShowAite,
}));
const { onFileChange, beforeSpeechToText, onselectionchange } = MyHandlers;
const { timeout, method, headers, speechToText } = getRequestConfig();
const { inputProps } = getConfig();
const { isShowInput, disabled, allowVoice, voiceProps, text: defVal, placeholder, allowUpload, uploadProps, completeAreaClass, inputAreaClass, inputClass, operateLeftCustomIcon, operateRightCustomIcon } = inputProps;
useEffect(() => {
if (inputRef && inputRef.current)
inputRef.current.rows = 1;
}, [isShowInput]);
useEffect(() => {
if (inputRef.current) {
const textarea = inputRef.current;
textarea.addEventListener('selectionchange', () => {
const start = textarea.selectionStart;
const end = textarea.selectionEnd;
typeof onselectionchange === 'function' ? onselectionchange({ value: inputRef.current.value, start, end }, GlobalCtxs) : '';
});
}
}, [inputRef]);
const [myPlaceholder, setMyPlaceholder] = useState(placeholder);
useEffect(() => {
if (placeholder === zh_placeholder || placeholder === en_placeholder) {
if (i18nContext.language === 'zh')
setMyPlaceholder(zh_placeholder);
if (i18nContext.language === 'en')
setMyPlaceholder(en_placeholder);
}
else {
setMyPlaceholder(placeholder);
}
}, [placeholder, i18nContext.language]);
const [myInputRows, setMyInputRows] = useState(1);
const [myCautionSearch, setMyCautionSearch] = useState('');
function substrAiteToCursor(_inputV) {
const _ref = inputRef.current;
const _selectEndIndex = _ref.selectionEnd;
const _preSelectStr = _inputV.substring(0, _selectEndIndex);
const _lastAiteIndex = _preSelectStr.lastIndexOf('@');
return _preSelectStr.substring(_lastAiteIndex);
}
function isAiteOrder(_inputV, _newV) {
if (_newV === '@')
return _newV;
if (_inputV.toString().indexOf('@') === -1)
return '';
return substrAiteToCursor(_inputV);
}
function onInputValueChange(_value, syntheticBaseEvent) {
if (_value === '') {
setMyInputRows(1);
setShowAite(false);
setSelectedAite(confirmAite);
if (inputRef && inputRef.current)
inputRef.current.rows = 1;
return;
}
if (syntheticBaseEvent) {
const { nativeEvent } = syntheticBaseEvent;
const { data: newStr } = nativeEvent;
const _substr = isAiteOrder(_value, newStr);
let _flag = (_substr.toString().startsWith('@'));
if (_flag) {
setSelectedAite(confirmAite);
setMyCautionSearch(_substr);
setShowAite(true);
}
else {
setShowAite(false);
}
}
const _findCode = _value.match(/[\u000A]/g);
const _textRows = _findCode ? _findCode.length + 1 : 1;
let _naxRows = _textRows;
if (inputRef && inputRef.current) {
const _refrows = inputRef.current.rows;
if (_refrows > _textRows)
_naxRows = _refrows;
}
setMyInputRows(_naxRows);
if (inputRef && inputRef.current && _naxRows < 4)
inputRef.current.rows = _naxRows;
}
const [isFullScreenInput, setIsFullScreenInput] = useState(false);
const { isMobile } = getDeviceInfo();
const [hasText, setHasText] = useState(!!defVal);
const { pattern } = inputOptions;
const [isDis, setIsDis] = useState(disabled || pattern === 'stop');
const [toastInfo, setToastInfo] = useState(null);
const MyOnFileChange = (ev, fileList) => typeof onFileChange === 'function' ? onFileChange(ev, fileList, GlobalCtxs) : () => '';
const getNewFileItem = (file) => {
const _file = extend({}, {
uid: RandomString(),
percent: 0,
response: '',
error: '',
type: 'url',
size: 0,
name: '',
}, file);
return _file;
};
const [uploadErrorMessage, setUploadErrorMessage] = useState('');
useEffect(() => {
if (sourceList.length === 0) {
const _thisInfo = getNewFileItem();
setSourceList([_thisInfo]);
}
else {
}
}, [sourceList]);
function onBeforeUpload(_file, _fl) {
console.log('?onBeforeUpload', _file, _fl);
let hasError = false;
const { multiple, maxNumber, maxByte } = uploadProps;
const _realyNum = sourceList.filter((e) => e.response).length;
const _restNum = Number(maxNumber - _realyNum);
if (_fl.length > _restNum) {
setUploadErrorMessage('numberOver');
return false;
}
each(_fl, (e) => {
if (e.size > maxByte)
hasError = true;
});
if (hasError) {
setUploadErrorMessage('bytesOver');
return false;
}
}
function onBatchStart(fileList) {
console.log('?onBatchStart', fileList);
const hasError = fileList.some(({ parsedFile }) => !parsedFile);
if (hasError)
return;
let _oldlist = [].concat(sourceList);
let findIndexStart = 0;
const _nlist = [];
each(fileList, ({ parsedFile }) => {
const { uid, name, type, size } = parsedFile;
const _oldItem = find(_oldlist, (_item, index) => {
if (!_item.response) {
findIndexStart = index + 1;
return true;
}
}, findIndexStart);
const _newItem = { uid, name, type, size, percent: 0, error: '', response: '' };
if (_oldItem)
extend(_oldItem, _newItem);
else
_nlist.push(_newItem);
});
setSourceList(_oldlist.concat(_nlist));
}
function onProgress(event, file) {
const { uid } = file;
const { percent } = event;
file.percent = percent;
console.log('文件上传进度:', percent, file);
set(find(sourceList, (_item) => _item.uid === uid), 'percent', percent);
setSourceList(sourceList.concat([]));
}
function onSuccess(response, file) {
const { uid, name, type } = file;
const fileItem = find(sourceList, (_item) => _item.uid === uid);
extend(fileItem, {}, { percent: 100, error: '', response });
console.log('修改之后的fileItem: ', fileItem);
setSourceList(sourceList.concat([]));
MyOnFileChange('success', sourceList);
}
function onError(err, ret, file) {
console.log('文件上传出现错误:', err, ret, file);
const { message } = err;
const { uid, name, type, size } = file;
const _thisInfo = { uid, name, type, size, percent: 0, error: err, response: name };
const _nlist = sourceList.map((_item) => (_item.uid === uid ? _thisInfo : _item));
setSourceList(_nlist);
MyOnFileChange('error', _nlist);
}
function getErrorTip(err) {
if (err.includes('500'))
return '上传失败, 网络连接不稳定或已断开';
if (err.includes('404'))
return '上传失败, 请求地址错误';
return err;
}
const [myAllowUpload, setMyAllowUpload] = useState(allowUpload);
useEffect(() => {
setMyAllowUpload(allowUpload);
}, [allowUpload]);
const [myUploadProps, setMyUploadProps] = useState(defaultsDeep(uploadProps, { disabled: isDis }));
useEffect(() => {
setMyUploadProps(uploadProps);
}, [uploadProps]);
const MyBeforeSpeechToText = (options) => typeof beforeSpeechToText === 'function' ? beforeSpeechToText(options) : { next: true };
const [myAllowVoice, setMyAllowVoice] = useState(allowVoice);
useEffect(() => {
setMyAllowVoice(allowVoice);
}, [allowVoice]);
function lessVoiceProps() {
const { minduration, warnduration, maxduration } = defaultsDeep(voiceProps, defaultVoiceProps);
if (minduration < 0 || warnduration < 0 || maxduration < 0) {
return defaultVoiceProps;
}
if (maxduration <= minduration) {
return defaultVoiceProps;
}
if (warnduration >= maxduration) {
return defaultVoiceProps;
}
return { minduration, warnduration, maxduration };
}
const [myVoiceProps, setMyVoiceProps] = useState(lessVoiceProps());
useEffect(() => {
setMyVoiceProps(lessVoiceProps());
}, [voiceProps]);
const [isToText, setIsToText] = useState(false);
const [toTextErr, setToTextErr] = useState('');
const [myMediaStream, setMyMediaStream] = useState(null);
const [timeWarning, setTimeWarning] = useState('');
useEffect(() => {
if (myMediaStream === null && assistantMediaRecorder !== null) {
assistantMediaRecorder.stop();
assistantMediaRecorder = null;
}
if (myMediaStream !== null) {
const _pir = 100;
assistantTimer = setInterval(() => {
effectiveTime = effectiveTime + _pir;
console.log('语音输入计时', myVoiceProps.minduration, effectiveTime, myVoiceProps.maxduration);
const _diff = myVoiceProps.maxduration - effectiveTime;
if (_diff <= myVoiceProps.warnduration) {
setTimeWarning(t('timeWarning', { time: Math.ceil(_diff / 1000) }));
}
else {
setTimeWarning('');
}
if (_diff <= 0)
stopMediaTracks(), (isWaitToText = true);
}, _pir);
return () => clearInterval(assistantTimer);
}
}, [myMediaStream]);
async function dealVioceStart() {
stopBroadAudio();
const _media = (await getMedia());
console.log('getMedia response:', _media);
if (typeof _media === 'string') {
if (_media === 'Not support')
openToast(t('NotSupport'));
if (_media === 'Requested device not found')
openToast(t('mediaNotFound'));
if (_media === 'Permission denied')
openToast(t('mediaDenied'));
setMyMediaStream(null);
return;
}
if (isObsolete) {
stopMediaTracks();
isObsolete = false;
effectiveTime = 0;
setText('');
setIsDis(false);
return;
}
isObsolete = false;
effectiveTime = 0;
setIsDis(true);
setText(t('voiceInput'));
setMyMediaStream(_media);
if (assistantMediaRecorder === null) {
chunks = [];
assistantMediaRecorder = new MediaRecorder(_media);
assistantMediaRecorder.ondataavailable = event => {
chunks.push(event.data);
};
assistantMediaRecorder.onstop = event => {
if (isWaitToText)
dealAllSpeechToText();
};
assistantMediaRecorder.start();
}
}
function dealBeforeSpeechToText(_preSpeechToText) {
const _nextOrSuc = MyBeforeSpeechToText(_preSpeechToText);
if (!_nextOrSuc.next) {
if (_nextOrSuc.succeed) {
setIsToText(false);
setToTextErr('');
setText('');
setIsDis(false);
effectiveTime = 0;
assistantMediaRecorder = null;
chunks = [];
}
else {
setText(t('voiceToTextFail'));
setToTextErr('1');
}
}
return _nextOrSuc.next;
}
async function defaultSpeechToText(_preSpeechToText) {
const _reqConfig = speechToText(_preSpeechToText);
const { mimeType, body: _cusFdOrObj } = _reqConfig;
let _formData = null;
if (mimeType === false) {
_formData = _cusFdOrObj;
}
else {
const _formFile = await blobToFile(_reqConfig.mimeType, chunks);
if (_formFile instanceof FormData) {
if (Object.keys(_cusFdOrObj).length > 0) {
for (const key in _cusFdOrObj) {
_formFile.append(key, _cusFdOrObj[key]);
}
}
_formData = _formFile;
}
else {
openToast(_formFile.toString());
}
}
controller = new AbortController();
sendRequestWithConfig({
commonOpt: { timeout, method, headers },
parameter: Object.assign({}, _reqConfig, { body: _formData }),
isFecth: true,
controller,
onResponse(response) {
const { status, message, data } = response;
if (effectiveTime !== 0) {
if (status === 200) {
setText(data?.text);
setToTextErr('');
setIsDis(false);
effectiveTime = 0;
if (inputRef.current)
inputRef.current.rows = 4;
}
else {
setText(t('voiceToTextFail'));
setToTextErr(message);
openToast(message);
}
}
},
onCatch(err) {
if (effectiveTime !== 0) {
setText(t('voiceToTextFail'));
setToTextErr(err);
openToast(err);
}
},
onFinally() {
setIsToText(false);
},
});
}
async function dealAllSpeechToText() {
console.log('看看本次预备发送的chunks:', chunks);
const _preSpeechToText = { data: { voice: chunks }, ctx: GlobalCtxs };
const _next = dealBeforeSpeechToText(_preSpeechToText);
if (!_next)
return;
if (typeof speechToText !== 'function') {
openToast(t('missVoiceToText'));
setIsDis(false);
setText('');
isObsolete = false;
effectiveTime = 0;
return;
}
setText(t('voiceToText'));
isObsolete = false;
setIsDis(true);
setIsToText(true);
setToTextErr('');
await defaultSpeechToText(_preSpeechToText);
}
function stopMediaTracks() {
if (myMediaStream !== null) {
if (myMediaStream !== 1) {
myMediaStream.getTracks().forEach(function (track) {
track.stop();
setMyMediaStream(null);
});
}
clearInterval(assistantTimer);
assistantTimer = null;
}
}
async function dealVioceEnd() {
if (effectiveTime === 0 && (myMediaStream === null || myMediaStream === 1))
isObsolete = true;
if (effectiveTime < myVoiceProps.minduration) {
if (myMediaStream !== 1)
stopMediaTracks();
setIsDis(false);
effectiveTime = 0;
setText('');
assistantMediaRecorder = null;
chunks = [];
isWaitToText = false;
openToast(t('voiceTooShort'));
return;
}
stopMediaTracks();
isWaitToText = true;
}
function stopToText() {
setIsToText(false);
setMyMediaStream(null);
effectiveTime = 0;
setText('');
setToTextErr('');
if (controller && controller.abort) {
controller.abort();
controller = null;
}
}
function openToast(text, type = 'info') {
if (text)
setToastInfo({ text, type });
setTimeout(() => {
setToastInfo(null);
}, 2000);
}
function handleSend() {
const _val = inputRef.current?.value;
if (_val) {
onSend('text', _val);
}
}
function handleBreak() {
onSend('stop', '');
}
const handleKeyDown = (event) => {
if (!getShowAite() && !event.shiftKey && event.key === 'Enter') {
event.preventDefault();
handleSend();
}
};
function setText(_nv) {
if (inputRef && inputRef.current) {
inputRef.current.value = _nv;
setHasText(_nv !== '');
if (_nv !== '') {
onInputValueChange(_nv);
}
else {
inputRef.current.rows = 1;
setShowAite(false);
setSelectedAite(confirmAite);
}
}
}
function setCitation(option) {
if (!option)
return;
if (typeof option._id !== 'string')
return;
setCitationInfo(option);
}
function replaceStr() {
const _ref = inputRef.current;
const _oldV = _ref.value;
const _selectEndIndexInAll = _ref.selectionEnd;
const _preSelectStr = _oldV.substring(0, _selectEndIndexInAll);
const _findAiteIndexInPre = _preSelectStr.lastIndexOf('@');
const _preRV = _oldV.substring(0, _findAiteIndexInPre);
const _fixRV = _oldV.substring(_selectEndIndexInAll);
inputRef.current.value = _preRV + _fixRV;
inputRef.current.focus();
}
useEffect(() => {
if (inputRef && inputRef.current) {
inputRef.current.ele = {
getText: () => inputRef.current.value,
setText: (_nv) => { setText(_nv); return inputRef.current.ele; },
handleSend: () => { handleSend(); return inputRef.current.ele; },
setCitation: (option) => { setCitation(option); return inputRef.current.ele; },
focus: () => { inputRef.current.focus(); return inputRef.current.ele; },
blur: () => { inputRef.current.blur(); return inputRef.current.ele; },
getCitation,
getConfirmAite,
getShowAite,
setShowAite: (boo) => { setShowAite(boo); return inputRef.current.ele; },
showAiteList: (show, resetSearch) => {
resetSearch && setMyCautionSearch('');
setShowAite(show);
return inputRef.current.ele;
},
};
}
if (defVal)
setText(defVal), onInputValueChange(defVal);
}, []);
useEffect(() => {
setIsDis(disabled || pattern === 'stop' || myMediaStream || isToText || toTextErr !== '');
}, [pattern, disabled, isToText, toTextErr, myMediaStream]);
const fileUrlListRef = useRef(null);
return (_jsxs("div", { className: classNames('DS-GA-relative DS-GA-w-full DS-GA-flex', completeAreaClass, isShowInput ? '' : 'DS-GA-hidden'), children: [_jsx(Flex, { className: 'DS-GA-w-full DS-GA-absolute -DS-GA-mt-12', justify: 'center', children: pattern === 'stop' && _jsx(Button, { label: "\u505C\u6B62\u751F\u6210", size: 'lg', onClick: handleBreak }) }), _jsx(ComposerLeftAddition, {}), _jsxs("div", { className: classNames('DS-GA-grow DS-GA-relative !DS-GA-overflow-visible DS-GA-shadow-full-shal', inputAreaClass), children: [_jsx(ComposerRightAddition, {}), _jsxs("div", { id: 'rComposer', className: classNames('DS-GA-w-full DS-GA-relative Composer DS-GA-flex-col DS-GA-bg-area-mode DS-GA-rounded-lg DS-GA-border-0', inputClass), onKeyDown: handleKeyDown, children: [_jsx(ComposerToast, { data: toastInfo }), myAllowUpload && sourceList.length > 0 && (_jsx("div", { className: 'DS-GA-w-full DS-GA-flex DS-GA-flex-wrap DS-GA-flex-shrink-0 DS-GA-gap-1', children: sourceList.map((item) => {
const { uid, name, type, percent, error } = item;
const { suf, color, icon } = getFileTypeIcon(type, name);
return (name !== '' && (_jsx(Tooltip, { title: name, children: _jsxs("div", { className: classNames('DS-GA-relative DS-GA-group DS-GA-w-20 DS-GA-h-20 DS-GA-rounded-md DS-GA-rounded-b-none DS-GA-overflow-hidden', 'DS-GA-flex DS-GA-flex-col DS-GA-justify-between DS-GA-items-center', 'hover:DS-GA-bg-theme-shal-2'), children: [_jsx("div", { className: 'DS-GA-max-w-[80%] DS-GA-w-fit DS-GA-text-base DS-GA-leading-[70px] DS-GA-text-text-deep-7 o-text', children: getFileName(name) }), suf && (_jsx("span", { className: classNames('DS-GA-text-xs DS-GA-tracking-tighter DS-GA-font-medium DS-GA-opacity-60', `${color}`), children: suf })), _jsx("i", { className: classNames('DS-GA-absolute DS-GA-top-0 DS-GA-left-[-3px] DS-GA-text-[86px] DS-GA-w-full DS-GA-h-full iconfont-assistant DS-GA-opacity-40', `icon-${icon} ${color}`) }), _jsx("i", { className: classNames('DS-GA-invisible group-hover:DS-GA-visible', 'iconfont-assistant icon-del DS-GA-text-xxs', 'DS-GA-absolute DS-GA--top-4 DS-GA--right-4 DS-GA-w-8 DS-GA-h-8 DS-GA-p-0 DS-GA-pl-[6px] DS-GA-leading-[45px] DS-GA-rounded-full', 'DS-GA-bg-theme-deep-3 DS-GA-text-zinc-400 hover:DS-GA-text-zinc-500 DS-GA-cursor-pointer'), onClick: () => {
const _nlist = sourceList.filter((_item) => _item.uid !== uid);
setSourceList(_nlist);
MyOnFileChange('delete', _nlist);
} })] }, uid) }, uid)));
}) })), _jsxs("div", { className: 'DS-GA-w-full DS-GA-flex DS-GA-my-2', children: [_jsx(Input, { disabled: isDis, ref: inputRef, size: 20, autoSize: true, maxRows: 4, placeholder: myPlaceholder || t('sendToAssistant'), onChange: debounce((v, ev) => (setHasText(v !== ''), onInputValueChange(v, ev)), 200), className: classNames('DS-GA-grow DS-GA-border-0 DS-GA-no-scrollbar DS-GA-bg-area-mode DS-GA-text-text-deep-9', isDis ? 'DS-GA-cursor-not-allowed' : '', !isDis && isFullScreenInput ? 'DS-GA-z-50 DS-GA-fixed DS-GA-top-0 DS-GA-left-0 DS-GA-pt-8 DS-GA-w-screen DS-GA-h-screen' : '') }), hasText && !isDis && (_jsx("div", { className: 'DS-GA-self-center DS-GA-h-4 DS-GA-w-4 DS-GA-mr-[2px] DS-GA-flex DS-GA-text-text-reverse-9 DS-GA-bg-zinc-300 hover:DS-GA-bg-zinc-400 DS-GA-rounded-full DS-GA-cursor-pointer', onClick: () => setText(''), children: _jsx(Tooltip, { title: t('clearText'), children: _jsx("i", { className: 'iconfont-assistant icon-del DS-GA-text-xxs DS-GA-m-auto' }) }) })), myMediaStream && !isToText && toTextErr === '' && (_jsxs("div", { className: 'DS-GA-pointer-events-none DS-GA-absolute DS-GA-w-full DS-GA-h-full DS-GA-top-0 DS-GA-left-0 DS-GA-rounded-lg DS-GA-overflow-hidden', children: [timeWarning !== '' && (_jsx("div", { className: 'DS-GA-absolute DS-GA-top-1/2 DS-GA-left-0 DS-GA-w-full DS-GA-h-full DS-GA-text-xs DS-GA-text-red-400 DS-GA-text-center', children: timeWarning })), _jsx(StreamWave, { className: 'DS-GA-absolute DS-GA-top-1/2 DS-GA-left-0 DS-GA-w-full DS-GA-h-full DS-GA-text-theme-shal-8', color: 'DS-GA-text-theme-shal-8', stream: myMediaStream })] }))] }), _jsx(ComposerCitationContent, {}), _jsxs("div", { className: 'composer-icon DS-GA-w-full DS-GA-rounded-b-lg DS-GA-relative DS-GA-flex DS-GA-justify-between DS-GA-items-end DS-GA-align-middle', children: [_jsxs("div", { className: 'DS-GA-flex DS-GA-justify-center DS-GA-items-center DS-GA-gap-2 DS-GA-text-theme-shal-7', children: [_jsx("i", { onClick: () => (setIsFullScreenInput(!isFullScreenInput),
!isFullScreenInput && inputRef && inputRef.current && inputRef.current.focus()), className: classNames('md:DS-GA-hidden', myInputRows > 1 ? 'DS-GA-visible' : 'DS-GA-hidden', isFullScreenInput
? 'DS-GA-z-[51] DS-GA-w-screen DS-GA-h-6 DS-GA-pl-4 DS-GA-fixed DS-GA-top-0 DS-GA-left-0 DS-GA-bg-text-reverse-10'
: 'DS-GA-top-[10px] DS-GA-left-[6px]'), children: _jsx(Tooltip, { title: isFullScreenInput ? t('exitfull') : t('fullscreen'), place: 'top', children: _jsx("span", { className: classNames('DS-GA-block iconfont-assistant DS-GA-text-lg DS-GA-text-text-deep-8 hover:DS-GA-text-theme-shal-9', isFullScreenInput ? 'DS-GA-absolute icon-down' : 'icon-up') }) }) }), GlobalCtxs && Array.isArray(operateLeftCustomIcon) && operateLeftCustomIcon.length > 0
&& operateLeftCustomIcon.map((RenderIcon, _index) => _jsx(RenderIcon, { ctx: GlobalCtxs }, _index))] }), _jsxs("div", { className: 'DS-GA-flex DS-GA-justify-center DS-GA-items-center DS-GA-gap-2 DS-GA-text-theme-shal-7', children: [GlobalCtxs && Array.isArray(operateRightCustomIcon) && operateRightCustomIcon.length > 0
&& operateRightCustomIcon.map((RenderIcon, _index) => _jsx(RenderIcon, { ctx: GlobalCtxs }, _index)), myAllowUpload && (_jsx(Tooltip, { delayHide: 350, delayShow: 350, noArrow: true, className: classNames('DS-GA--ml-3 DS-GA-border-solid DS-GA-border-gray-300 DS-GA-border-[1px] !DS-GA-bg-text-reverse-10'), offset: 15, place: 'top-start', variant: 'light', openOnClick: true, title: _jsxs("div", { className: 'DS-GA-w-72 DS-GA-p-1 DS-GA-flex DS-GA-flex-col DS-GA-justify-center DS-GA-items-center', children: [_jsx("div", { ref: fileUrlListRef, className: 'DS-GA-w-full DS-GA-h-fit DS-GA-max-h-60 DS-GA-overflow-y-auto DS-GA-flex DS-GA-flex-col DS-GA-justify-items-center DS-GA-items-end gap-1', children: sourceList.map((_web, _ind) => {
const { uid: thisUid, response: thisResponse, name, percent, error } = _web;
const _numLimit = myUploadProps.multiple === true ? myUploadProps.maxNumber : 1;
const _realyNum = sourceList.filter((e) => e.name !== '').length;
const _restNum = Number(_numLimit - _realyNum);
const _allowAdd = _realyNum < _numLimit && sourceList.length < _numLimit;
const _hasErr = !!error;
return (_jsxs("div", { className: 'DS-GA-w-full DS-GA-flex DS-GA-flex-col', children: [_jsxs("div", { className: classNames('DS-GA-w-full DS-GA-p-1 DS-GA-flex DS-GA-items-center DS-GA-gap-1 DS-GA-rounded-xl', 'DS-GA-border DS-GA-border-theme-shal-3 hover:DS-GA-border-theme-shal-6 DS-GA-relative', _hasErr ? '!DS-GA-border-red-500 !hover:DS-GA-border-red-500' : ''), children: [_jsx(Progress, { value: percent, status: percent < 100 ? 'active' : 'success', className: classNames('DS-GA-opacity-25 DS-GA-absolute DS-GA-h-full DS-GA-left-0 DS-GA-right-0 DS-GA-top-0 DS-GA-bottom-0 DS-GA-rounded-[inherit] DS-GA-bg-transparent', !percent || percent >= 100 ? 'DS-GA-hidden' : '') }), _jsx(Input, { id: thisUid, placeholder: t('uploadPlaceholder'), className: 'DS-GA-p-0 DS-GA-pl-1 DS-GA-text-xs DS-GA-border-none', defaultValue: thisResponse?.data || thisResponse || name, onChange: debounce(_wv => {
const _thisInfo = { response: _wv, type: 'url', error: '' };
const _newlist = sourceList.map((_e) => (_e.uid === thisUid ? Object.assign({}, _e, _thisInfo) : _e));
setSourceList(_newlist);
MyOnFileChange('success', _newlist);
}, 500) }), thisResponse && thisResponse.toString().replace(/ /g, '') !== '' && (_jsx("i", { className: 'iconfont-assistant icon-del DS-GA-self-center DS-GA-w-4 DS-GA-h-4 DS-GA-px-1 DS-GA-py-0 DS-GA-text-xxs DS-GA-leading-4 DS-GA-text-text-reverse-9 DS-GA-bg-zinc-300 hover:DS-GA-bg-zinc-400 DS-GA-rounded-full', onClick: () => {
const _inpdom = document.getElementById(thisUid);
_inpdom.value = '';
const _thisInfo = { response: '', name: '', error: '' };
const _newlist = sourceList.map((_e) => (_e.uid === thisUid ? Object.assign({}, _e, _thisInfo) : _e));
setSourceList(_newlist);
MyOnFileChange('change', _newlist);
} })), (sourceList.length === 1 || sourceList.length === _ind + 1) && myUploadProps.multiple && (_jsx("span", { className: classNames('DS-GA-px-1 DS-GA-mr-1 iconfont-assistant icon-add DS-GA-text-xxs DS-GA-leading-4 DS-GA-rounded-full DS-GA-bg-theme-deep-8 DS-GA-text-text-reverse-9 hover:DS-GA-bg-theme-deep-9', _allowAdd ? '' : 'DS-GA-cursor-not-allowed'), onClick: () => {
if (!_allowAdd)
return;
let _newCache = sourceList.concat(getNewFileItem());
setSourceList(_newCache);
setTimeout(() => {
const lastElementChild = fileUrlListRef.current?.lastElementChild;
lastElementChild?.scrollIntoView({ behavior: 'smooth', block: 'end' });
lastElementChild.querySelector('input').focus();
}, 0);
} })), sourceList.length !== 1 && sourceList.length !== _ind + 1 && (_jsx("span", { className: 'DS-GA-px-1 DS-GA-mr-1 iconfont-assistant icon-minus DS-GA-text-xxs DS-GA-leading-4 DS-GA-rounded-full DS-GA-bg-red-500 DS-GA-text-text-reverse-9 hover:DS-GA-bg-red-600', onClick: () => {
const _nlist = sourceList.filter((_e) => _e.uid !== thisUid);
setSourceList(_nlist);
MyOnFileChange('delete', _nlist);
} }))] }), _hasErr && _jsx("span", { className: 'DS-GA-pl-1 DS-GA-self-start o-text DS-GA-text-xs DS-GA-text-red-500', children: getErrorTip(error.toString()) })] }, RandomString()));
}) }), _jsx(Divider, { className: 'DS-GA-w-full', children: "OR" }), _jsx(Upload, { className: classNames('DS-GA-grow-0 DS-GA-w-fit', sourceList.filter((e) => e.name !== '').length <
(myUploadProps.multiple === true ? myUploadProps.maxNumber : 1)
? ''
: 'DS-GA-cursor-not-allowed'), openFileDialogOnClick: sourceList.filter((e) => e.name !== '').length <
(myUploadProps.multiple === true ? myUploadProps.maxNumber : 1), beforeUpload: onBeforeUpload, onBatchStart: onBatchStart, onSuccess: onSuccess, onProgress: onProgress, onError: onError, ...myUploadProps, children: _jsx("span", { className: 'DS-GA-p-2 DS-GA-text-xs DS-GA-rounded-lg DS-GA-bg-theme-deep-8 DS-GA-text-text-reverse-9 hover:DS-GA-bg-theme-deep-9', children: t('upload') }) }), _jsxs("div", { className: 'DS-GA-self-start DS-GA-w-full DS-GA-mt-4 DS-GA-text-xs DS-GA-text-left DS-GA-flex DS-GA-flex-col DS-GA-gap-1', children: [_jsx("div", { className: 'DS-GA-w-full DS-GA-w-max-full DS-GA-flex DS-GA-justify-between', children: (() => {
const _numLimit = myUploadProps.multiple === true ? myUploadProps.maxNumber : 1;
const _realyNum = sourceList.filter((e) => e.name !== '').length;
return (_jsxs(_Fragment, { children: [_jsx("p", { className: 'DS-GA-grow o-text DS-GA-inline-flex', children: t('fileNumberLimit', { limit: _numLimit }).split(':').map((_t, _i) => _jsx("span", { className: classNames('DS-GA-py-1 DS-GA-px-2 DS-GA-rounded-md', _i === 0 ? 'DS-GA-w-fit DS-GA-bg-theme-shal-1' : ''), children: _t }, _i)) }), _jsxs("span", { className: classNames('DS-GA-w-fit DS-GA-flex', _realyNum > _numLimit ? 'DS-GA-text-amber-400' : 'DS-GA-text-theme-shal-9'), children: [uploadErrorMessage !== '' && _jsx(Tooltip, { isOpen: uploadErrorMessage !== '', afterShow: () => setTimeout(() => { setUploadErrorMessage(''); }, 5000), className: '!DS-GA-text-red-500', title: t(uploadErrorMessage), children: _jsx(IoIosWarning, { className: 'DS-GA-text-red-500 DS-GA-text-base', onMouseLeave: () => setUploadErrorMessage('') }) }), "(", _realyNum, "/", _numLimit, ")"] })] }));
})() }), _jsx("p", { className: 'DS-GA-w-full DS-GA-w-max-full DS-GA-flex', children: t('fileBytesLimit', { limit: getFileGeneralSize(myUploadProps.maxByte) }).split(':').map((_t, _i) => _jsx("span", { className: classNames('DS-GA-py-1 DS-GA-px-2 DS-GA-rounded-md', _i === 0 ? 'DS-GA-w-fit DS-GA-bg-theme-shal-1' : ''), children: _t }, _i)) }), _jsx("p", { className: 'DS-GA-w-full DS-GA-w-max-full DS-GA-flex', children: t('fileTypeLimit', { limit: myUploadProps.accept.toString().replace(/,/g, ' ') || t('unlimited') }).split(':').map((_t, _i) => _i === 0 ?
_jsx("span", { className: 'DS-GA-py-1 DS-GA-px-2 DS-GA-rounded-md DS-GA-w-fit DS-GA-h-fit DS-GA-min-w-16 DS-GA-bg-theme-shal-1', children: _t }, _i)
: _jsx(Tooltip, { className: '!DS-GA-whitespace-normal !DS-GA-max-w-full', title: _t, children: _jsx("span", { className: 'DS-GA-py-1 DS-GA-px-2 DS-GA-rounded-sm DS-GA-grow', children: _t }, _i) }, _i)) })] })] }), children: _jsx("i", { className: classNames('iconfont-assistant icon-upload DS-GA-text-text-deep-9 DS-GA-text-2xl DS-GA-cursor-pointer') }) })), !isMobile && myAllowVoice && !hasText && !isDis && (_jsx(Tooltip, { title: t('voiceStart'), children: _jsx("i", { className: 'iconfont-assistant DS-GA-text-xl icon-mic hover:DS-GA-text-theme-shal-10', onClick: dealVioceStart }) })), !isMobile && myAllowVoice && myMediaStream && isDis && !isToText && toTextErr === '' && (_jsx(Tooltip, { title: t('voiceStop'), children: _jsx("i", { className: classNames('iconfont-assistant icon-stop DS-GA-mb-1 DS-GA-p-1 DS-GA-text-xs DS-GA-w-5 DS-GA-h-5 !DS-GA-leading-3 DS-GA-rounded-xl DS-GA-text-white DS-GA-bg-neutral-800 hover:DS-GA-bg-black', isToText ? 'DS-GA-cursor-not-allowed' : ''), onClick: isToText ? null : dealVioceEnd }) })), myAllowVoice && toTextErr !== '' && (_jsx(Tooltip, { title: t('voiceReToText'), children: _jsx("i", { className: 'iconfont-assistant icon-fresh DS-GA-text-lg hover:DS-GA-text-theme-shal-10', onClick: dealAllSpeechToText }) })), myAllowVoice && (isToText || toTextErr !== '') && (_jsx(Tooltip, { title: t('voiceCancelToText'), children: _jsx("i", { className: 'iconfont-assistant icon-del DS-GA-text-sm DS-GA-text-zinc-400 hover:DS-GA-text-zinc-500', onClick: stopToText }) })), isMobile &&
myAllowVoice &&
pattern !== 'stop' &&
(!hasText || (isDis && myMediaStream && !isToText && toTextErr === '')) && (_jsx(Tooltip, { title: t('voiceLongStart'), children: _jsx("i", { className: 'iconfont-assistant DS-GA-text-xl icon-mic hover:DS-GA-text-theme-shal-10', onTouchStart: dealVioceStart, onTouchEnd: dealVioceEnd, onTouchMove: dealVioceEnd, onTouchCancel: dealVioceEnd }) })), hasText && !isDis && (_jsx(Tooltip, { title: t('sendText'), children: _jsx("i", { className: 'iconfont-assistant icon-send DS-GA-text-xl hover:DS-GA-text-theme-shal-10', onClick: handleSend }) })), pattern === 'stop' && (_jsx(Tooltip, { title: t('interrupt'), children: _jsx("i", { className: 'iconfont-assistant icon-stop DS-GA-text-2xl DS-GA-bg-neutral-800 DS-GA-text-white DS-GA-w-8 DS-GA-h-8 DS-GA-line-8 DS-GA-rounded-2xl DS-GA-text-center', onClick: handleBreak }) }))] })] })] })] }), _jsx(ComposerCautionContent, { search: myCautionSearch, inputRef: inputRef, cancel: () => (setSelectedAite(confirmAite), setShowAite(false)), confirm: (_opt) => (setShowAite(false), replaceStr()) })] }));
});
export default InputComposer;