@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
204 lines (203 loc) • 8.95 kB
JavaScript
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import React, { useState, useRef } from "react";
import { createInnerAudioContext } from "@tarojs/taro";
import { Service } from "@nutui/icons-react-taro";
import { View } from "@tarojs/components";
import Range from "../range/index";
import Button from "../button/index";
import { useConfig } from "../configprovider/index";
import { ComponentDefaults } from "../../utils/typings";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
className: '',
src: '',
style: {},
autoplay: false,
loop: false,
type: 'progress',
onFastBack: function(ctx) {},
onForward: function(ctx) {},
onPause: function(ctx) {},
onPlay: function(ctx) {},
onPlayEnd: function(ctx) {},
onCanPlay: function(ctx) {}
});
export var Audio = function(props) {
var formatSeconds = 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 classPrefix = 'nut-audio';
var locale = useConfig().locale;
var _ref = _object_spread({}, defaultProps, props), className = _ref.className, src = _ref.src, style = _ref.style, autoplay = _ref.autoplay, loop = _ref.loop, type = _ref.type, onFastBack = _ref.onFastBack, onForward = _ref.onForward, onPause = _ref.onPause, onPlay = _ref.onPlay, onPlayEnd = _ref.onPlayEnd, onCanPlay = _ref.onCanPlay, children = _ref.children, iconClassPrefix = _ref.iconClassPrefix, iconFontClassName = _ref.iconFontClassName, rest = _object_without_properties(_ref, [
"className",
"src",
"style",
"autoplay",
"loop",
"type",
"onFastBack",
"onForward",
"onPause",
"onPlay",
"onPlayEnd",
"onCanPlay",
"children",
"iconClassPrefix",
"iconFontClassName"
]);
var _useState = _sliced_to_array(useState(false), 2), playing = _useState[0], setPlaying = _useState[1];
var _useState1 = _sliced_to_array(useState(0), 2), totalSeconds = _useState1[0], setTotalSeconds = _useState1[1];
var _useState2 = _sliced_to_array(useState(0), 2), percent = _useState2[0], setPercent = _useState2[1];
var _useState3 = _sliced_to_array(useState(false), 2), isCanPlay = _useState3[0], setIsCanPlay = _useState3[1];
var _useState4 = _sliced_to_array(useState('00:00:00'), 2), currentDuration = _useState4[0], setCurrentDuration = _useState4[1];
var statusRef = useRef({
currentTime: 0,
currentDuration: '00:00:00',
percent: 0
});
var audioRef = useRef(createInnerAudioContext());
var audioCtx = audioRef.current;
audioCtx.src = src;
audioCtx.autoplay = autoplay || false;
audioCtx.loop = loop || false;
audioCtx.onPause(function() {
onPause === null || onPause === void 0 ? void 0 : onPause(audioCtx);
});
audioCtx.onEnded(function() {
if (loop) {
console.warn(locale.audio.tips || 'onPlayEnd事件在loop=false时才会触发');
} else {
onPlayEnd === null || onPlayEnd === void 0 ? void 0 : onPlayEnd(audioCtx);
}
});
audioCtx.onPlay(function() {
var duration = audioCtx.duration;
setTotalSeconds(Math.floor(duration));
onPlay === null || onPlay === void 0 ? void 0 : onPlay(audioCtx);
});
audioCtx.onCanplay(function() {
var intervalID = setInterval(function() {
if (audioCtx.duration !== 0) {
setTotalSeconds(audioCtx.duration);
clearInterval(intervalID);
}
}, 500);
setIsCanPlay(true);
onCanPlay === null || onCanPlay === void 0 ? void 0 : 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.warn('onError', res.errCode, res.errMsg);
});
var handleBack = function() {
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);
onFastBack === null || onFastBack === void 0 ? void 0 : onFastBack(audioCtx);
};
var handleForward = function() {
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);
onForward === null || onForward === void 0 ? void 0 : onForward(audioCtx);
};
var handleStatusChange = function() {
setPlaying(!playing);
if (!playing) {
audioCtx.play();
} else {
audioCtx.pause();
}
};
var renderIcon = function() {
return /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-icon")
}, /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-icon-box} ").concat(playing ? "".concat(classPrefix, "-icon-play}") : "".concat(classPrefix, "-icon-stop}")),
onClick: handleStatusChange
}, /*#__PURE__*/ React.createElement(Service, {
className: playing ? 'nut-icon-loading' : ''
})));
};
var renderProgerss = function() {
return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-progress")
}, /*#__PURE__*/ React.createElement(View, {
className: "time"
}, currentDuration), /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-progress-bar-wrapper")
}, /*#__PURE__*/ React.createElement(Range, {
value: percent,
onChange: function(val) {
return setPercent(val);
},
currentDescription: null,
maxDescription: null,
minDescription: null,
"inactive-color": "#cccccc",
"active-color": "#FF0F23"
})), /*#__PURE__*/ React.createElement(View, {
className: "time"
}, formatSeconds("".concat(totalSeconds)) || '00:00:00')), /*#__PURE__*/ React.createElement(View, {
className: isCanPlay ? 'custom-button-group' : 'custom-button-group-disable'
}, /*#__PURE__*/ React.createElement(Button, {
type: "primary",
size: "small",
className: "back",
onClick: handleBack
}, locale.audio.back || '快退'), /*#__PURE__*/ React.createElement(Button, {
type: "primary",
size: "small",
className: "start",
onClick: handleStatusChange
}, playing ? "".concat(locale.audio.pause || '暂停') : "".concat(locale.audio.start || '开始')), /*#__PURE__*/ React.createElement(Button, {
type: "primary",
size: "small",
onClick: handleForward
}, locale.audio.forward || '快进')));
};
var renderNone = function() {
return /*#__PURE__*/ React.createElement(View, {
className: "".concat(classPrefix, "-none-container"),
onClick: handleStatusChange
}, children);
};
var renderAudio = function() {
switch(type){
case 'icon':
return renderIcon();
case 'progress':
return renderProgerss();
case 'none':
return renderNone();
default:
return null;
}
};
return /*#__PURE__*/ React.createElement(View, _object_spread({
className: "".concat(classPrefix, " ").concat(className),
style: style
}, rest), renderAudio());
};
Audio.displayName = 'NutAudio';