gui-one-nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
229 lines (228 loc) • 9.56 kB
JavaScript
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 };