Created
August 23, 2018 08:55
-
-
Save kkkrist/6f985ee0f3e6d7c206fd399786262643 to your computer and use it in GitHub Desktop.
Alternate UI for react-mic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import PropTypes from 'prop-types' | |
import React from 'react' | |
import { MicrophoneRecorder } from 'react-mic/lib/libs/MicrophoneRecorder' | |
import app from '../app' | |
import translate from '../../modules/translate' | |
import uploadAttachment from '../../modules/upload-attachment' | |
import Icon from './icon' | |
const uploadsService = app.service('uploads/:filename') | |
export default class AudioRecorder extends React.Component { | |
static propTypes = { | |
addModal: PropTypes.func.isRequired, | |
id: PropTypes.string.isRequired, | |
handleChange: PropTypes.func.isRequired, | |
url: PropTypes.string | |
} | |
constructor (props) { | |
super() | |
this.state = { | |
current: props.url, | |
library: props.url ? [props.url] : [], | |
recording: false, | |
uploading: false | |
} | |
if (window.MediaRecorder) { | |
this.microphoneRecorder = new MicrophoneRecorder( | |
this.handleStart, | |
this.handleStop, | |
{ | |
audioBitsPerSecond: 128000, | |
mimeType: 'audio/webm;codecs=opus' | |
} | |
) | |
} | |
} | |
componentWillUnmount () { | |
this.cleanup(this.state.current) | |
} | |
cleanup = keep => { | |
this.state.library.map(url => { | |
if (url !== keep) { | |
uploadsService | |
.remove(url.slice(9).replace(/\/.*$/, '')) | |
.catch(console.error) | |
} | |
}) | |
this.setState({ | |
current: keep, | |
library: [keep] | |
}) | |
} | |
handleDelete = () => { | |
this.props.handleChange({ correctionAudioUrl: null }) | |
this.setState({ | |
blobURL: null | |
}) | |
} | |
handleRecording = () => { | |
if (this.state.recording) { | |
this.microphoneRecorder.stopRecording() | |
} else { | |
this.microphoneRecorder.startRecording() | |
} | |
} | |
handleStart = () => { | |
this.setState({ recording: true }) | |
} | |
handleStop = file => { | |
file.blob.name = 'audio.ogg' | |
this.setState({ blobURL: file.blobURL, recording: false, uploading: true }) | |
this.storeUpload(file.blob, this.props.id) | |
} | |
storeUpload = (result, id) => { | |
const { addModal, handleChange } = this.props | |
uploadAttachment( | |
{ | |
file: result, | |
onError: error => { | |
addModal({ | |
title: 'Fehler' + (error.code ? ' ' + error.code : ''), | |
body: | |
'Fehler beim Hochladen der Datei' + | |
(error.message ? `: ${translate(error.message)}` : '.'), | |
icon: 'faExclamationCircle', | |
cssClass: 'is-danger' | |
}) | |
}, | |
setAttributes: attributes => { | |
handleChange({ correctionAudioUrl: attributes.url }) | |
this.setState(({ library }) => ({ | |
library: library.concat([attributes.url]), | |
uploading: false | |
})) | |
} | |
}, | |
id | |
) | |
} | |
render () { | |
const { url } = this.props | |
const { blobURL, recording, uploading } = this.state | |
if (!this.microphoneRecorder) { | |
return ( | |
<div className='audio-recorder'> | |
<button className='button is-outlined' disabled type='button'> | |
<span className='icon'> | |
<Icon icon='faMicrophone' props={{ fixedWidth: true }} /> | |
</span> | |
</button> | |
<span | |
className='help has-text-grey' | |
style={{ display: 'inline', marginLeft: '1em' }} | |
> | |
Audio-Kommentare sind z.Zt. leider nur mit Chrome oder Firefox | |
möglich. | |
</span> | |
</div> | |
) | |
} else { | |
return ( | |
<div className='audio-recorder columns buttons has-addons'> | |
<div className='column is-narrow'> | |
<button | |
className={`button ${ | |
recording ? 'is-danger is-breathing' : 'is-outlined' | |
}`} | |
disabled={!this.microphoneRecorder} | |
onClick={this.handleRecording} | |
type='button' | |
> | |
<span className='icon'> | |
<Icon | |
icon={uploading ? 'faSpinner' : 'faMicrophone'} | |
props={{ fixedWidth: true, pulse: uploading }} | |
/> | |
</span> | |
</button> | |
{(blobURL || (url && blobURL !== null)) && ( | |
<button | |
className='button is-outlined' | |
disabled={recording || uploading} | |
onClick={this.handleDelete} | |
type='button' | |
> | |
<span className='icon'> | |
<Icon | |
icon='faTrash' | |
props={{ color: 'var(--color-danger)', fixedWidth: true }} | |
/> | |
</span> | |
</button> | |
)} | |
</div> | |
<div className='column is-narrow'> | |
{!recording && | |
(blobURL || (url && blobURL !== null)) && ( | |
<audio controls src={blobURL || url} /> | |
)} | |
</div> | |
</div> | |
) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment