UNPKG

@krowdy-ui/views

Version:

React components that implement Google's Material Design.

431 lines (389 loc) 13.3 kB
import _regeneratorRuntime from "@babel/runtime/regenerator"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _extends from "@babel/runtime/helpers/esm/extends"; import React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import MicRecorder from 'mic-recorder-to-mp3'; import { IconButton } from '@krowdy-ui/core'; import { withStyles } from '@krowdy-ui/styles'; import Timer from 'react-compound-timer'; var Mp3Recorder = new MicRecorder({ bitRate: 128 }); var SPECTRO_PASSIVE_COLOR = 'grey'; var SPECTRO_ACTIVE_COLOR = 'white'; var TIME_RECORD = 120; var INCREMENT_STYLE = 6.92; var PADDING_LEFT = 15; var PADDING_RIGHT = 15; // position var X_POSITION = PADDING_LEFT; var Y_SIZE = 0; export var styles = function styles(theme) { return { audio: { height: 0, visibility: 'hidden', width: 0 }, barContainer: { alignItems: 'center', display: 'flex', flexDirection: 'row', position: 'relative', width: 'calc(100% - 230px)' }, button: { color: theme.palette.primary['contrastText'], fontWeight: 'bold', left: 10, position: 'absolute' }, canvas: { background: theme.palette.primary[500], borderRadius: 60, height: 50, padding: 5, width: '100%' }, container: { display: 'flex', flexDirection: 'row' }, counter: { color: theme.palette.primary['contrastText'], fontWeight: 'bold', position: 'absolute', right: 26 } }; }; var withTimer = function withTimer(timerProps) { return function (WrappedComponent) { return function (wrappedComponentProps) { return /*#__PURE__*/React.createElement(Timer, timerProps, function (timerRenderProps) { return /*#__PURE__*/React.createElement(WrappedComponent, _extends({}, wrappedComponentProps, { timer: timerRenderProps })); }); }; }; }; var interval = null; var getLimitDate = function getLimitDate(secs) { var rawDate = new Date(null); rawDate.setSeconds(secs); return rawDate.toISOString().substr(14, 5); }; var _ref = /*#__PURE__*/React.createElement(Timer.Minutes, null); var _ref2 = /*#__PURE__*/React.createElement("span", null, ":"); var _ref3 = /*#__PURE__*/React.createElement(Timer.Seconds, null); var _ref4 = /*#__PURE__*/React.createElement("span", null, "/"); var AudioRecorder = function AudioRecorder(props) { var classes = props.classes, PauseIcon = props.pause, PlayIcon = props.play, RecordIcon = props.record, StopIcon = props.stop, DeleteIcon = props['delete'], _props$timer = props.timer, start = _props$timer.start, pause = _props$timer.pause, stop = _props$timer.stop, reset = _props$timer.reset, getTime = _props$timer.getTime, _props$onBlobUrl = props.onBlobUrl, onBlobUrl = _props$onBlobUrl === void 0 ? function () {} : _props$onBlobUrl, _props$spectroActiveC = props.spectroActiveColor, spectroActiveColor = _props$spectroActiveC === void 0 ? SPECTRO_ACTIVE_COLOR : _props$spectroActiveC, _props$spectroPassive = props.spectroPassiveColor, spectroPassiveColor = _props$spectroPassive === void 0 ? SPECTRO_PASSIVE_COLOR : _props$spectroPassive, _props$onStatus = props.onStatus, onStatus = _props$onStatus === void 0 ? function () {} : _props$onStatus, classNameCanvas = props.classNameCanvas; var _React$useState = React.useState(''), _React$useState2 = _slicedToArray(_React$useState, 2), blobURL = _React$useState2[0], setBlobURL = _React$useState2[1]; var _React$useState3 = React.useState(false), _React$useState4 = _slicedToArray(_React$useState3, 2), blocked = _React$useState4[0], setBlocked = _React$useState4[1]; var _React$useState5 = React.useState(null), _React$useState6 = _slicedToArray(_React$useState5, 2), ctx = _React$useState6[0], setCtx = _React$useState6[1]; var _React$useState7 = React.useState(0), _React$useState8 = _slicedToArray(_React$useState7, 2), time = _React$useState8[0], setTime = _React$useState8[1]; var _React$useState9 = React.useState('record'), _React$useState10 = _slicedToArray(_React$useState9, 2), type = _React$useState10[0], setType = _React$useState10[1]; var _React$useState11 = React.useState({ i: X_POSITION, x: Y_SIZE }), _React$useState12 = _slicedToArray(_React$useState11, 2), currentTime = _React$useState12[0], setCurrentTime = _React$useState12[1]; var canvas = React.useRef(); var audio = React.useRef(); var drawStick = function drawStick(ctx, i, x, color) { var cut = canvas.current.height * Math.abs(Math.sin(x)); ctx.fillStyle = color; ctx.fillRect(i * 2, (canvas.current.height - cut) / 2, 2, cut); }; var drawSticks = React.useCallback(function (ctx, limit, color, lazy) { if (!lazy) ctx.clearRect(0, 0, canvas.current.width, canvas.current.height); var i = X_POSITION; var x = Y_SIZE; while (limit - (PADDING_LEFT + PADDING_RIGHT) > i) { x += INCREMENT_STYLE; drawStick(ctx, i, x, color); i += 2; } }, []); var loopFrames = function loopFrames(lapse) { var i = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : X_POSITION; var x = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Y_SIZE; interval = setInterval(function () { if (getTime() >= lapse * 1000) { _handleStop(); clearInterval(interval); setCurrentTime({ i: X_POSITION, x: Y_SIZE }); } else { if (canvas && canvas.current && canvas.current.height) { if (canvas.current.height - (PADDING_LEFT + PADDING_RIGHT) > i) { x += INCREMENT_STYLE; drawStick(ctx, i, x, spectroActiveColor); i += 2; setCurrentTime({ i: i, x: x }); } else { _handleStop(); clearInterval(interval); setCurrentTime({ i: X_POSITION, x: Y_SIZE }); } } else { _handleStop(); clearInterval(interval); setCurrentTime({ i: X_POSITION, x: Y_SIZE }); } } }, lapse * 1000 / ((canvas.current.height - (PADDING_LEFT + PADDING_RIGHT + PADDING_RIGHT)) / 2)); }; var changeType = function changeType(type) { setType(type); onStatus(type); }; var updateCanvas = React.useCallback(function () { var ctx = canvas.current.getContext('2d'); setCtx(ctx); drawSticks(ctx, canvas.current.height, spectroPassiveColor); }, [drawSticks, spectroPassiveColor]); var _handleRecord = function _handleRecord() { return _regeneratorRuntime.async(function _handleRecord$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (blocked) { _context.next = 17; break; } _context.prev = 1; setBlobURL(''); setTime(0); drawSticks(ctx, canvas.current.height, spectroPassiveColor); loopFrames(TIME_RECORD); _context.next = 8; return _regeneratorRuntime.awrap(Mp3Recorder.start()); case 8: changeType('stop'); start(); _context.next = 15; break; case 12: _context.prev = 12; _context.t0 = _context["catch"](1); console.error(_context.t0); case 15: _context.next = 18; break; case 17: console.error('Permission Denied'); case 18: case "end": return _context.stop(); } } }, null, null, [[1, 12]], Promise); }; var _handlePause = function _handlePause() { audio.current.pause(); pause(); clearInterval(interval); changeType('play'); }; var _handleStop = function _handleStop() { var _await$Mp3Recorder$st, _await$Mp3Recorder$st2, buffer, blob, _blobURL; return _regeneratorRuntime.async(function _handleStop$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _context2.prev = 0; _context2.next = 3; return _regeneratorRuntime.awrap(Mp3Recorder.stop().getMp3()); case 3: _await$Mp3Recorder$st = _context2.sent; _await$Mp3Recorder$st2 = _slicedToArray(_await$Mp3Recorder$st, 2); buffer = _await$Mp3Recorder$st2[0]; blob = _await$Mp3Recorder$st2[1]; _blobURL = URL.createObjectURL(blob); onBlobUrl({ blob: blob, blobURL: _blobURL, buffer: buffer }); changeType('play'); drawSticks(ctx, canvas.current.height, spectroPassiveColor); stop(); reset(); clearInterval(interval); setCurrentTime({ i: X_POSITION, x: Y_SIZE }); setBlobURL(_blobURL); _context2.next = 21; break; case 18: _context2.prev = 18; _context2.t0 = _context2["catch"](0); console.error(_context2.t0); case 21: case "end": return _context2.stop(); } } }, null, null, [[0, 18]], Promise); }; var _handlePlay = function _handlePlay() { var i = currentTime.i, x = currentTime.x; if (i === X_POSITION || x === 0) drawSticks(ctx, canvas.current.height, spectroPassiveColor); audio.current.play(); changeType('pause'); loopFrames(time, i, x); setCurrentTime({ i: X_POSITION, x: Y_SIZE }); start(); }; var _handleDelete = function _handleDelete() { changeType('record'); setBlobURL(''); setTime(0); clearInterval(interval); setCurrentTime({ i: X_POSITION, x: Y_SIZE }); stop(); reset(); drawSticks(ctx, canvas.current.height, spectroPassiveColor); }; React.useEffect(function () { updateCanvas(); }, [updateCanvas]); React.useEffect(function () { navigator.getUserMedia({ audio: true }, function () { setBlocked(false); }, function () { setBlocked(true); }); }, []); React.useEffect(function () { audio.current.onloadedmetadata = function () { setTime(audio.current.duration); }; }, [blobURL]); return /*#__PURE__*/React.createElement("div", { className: classes.container }, /*#__PURE__*/React.createElement("div", { className: classes.barContainer }, /*#__PURE__*/React.createElement("canvas", { className: clsx(classes.canvas, classNameCanvas), ref: canvas }), /*#__PURE__*/React.createElement("audio", { className: classes.audio, controls: "controls", ref: audio, src: blobURL }), /*#__PURE__*/React.createElement("div", { className: classes.button }, type === 'record' ? /*#__PURE__*/React.createElement(IconButton, { color: "inherit", onClick: _handleRecord, variant: "contained" }, /*#__PURE__*/React.createElement(RecordIcon, null)) : type === 'play' ? /*#__PURE__*/React.createElement(IconButton, { color: "inherit", onClick: _handlePlay, variant: "contained" }, /*#__PURE__*/React.createElement(PlayIcon, null)) : type === 'pause' ? /*#__PURE__*/React.createElement(IconButton, { color: "inherit", onClick: _handlePause, variant: "contained" }, /*#__PURE__*/React.createElement(PauseIcon, null)) : type === 'stop' ? /*#__PURE__*/React.createElement(IconButton, { color: "inherit", onClick: _handleStop, variant: "contained" }, /*#__PURE__*/React.createElement(StopIcon, null)) : /*#__PURE__*/React.createElement(IconButton, { color: "inherit", onClick: _handleRecord, variant: "contained" }, /*#__PURE__*/React.createElement(RecordIcon, null))), /*#__PURE__*/React.createElement("div", { className: classes.counter }, _ref, _ref2, _ref3, _ref4, /*#__PURE__*/React.createElement("span", null, getLimitDate(time ? time : TIME_RECORD)))), blobURL && /*#__PURE__*/React.createElement(IconButton, { color: "error", onClick: _handleDelete, variant: "contained" }, /*#__PURE__*/React.createElement(DeleteIcon, null))); }; process.env.NODE_ENV !== "production" ? AudioRecorder.propTypes = { classNameCanvas: PropTypes.string, classes: PropTypes.object, 'delete': PropTypes.func.isRequired, onBlobUrl: PropTypes.func, onStatus: PropTypes.func, pause: PropTypes.func.isRequired, play: PropTypes.func.isRequired, record: PropTypes.func.isRequired, spectroActiveColor: PropTypes.string, spectroPassiveColor: PropTypes.string, stop: PropTypes.func.isRequired } : void 0; AudioRecorder.muiName = 'AudioRecorder'; export default withStyles(styles, { name: 'AudioRecorder' })(withTimer({ formatValue: function formatValue(value) { return "".concat(value < 10 ? "0".concat(value) : value); }, startImmediately: false })(AudioRecorder));