diff --git a/src/app/organisms/room/AttachmentFrame.jsx b/src/app/organisms/room/AttachmentFrame.jsx index 7708736a..72fd75ee 100644 --- a/src/app/organisms/room/AttachmentFrame.jsx +++ b/src/app/organisms/room/AttachmentFrame.jsx @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { attachmentUiFrameTypes } from './AttachmentTypeSelector'; -import { VoiceMailRecorder } from './VoiceMailRecorder'; +import { funnyFunc, VoiceMailRecorder } from './VoiceMailRecorder'; import RawIcon from '../../atoms/system-icons/RawIcon'; import VLCIC from '../../../../public/res/ic/outlined/vlc.svg'; import VolumeFullIC from '../../../../public/res/ic/outlined/volume-full.svg'; @@ -40,6 +40,19 @@ function AttachmentFrame({ } function attachmentFrame() { + let initStop; + const fnInitStop = (func) => { + initStop = func; + }; + let requestResult; + const fnRequestResult = (func) => { + requestResult = func; + }; + let howToSubmit; + const fnHowToSubmit = (func) => { + howToSubmit = func; + }; + // If there already is an attachment, show it if (typeof attachmentOrUi === 'object') return fileAttachedIndicator(); @@ -49,8 +62,9 @@ function AttachmentFrame({ // Not too easy, need to attach function to return the audio blob return ( ); default: diff --git a/src/app/organisms/room/RoomViewInput.jsx b/src/app/organisms/room/RoomViewInput.jsx index 5f28e8be..c0af71d5 100644 --- a/src/app/organisms/room/RoomViewInput.jsx +++ b/src/app/organisms/room/RoomViewInput.jsx @@ -27,6 +27,7 @@ import MarkdownIC from '../../../../public/res/ic/outlined/markdown.svg'; import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import { AttachmentTypeSelector, attachmentUiFrameTypes } from './AttachmentTypeSelector'; import AttachmentFrame from './AttachmentFrame'; +import { VoiceMailRecorder } from './VoiceMailRecorder'; const CMD_REGEX = /(^\/|:|@)(\S*)$/; let isTyping = false; diff --git a/src/app/organisms/room/VoiceMailRecorder.jsx b/src/app/organisms/room/VoiceMailRecorder.jsx index cc0fa03c..22073123 100644 --- a/src/app/organisms/room/VoiceMailRecorder.jsx +++ b/src/app/organisms/room/VoiceMailRecorder.jsx @@ -1,65 +1,101 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import React, { useRef } from 'react'; +import PropTypes, { func } from 'prop-types'; import Text from '../../atoms/text/Text'; import RawIcon from '../../atoms/system-icons/RawIcon'; import VolumeFullIC from '../../../../public/res/ic/outlined/volume-full.svg'; +import IconButton from '../../atoms/button/IconButton'; -function VoiceMailRecorder({ returnedFileHandler, attachmentOrUi }) { - let mediaRecorder; +let _stream; +let _mediaRecorder; +const audioChunks = []; - const recordVoice = () => { - console.log('record voice, new recorder'); - // TODO: Check if supported +console.log('record voice, new recorder'); +// TODO: Check if supported - navigator.mediaDevices.getUserMedia({ audio: true }) - .then((stream) => { - mediaRecorder = new MediaRecorder(stream); - mediaRecorder.start(); - const audioChunks = []; +navigator.mediaDevices.getUserMedia({ audio: true }) + .then((stream) => { + _stream = stream; + _mediaRecorder = new MediaRecorder(_stream); - mediaRecorder.addEventListener('dataavailable', (event) => { - audioChunks.push(event.data); - }); - mediaRecorder.addEventListener('error', (error) => { - console.log(error); - mediaRecorder.stop(); - }); - mediaRecorder.addEventListener('stop', () => { - const opts = { type: 'audio/webm' }; - const audioBlob = new Blob(audioChunks, opts); + _mediaRecorder.start(); - const audioFile = new File([audioBlob], 'voicemail.webm', opts); - console.log(`attachmentOrUi is ${attachmentOrUi}`); - returnedFileHandler(audioFile); - }); + _mediaRecorder.ondataavailable = (event) => audioChunks.push(event.data); + _mediaRecorder.onerror = (error) => { + console.log(error); + _mediaRecorder.stop(); + }; + }) + .catch(console.log); - // Voicemails too long are not nice, lets forbid them! - setTimeout(() => { - mediaRecorder.stop(); - }, 5000); // 1 hour 3600000 - }) - .catch(console.log); - }; +// TODO: Handle turning off the recorder to remove the browser indicator +function VoiceMailRecorder({ fnCancel, fnRequestResult, fnHowToSubmit }) { + const [state, setState] = React.useState('unknown'); - recordVoice(); + while (!_mediaRecorder) { + // Blocking + } + + _mediaRecorder.onstop = () => setState('stopped'); + _mediaRecorder.onstart = () => setState('started'); + _mediaRecorder.onpause = () => setState('paused'); + _mediaRecorder.onresume = () => setState('resumed'); + + function pauseRec() { + if (_mediaRecorder.state === 'recording') { + _mediaRecorder.pause(); + console.log('pause'); + } + } + function startOrResumeRec() { + if (_mediaRecorder.state === 'paused') { + _mediaRecorder.resume(); + console.log('resume'); + } else if (_mediaRecorder.state === 'inactive') { + audioChunks.length = 0; + _mediaRecorder.start(); + console.log('start'); + } + } + function restartRec() { + _mediaRecorder.stop(); + startOrResumeRec(); + } + + function stopAndSubmit() { + _mediaRecorder.stop(); + + _stream.getTracks().forEach((track) => track.stop()); + + const opts = { type: 'audio/webm' }; + const audioBlob = new Blob(audioChunks, opts); + + const audioFile = new File([audioBlob], 'voicemail.webm', opts); + fnHowToSubmit(audioFile); + } + fnCancel(stopAndSubmit); return (
- Voice recorder
- Recording... + Recording...{state} {`for: ${'some time '}`} + + + + +
); } VoiceMailRecorder.propTypes = { - returnedFileHandler: PropTypes.func.isRequired, - attachmentOrUi: PropTypes.node.isRequired, + fnCancel: PropTypes.func.isRequired, + fnRequestResult: PropTypes.func.isRequired, + fnHowToSubmit: PropTypes.func.isRequired, }; export { VoiceMailRecorder };