@krowdy-ui/views
Version:
React components that implement Google's Material Design.
431 lines (389 loc) • 13.3 kB
JavaScript
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));