UNPKG

ze-react-component-library

Version:
438 lines (395 loc) 13.7 kB
import "antd/es/button/style"; import _Button from "antd/es/button"; import "antd/es/input/style"; import _Input from "antd/es/input"; import "antd/es/auto-complete/style"; import _AutoComplete from "antd/es/auto-complete"; import "antd/es/message/style"; import _message from "antd/es/message"; var __spreadArray = this && this.__spreadArray || function (to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) { to[j] = from[i]; } return to; }; import React, { useRef, useEffect, useState } from "react"; import { useLocalStorageState } from "@umijs/hooks"; import { voice } from "zeroetp-api-sdk"; import ZEHistory from "../../ZEHistory"; import wx from "weixin-js-sdk"; import "./index.less"; // @ts-ignore import keyboardIcon from "./assets/keyboardIcon.png"; // @ts-ignore import voiceIcon from "./assets/voiceIcon.png"; import { isIOS, isLark, isWXWork, isWeixin } from "../util"; import { useSuggestions } from "../index"; import { requestSuggestByVoice } from "../../request"; import useLocale from "../../hooks/useLocale"; import AutoKeywords, { useInputCursor } from "../AutoKeywords"; import useRecorder from "../../hooks/useRecorder"; var InputBar = function InputBar(_a) { var srcPlaceholder = _a.placeholder, loading = _a.loading, onSubmit = _a.onSubmit, onTouchStart = _a.onTouchStart, onTouchEnd = _a.onTouchEnd, questionToEdit = _a.questionToEdit; var t = useLocale().t; var recorder = useRecorder(); var _b = useLocalStorageState("histories", []), history = _b[0], setHistory = _b[1]; var popRef = useRef(); var _c = useState(), value = _c[0], setValue = _c[1]; var _d = useState(false), isRecording = _d[0], setIsRecording = _d[1]; var _e = useState(0), posStart = _e[0], setPosStart = _e[1]; var recordingButton = useRef(null); var _f = useState("text"), mode = _f[0], setMode = _f[1]; // textByVoice指的是先voice后,变成修改模式。然后提交完后要再变为voice模式 var _g = useSuggestions(), suggestions = _g.suggestions, setSuggestions = _g.setSuggestions, getSuggestions = _g.getSuggestions; var _h = useState(false), open = _h[0], setOpen = _h[1]; var _j = useInputCursor({ text: value }), cursorText = _j.cursorText, onCursorChange = _j.onCursorChange, getNewWord = _j.getNewWord, inputRef = _j.inputRef; var saveValueToHistory = function saveValueToHistory() { if (value) { // 存储最新10条 var arr = __spreadArray([], history).filter(function (h) { return h !== value; }); if (history.length >= 10) { arr.shift(); } setHistory(__spreadArray(__spreadArray([], arr), [value])); } }; useEffect(function () { window.oncontextmenu = function (e) { //取消默认的浏览器自带右键 很重要!! // TODO:测试下会不会复制文字不行了 e.preventDefault(); }; if (recordingButton === null || recordingButton === void 0 ? void 0 : recordingButton.current) { (recordingButton === null || recordingButton === void 0 ? void 0 : recordingButton.current).addEventListener("contextmenu", function (e) { e.preventDefault(); }); } setTimeout(function () { tryRecord(); // 先试一下,主要用于第一次的时候出现一个提示 }, 500); }, []); useEffect(function () { if ((value === null || value === void 0 ? void 0 : value.trim().length) > 0 && mode === "voice") { submit(); } }, [value, mode]); useEffect(function () { if (questionToEdit) { setMode("text"); setValue(questionToEdit); } }, [questionToEdit]); var setVoiceText = function setVoiceText(s) { var newS = s; if (newS) { newS = newS.replace(/(病痛啥|并通商)/g, "丙通沙"); newS = newS.replace(/(夏凡宁|夏凡尼)/g, "夏帆宁"); newS = newS.replace(/(或是为|卧室伟)/g, "沃士韦"); newS = newS.replace(/(威力的|韦立德)/g, "韦立得"); newS = newS.replace(/(捷夫康)/g, "捷扶康"); newS = newS.replace(/(B所为|B拖尾)/g, "必妥维"); newS = newS.replace(/(大可灰|大可会)/g, "达可挥"); newS = newS.replace(/(抒发太)/g, "舒发泰"); } setValue(newS); }; var tryRecord = function tryRecord() { try { if (isWeixin()) { wx.startRecord({ success: function success() { setTimeout(function () { wx.stopRecord(); }, 500); }, cancel: function cancel() { _message.info("用户拒绝授权"); }, fail: function fail(res) {// message.info(JSON.stringify(res)); } }); } else if (isLark()) {// do nothing } else { recorder.start(); setTimeout(function () { recorder.stop(); }, 500); } } catch (error) { _message.error("无法打开录音设备,请确保浏览器权限设置正确"); } }; var startRecording = function startRecording() { if (isRecording) return; setIsRecording(true); try { onTouchStart === null || onTouchStart === void 0 ? void 0 : onTouchStart(); if (isWeixin()) { // 微信环境 wx.startRecord(); } else if (isLark()) { var recorderManager = window.tt.getRecorderManager(); recorderManager.onStop(function (res) { // message.info("录音结束"); var tempFilePath = res.tempFilePath; var fileSystemManager = window.tt.getFileSystemManager(); fileSystemManager.readFile({ filePath: tempFilePath, success: function success(fileRes) { // message.info("文件上传中"); try { var formData = new FormData(); formData.append("voice", new Blob([new Uint8Array(fileRes.data).buffer], { type: isIOS() ? "audio/aac" : "audio/wav" })); formData.append("ua", navigator.userAgent); voice(formData).then(function (voiceRes) { if (voiceRes.result.length > 0) { setVoiceText(voiceRes.result); } }).catch(function (error) { return _message.error(error.message); }); } catch (eee) { _message.error(eee.message); } }, fail: function fail(failRes) { _message.error("\u5F55\u97F3\u6587\u4EF6\u8BFB\u53D6\u9519\u8BEF\uFF1A" + JSON.stringify(failRes)); } }); }); recorderManager.onStart(function () {// message.info("录音开始"); }); recorderManager.onError(function (errMsg) { _message.error(errMsg); }); recorderManager.start({ duration: 10000, sampleRate: 16000, numberOfChannels: 1 }); } else { recorder.start(); } } catch (error) { _message.error("无法打开录音设备,请确保浏览器权限设置正确"); setIsRecording(false); } }; var stopRecording = function stopRecording(endY) { if (!isRecording) return; setIsRecording(false); onTouchEnd === null || onTouchEnd === void 0 ? void 0 : onTouchEnd(); // @ts-ignore if (isWeixin()) { wx.stopRecord({ success: function success(res) { var localId = res.localId; if (localId) { if (isWXWork()) { wx.uploadVoice({ localId: localId, isShowProgressTips: 0, success: function success(res2) { var serverId = res2.serverId; var formData = new FormData(); formData.append("platform", "wxwork"); formData.append("media_id", serverId); requestSuggestByVoice(formData).then(function (res) { setVoiceText(res.result); // console.log("l666", res.result); // message.info(res.result); }).catch(function (e) {// message.error(e.message); }); }, fail: function fail(res2) {// message.error(JSON.stringify(res2)); } }); } else { wx.translateVoice({ localId: localId, isShowProgressTips: 1, success: function success(res2) { setVoiceText(res2.translateResult); }, fail: function fail(r) { _message.error(JSON.stringify(r)); } }); } } else { _message.error("未获取到录音文件,可能是录音权限被关闭"); } }, fail: function fail(res) {// message.info(JSON.stringify(res)); } }); } else if (isLark()) { var recorderManager = window.tt.getRecorderManager(); recorderManager.stop(); } else { recorder.stop(function (blob) { var formData = new FormData(); formData.append("voice", blob); voice(formData).then(function (res) { if (res.result.length > 0) { setVoiceText(res.result); } }).catch(function (error) { return _message.error(error.message); }); }); } }; var onInputChange = function onInputChange(v) { setSuggestions([]); v.trim().length > 0 && getSuggestions(v.trim()); setValue(v); }; var submit = function submit() { saveValueToHistory(); if (value && value.trim().length > 0) { onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(value.trim()); } }; var renderDropdownContent = function renderDropdownContent(menu) { if (suggestions.length > 0 || cursorText) { return /*#__PURE__*/React.createElement(React.Fragment, null, suggestions.length > 0 && /*#__PURE__*/React.createElement("div", { style: { marginBottom: 12 } }, /*#__PURE__*/React.createElement("p", { className: "ze-search-bar-history-pop-content-title" }, t("nlq.hot")), menu), cursorText && /*#__PURE__*/React.createElement(AutoKeywords, { question: cursorText, onClick: function onClick(w) { onInputChange(getNewWord(w)); } })); } return /*#__PURE__*/React.createElement(ZEHistory, { onClick: function onClick(q) { setOpen(false); setValue(q); onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(q); } }); }; var placeholder = t("nlq.searchbar.placeholder"); if (srcPlaceholder) { placeholder = srcPlaceholder; } return /*#__PURE__*/React.createElement("div", { className: "inputBarContainer", ref: popRef }, /*#__PURE__*/React.createElement("img", { className: "icon", src: mode === "voice" ? keyboardIcon : voiceIcon, onClick: function onClick() { if (mode.startsWith("text")) { setVoiceText(undefined); setMode("voice"); localStorage.setItem("inputMode", "voice"); } else { setMode("text"); localStorage.setItem("inputMode", "text"); } } }), /*#__PURE__*/React.createElement("div", { className: "input" }, mode === "text" && /*#__PURE__*/React.createElement(_AutoComplete, { open: open, dropdownRender: renderDropdownContent, backfill: true, allowClear: true, options: suggestions.length > 0 ? suggestions.map(function (s) { return { label: s, value: s }; }) : // placeholder,用来触发popup展示,因为默认options为空时不会触发popup [{ label: "@@@@", value: "@@@@" }], getPopupContainer: function getPopupContainer() { return popRef.current; }, dropdownMatchSelectWidth: false, value: value, popupClassName: "ze-search-bar-history-pop-content", onChange: function onChange(v, option) { // option选中时 if (!Array.isArray(option) && (option === null || option === void 0 ? void 0 : option.value)) { setSuggestions([]); setValue(v); } }, onSearch: onInputChange, onDropdownVisibleChange: setOpen }, /*#__PURE__*/React.createElement(_Input.Search, { ref: inputRef, style: { height: "100%" }, placeholder: placeholder, onSearch: function onSearch() { return submit(); }, onKeyUp: onCursorChange, onMouseUp: onCursorChange })), mode === "voice" && /*#__PURE__*/React.createElement("div", { ref: recordingButton, className: "recordingButton", onTouchStart: function onTouchStart(e) { setPosStart(e.targetTouches[0].pageY); startRecording(); }, onTouchEnd: function onTouchEnd(e) { // setPosEnd(e.changedTouches[0].pageY); stopRecording(e.changedTouches[0].pageY); }, // onTouchMove={(e) => { // 用来改UI上面的文案的,暂时不调了 // }} onMouseDown: function onMouseDown() { startRecording(); }, onMouseUp: function onMouseUp() { stopRecording(); } }, /*#__PURE__*/React.createElement("div", { className: "text" }, isRecording ? "松开 结束" : "按住 说话"))), /*#__PURE__*/React.createElement(_Button, { loading: loading, type: "primary", className: "sendButton", onClick: function onClick() { submit(); } }, "\u53D1\u9001")); }; export default InputBar;