UNPKG

@chatui/core

Version:

The React library for Chatbot UI

142 lines (140 loc) 5.88 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.VoiceInputStatus = exports.VoiceInput = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _canUse = _interopRequireDefault(require("../../utils/canUse")); var _ClickOutside = require("../ClickOutside"); var _ConfigProvider = require("../ConfigProvider"); var _Icon = require("../Icon"); var _SoundWave = require("./SoundWave"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } var canPassive = (0, _canUse.default)('passiveListener'); var listenerOpts = canPassive ? { passive: true } : false; var listenerOptsWithoutPassive = canPassive ? { passive: false } : false; var MOVE_INTERVAL = 80; var ts = 0; var startY = 0; /** 语音输入状态枚举 */ var VoiceInputStatus = exports.VoiceInputStatus = { INITED: 'inited', RECORDING: 'recording', WILL_CANCEL: 'willCancel' }; /** 状态文案映射 */ var statusTextMap = (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, VoiceInputStatus.INITED, 'hold2talk'), VoiceInputStatus.RECORDING, 'releaseOrSwipe'), VoiceInputStatus.WILL_CANCEL, 'release2send'); var VoiceInput = exports.VoiceInput = /*#__PURE__*/_react.default.forwardRef(function (props, ref) { var onStart = props.onStart, onEnd = props.onEnd, onCancel = props.onCancel, onClose = props.onClose, onStatusChange = props.onStatusChange; var _useState = (0, _react.useState)(VoiceInputStatus.INITED), _useState2 = (0, _slicedToArray2.default)(_useState, 2), status = _useState2[0], setStatus = _useState2[1]; var btnRef = (0, _react.useRef)(null); var _useLocale = (0, _ConfigProvider.useLocale)('VoiceInput'), trans = _useLocale.trans; var updateStatus = (0, _react.useCallback)(function (newStatus) { setStatus(newStatus); if (onStatusChange) { onStatusChange(newStatus); } }, [onStatusChange]); var doEnd = (0, _react.useCallback)(function () { var duration = Date.now() - ts; if (onEnd) { onEnd({ duration: duration }); } }, [onEnd]); var handleClose = (0, _react.useCallback)(function () { updateStatus(VoiceInputStatus.INITED); if (onClose) { onClose(); } }, [onClose, updateStatus]); (0, _react.useImperativeHandle)(ref, function () { return { stop: function stop() { updateStatus(VoiceInputStatus.INITED); doEnd(); ts = 0; } }; }); (0, _react.useEffect)(function () { var btn = btnRef.current; if (!btn) return; function handleTouchStart(e) { if (e.cancelable) { e.preventDefault(); } var touch0 = e.touches[0]; startY = touch0.pageY; ts = Date.now(); updateStatus(VoiceInputStatus.RECORDING); if (onStart) { onStart(); } } function handleTouchMove(e) { if (!ts) return; var nowY = e.touches[0].pageY; var isCancel = startY - nowY > MOVE_INTERVAL; updateStatus(isCancel ? VoiceInputStatus.WILL_CANCEL : VoiceInputStatus.RECORDING); } function handleTouchEnd(e) { if (!ts) return; var endY = e.changedTouches[0].pageY; var isRecording = startY - endY < MOVE_INTERVAL; updateStatus(VoiceInputStatus.INITED); if (isRecording) { doEnd(); } else if (onCancel) { onCancel(); } } btn.addEventListener('touchstart', handleTouchStart, listenerOptsWithoutPassive); btn.addEventListener('touchmove', handleTouchMove, listenerOpts); btn.addEventListener('touchend', handleTouchEnd); btn.addEventListener('touchcancel', handleTouchEnd); return function () { btn.removeEventListener('touchstart', handleTouchStart); btn.removeEventListener('touchmove', handleTouchMove); btn.removeEventListener('touchend', handleTouchEnd); btn.removeEventListener('touchcancel', handleTouchEnd); }; }, [doEnd, onCancel, onStart, updateStatus]); var isRecording = status === VoiceInputStatus.RECORDING; var isCancel = status === VoiceInputStatus.WILL_CANCEL; return /*#__PURE__*/_react.default.createElement(_ClickOutside.ClickOutside, { onClick: handleClose }, /*#__PURE__*/_react.default.createElement("div", { className: "VoiceInput", "data-voice-status": status }, /*#__PURE__*/_react.default.createElement("div", { className: "VoiceInput-tip" }, trans(statusTextMap[status])), /*#__PURE__*/_react.default.createElement("div", { className: "VoiceInput-control" }, isRecording && /*#__PURE__*/_react.default.createElement(_SoundWave.SoundWave, null), /*#__PURE__*/_react.default.createElement("div", { className: "VoiceInput-btn", role: "button", "aria-label": trans(statusTextMap[status]), ref: btnRef }, /*#__PURE__*/_react.default.createElement(_Icon.Icon, { className: "VoiceInput-btnIcon", type: isCancel ? 'cancel' : 'mic' }))))); });