UNPKG

gui-one-nutui-react-taro

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

229 lines (228 loc) 9.56 kB
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _excluded = ["className", "url", "style", "autoplay", "loop", "type", "onFastBack", "onForward", "onPause", "onPlay", "onPlayEnd", "onCanPlay", "children", "iconClassPrefix", "iconFontClassName"]; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } import React__default, { useState, useRef } from 'react'; import Taro from '@tarojs/taro'; import { I as Icon } from './icon.taro-1d0d4fb7.js'; import { R as Range } from './range.taro-4232e6a7.js'; import { B as Button } from './button.taro-4ce133b9.js'; import { c as cn } from './bem-893ad28d.js'; import { u as useConfig } from './configprovider.taro-6c7b3056.js'; import { C as ComponentDefaults } from './typings-1c5f2628.js'; var b = cn('audio'); var warn = console.warn; var defaultProps = _objectSpread(_objectSpread({}, ComponentDefaults), {}, { className: '', url: '', style: {}, autoplay: false, loop: false, type: 'progress', onFastBack: function onFastBack(ctx) {}, onForward: function onForward(ctx) {}, onPause: function onPause(ctx) {}, onPlay: function onPlay(ctx) {}, onPlayEnd: function onPlayEnd(ctx) {}, onCanPlay: function onCanPlay(ctx) {} }); var Audio = function Audio(props) { var _useConfig = useConfig(), locale = _useConfig.locale; var _defaultProps$props = _objectSpread(_objectSpread({}, defaultProps), props), className = _defaultProps$props.className, url = _defaultProps$props.url, style = _defaultProps$props.style, autoplay = _defaultProps$props.autoplay, loop = _defaultProps$props.loop, type = _defaultProps$props.type, onFastBack = _defaultProps$props.onFastBack, onForward = _defaultProps$props.onForward, onPause = _defaultProps$props.onPause, onPlay = _defaultProps$props.onPlay, onPlayEnd = _defaultProps$props.onPlayEnd, onCanPlay = _defaultProps$props.onCanPlay, children = _defaultProps$props.children, iconClassPrefix = _defaultProps$props.iconClassPrefix, iconFontClassName = _defaultProps$props.iconFontClassName, rest = _objectWithoutProperties(_defaultProps$props, _excluded); var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), playing = _useState2[0], setPlaying = _useState2[1]; var _useState3 = useState(0), _useState4 = _slicedToArray(_useState3, 2), totalSeconds = _useState4[0], setTotalSeconds = _useState4[1]; var _useState5 = useState(0), _useState6 = _slicedToArray(_useState5, 2), percent = _useState6[0], setPercent = _useState6[1]; var _useState7 = useState(false), _useState8 = _slicedToArray(_useState7, 2), isCanPlay = _useState8[0], setIsCanPlay = _useState8[1]; var _useState9 = useState('00:00:00'), _useState10 = _slicedToArray(_useState9, 2), currentDuration = _useState10[0], setCurrentDuration = _useState10[1]; var statusRef = useRef({ currentTime: 0, currentDuration: '00:00:00', percent: 0 }); var audioRef = useRef(Taro.createInnerAudioContext()); var audioCtx = audioRef.current; audioCtx.src = url; audioCtx.autoplay = autoplay || false; audioCtx.loop = loop || false; audioCtx.onPause(function () { props.onPause && props.onPause(audioCtx); }); audioCtx.onEnded(function () { if (props.loop) { warn(locale.audio.tips || 'onPlayEnd事件在loop=false时才会触发'); } else { props.onPlayEnd && props.onPlayEnd(audioCtx); } }); audioCtx.onPlay(function () { var duration = audioCtx.duration; setTotalSeconds(Math.floor(duration)); props.onPlay && props.onPlay(audioCtx); }); audioCtx.onCanplay(function () { var intervalID = setInterval(function () { if (audioCtx.duration !== 0) { setTotalSeconds(audioCtx.duration); clearInterval(intervalID); } }, 500); setIsCanPlay(true); props.onCanPlay && props.onCanPlay(audioCtx); }); audioCtx.onTimeUpdate(function () { var time = parseInt("".concat(audioCtx.currentTime)); var formated = formatSeconds("".concat(time)); statusRef.current.currentDuration = formated; setPercent(time / totalSeconds * 100); setCurrentDuration(formatSeconds(audioCtx.currentTime.toString())); }); audioCtx.onError(function (res) { console.log('code', res.errCode); console.log('message', res.errMsg); }); function formatSeconds(value) { if (!value) { return '00:00:00'; } var time = parseInt(value); var hours = Math.floor(time / 3600); var minutes = Math.floor((time - hours * 3600) / 60); var secondss = time - hours * 3600 - minutes * 60; var result = ''; result += "".concat("0".concat(hours.toString()).slice(-2), ":"); result += "".concat("0".concat(minutes.toString()).slice(-2), ":"); result += "0".concat(secondss.toString()).slice(-2); return result; } var handleBack = function handleBack() { var currentTime = Math.floor(audioCtx.currentTime); statusRef.current.currentTime = Math.max(currentTime - 1, 0); setCurrentDuration(formatSeconds(statusRef.current.currentTime.toString())); audioCtx.seek(statusRef.current.currentTime); props.onFastBack && props.onFastBack(audioCtx); }; var handleForward = function handleForward() { var currentTime = Math.floor(audioCtx.currentTime); statusRef.current.currentTime = Math.min(currentTime + 1, audioCtx.duration); setCurrentDuration(formatSeconds(statusRef.current.currentTime.toString())); audioCtx.seek(statusRef.current.currentTime); props.onForward && props.onForward(audioCtx); }; var handleStatusChange = function handleStatusChange() { setPlaying(!playing); if (!playing) { audioCtx.play(); } else { audioCtx.pause(); } }; var renderIcon = function renderIcon() { return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", { className: b('icon') }, React__default.createElement("div", { className: "".concat(b('icon-box'), " ").concat(playing ? b('icon-play') : b('icon-stop')), onClick: handleStatusChange }, playing ? React__default.createElement(Icon, { classPrefix: iconClassPrefix, fontClassName: iconFontClassName, name: "service", className: "nut-icon-loading" }) : React__default.createElement(Icon, { classPrefix: iconClassPrefix, fontClassName: iconFontClassName, name: "service" })))); }; var renderProgerss = function renderProgerss() { return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", { className: b('progress') }, React__default.createElement("div", { className: "time" }, currentDuration), React__default.createElement("div", { className: b('progress-bar-wrapper') }, React__default.createElement(Range, { modelValue: percent, hiddenTag: true, hiddenRange: true, "inactive-color": "#cccccc", "active-color": "#fa2c19" })), React__default.createElement("div", { className: "time" }, formatSeconds("".concat(totalSeconds)) || '00:00:00')), React__default.createElement("div", { className: isCanPlay ? 'custom-button-group' : 'custom-button-group-disable' }, React__default.createElement(Button, { type: "primary", size: "small", className: "back", onClick: handleBack }, locale.audio.back || '快退'), React__default.createElement(Button, { type: "primary", size: "small", className: "start", onClick: handleStatusChange }, playing ? "".concat(locale.audio.pause || '暂停') : "".concat(locale.audio.start || '开始')), React__default.createElement(Button, { type: "primary", size: "small", onClick: handleForward }, locale.audio.forward || '快进'))); }; var renderNone = function renderNone() { return React__default.createElement("div", { className: b('none-container'), onClick: handleStatusChange }, children); }; var renderAudio = function renderAudio() { switch (type) { case 'icon': return renderIcon(); case 'progress': return renderProgerss(); case 'none': return renderNone(); default: return null; } }; return React__default.createElement("div", _objectSpread({ className: "".concat(b(), " ").concat(className), style: style }, rest), renderAudio()); }; Audio.defaultProps = defaultProps; Audio.displayName = 'NutAudio'; export { Audio as A };