@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
243 lines (242 loc) • 9.71 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, useEffect, useRef } from "react";
import { Service } from "@nutui/icons-react";
import classNames from "classnames";
import Range from "../range";
import Button from "../button";
import { useConfig } from "../configprovider";
import { ComponentDefaults } from "../../utils/typings";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
src: '',
muted: false,
autoPlay: false,
loop: false,
preload: 'auto',
type: 'progress',
onBack: function(e) {},
onForward: function(e) {},
onPause: function(e) {},
onEnd: function(e) {},
onMute: function(e) {},
onCanPlay: function(e) {}
});
export var Audio = function(props) {
var watch = function watch() {
if (AudioRef && AudioRef.current) {
var current = AudioRef.current;
current.addEventListener('play', function() {
setPlaying(true);
});
}
};
var locale = useConfig().locale;
var _ref = _object_spread({}, defaultProps, props), className = _ref.className, src = _ref.src, style = _ref.style, muted = _ref.muted, autoPlay = _ref.autoPlay, loop = _ref.loop, preload = _ref.preload, type = _ref.type, onBack = _ref.onBack, onForward = _ref.onForward, onPause = _ref.onPause, onEnd = _ref.onEnd, onMute = _ref.onMute, onCanPlay = _ref.onCanPlay, children = _ref.children, rest = _object_without_properties(_ref, [
"className",
"src",
"style",
"muted",
"autoPlay",
"loop",
"preload",
"type",
"onBack",
"onForward",
"onPause",
"onEnd",
"onMute",
"onCanPlay",
"children"
]);
var _useState = _sliced_to_array(useState(false), 2), playing = _useState[0], setPlaying = _useState[1];
var _useState1 = _sliced_to_array(useState(0), 2), percent = _useState1[0], setPercent = _useState1[1];
var _useState2 = _sliced_to_array(useState(false), 2), isCanPlay = _useState2[0], setIsCanPlay = _useState2[1];
var _useState3 = _sliced_to_array(useState('00:00:00'), 2), currentDuration = _useState3[0], setCurrentDuration = _useState3[1];
var AudioRef = useRef(null);
var statusRef = useRef({
currentTime: 0,
currentDuration: '00:00:00',
percent: 0,
duration: '00:00:00',
second: 0,
hanMuted: muted,
playing: autoPlay,
handPlaying: false
});
var classPrefix = 'nut-audio';
var handleEnded = function(e) {
if (loop) {
console.warn(locale.audio.tips || 'onPlayEnd事件在loop=false时才会触发');
} else {
onEnd === null || onEnd === void 0 ? void 0 : onEnd(e);
}
};
useEffect(function() {
watch();
}, []);
useEffect(function() {}, [
currentDuration
]);
var handleStatusChange = function() {
setPlaying(!playing);
if (playing) {
AudioRef && AudioRef.current && AudioRef.current.pause();
} else {
AudioRef && AudioRef.current && AudioRef.current.play();
}
};
var renderIcon = function() {
return /*#__PURE__*/ React.createElement("div", {
className: "".concat(classPrefix, "-icon")
}, /*#__PURE__*/ React.createElement("div", {
className: classNames("".concat(classPrefix, "-icon-box"), playing ? "".concat(classPrefix, "-icon-play") : "".concat(classPrefix, "-icon-stop")),
onClick: handleStatusChange
}, /*#__PURE__*/ React.createElement(Service, {
className: playing ? 'nut-icon-loading' : ''
})));
};
var handleBack = function() {
if (statusRef.current.currentTime > 0 && AudioRef.current) {
statusRef.current.currentTime--;
AudioRef.current.currentTime = statusRef.current.currentTime;
onBack === null || onBack === void 0 ? void 0 : onBack(AudioRef.current);
}
};
var handleForward = function() {
if (AudioRef.current) {
statusRef.current.currentTime++;
AudioRef.current.currentTime = statusRef.current.currentTime;
onForward === null || onForward === void 0 ? void 0 : onForward(AudioRef.current);
}
};
var handleMute = function() {
if (AudioRef.current) {
AudioRef.current.muted = !AudioRef.current.muted;
onMute === null || onMute === void 0 ? void 0 : onMute(AudioRef.current);
}
};
var handlePause = function(e) {
setPlaying(false);
onPause === null || onPause === void 0 ? void 0 : onPause(e);
};
var formatSeconds = function(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 seconds = 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(seconds.toString()).slice(-2);
return result;
};
var renderProgerss = function() {
return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("div", {
className: "".concat(classPrefix, "-progress")
}, /*#__PURE__*/ React.createElement("div", {
className: "time"
}, currentDuration), /*#__PURE__*/ React.createElement("div", {
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("div", {
className: "time"
}, AudioRef.current ? formatSeconds("".concat(statusRef.current.second)) : '00:00:00')), /*#__PURE__*/ React.createElement("div", {
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 || '快进'), /*#__PURE__*/ React.createElement(Button, {
type: AudioRef.current && AudioRef.current.muted ? 'default' : 'primary',
size: "small",
onClick: handleMute
}, locale.audio.mute || '静音')));
};
var renderNone = function() {
return /*#__PURE__*/ React.createElement("div", {
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;
}
};
var handleCanplay = function(e) {
setIsCanPlay(true);
if (autoPlay && !playing) {
AudioRef && AudioRef.current && AudioRef.current.play();
}
if (AudioRef.current) {
statusRef.current.second = AudioRef.current.duration || 0;
onCanPlay === null || onCanPlay === void 0 ? void 0 : onCanPlay(e);
}
};
var onTimeupdate = function(e) {
var time = parseInt(String(e.target.currentTime));
var formated = formatSeconds("".concat(time));
statusRef.current.currentDuration = formated;
setPercent(time / statusRef.current.second * 100);
setCurrentDuration(formated);
statusRef.current.currentTime = time;
};
return /*#__PURE__*/ React.createElement("div", _object_spread({
className: classNames(classPrefix, className),
style: style
}, rest), renderAudio(), /*#__PURE__*/ React.createElement("audio", {
className: "audioMain",
controls: type === 'controls',
ref: AudioRef,
src: src,
muted: muted,
preload: preload,
loop: loop,
onPause: function(e) {
return handlePause(e);
},
onEnded: function(e) {
return handleEnded(e);
},
onCanPlay: function(e) {
return handleCanplay(e);
},
onTimeUpdate: function(e) {
return onTimeupdate(e);
}
}, /*#__PURE__*/ React.createElement("track", {
kind: "captions"
})));
};
Audio.displayName = 'NutAudio';