Skip to content

Commit

Permalink
push-to-talk support
Browse files Browse the repository at this point in the history
  • Loading branch information
aviraldg committed Feb 16, 2017
1 parent ebe7ec4 commit f85bf00
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 5 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"linkifyjs": "^2.1.3",
"lodash": "^4.13.1",
"matrix-js-sdk": "matrix-org/matrix-js-sdk#develop",
"msr": "^1.3.4",
"optimist": "^0.6.1",
"q": "^1.4.1",
"react": "^15.4.0",
Expand Down
5 changes: 3 additions & 2 deletions src/ContentMessages.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ class ContentMessages {
this.nextId = 0;
}

sendContentToRoom(file, roomId, matrixClient) {
const content = {
sendContentToRoom(file, roomId, matrixClient, infoFunction: (Object) => Object = (o) => o) {
let content = {
body: file.name,
info: {
size: file.size,
Expand Down Expand Up @@ -343,6 +343,7 @@ class ContentMessages {
dis.dispatch({action: 'upload_progress', upload: upload});
}
}).then(function(url) {
content = infoFunction(content);
return matrixClient.sendMessage(roomId, content);
}, function(err) {
error = err;
Expand Down
4 changes: 2 additions & 2 deletions src/components/structures/RoomView.js
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@ module.exports = React.createClass({
this.setState({ draggingFile : false });
},

uploadFile: function(file) {
uploadFile: function(file, infoFunction: (Object) => Object = (o) => o) {
var self = this;

if (MatrixClientPeg.get().isGuest()) {
Expand All @@ -887,7 +887,7 @@ module.exports = React.createClass({
}

ContentMessages.sendContentToRoom(
file, this.state.room.roomId, MatrixClientPeg.get()
file, this.state.room.roomId, MatrixClientPeg.get(), infoFunction,
).done(undefined, function(error) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createDialog(ErrorDialog, {
Expand Down
6 changes: 5 additions & 1 deletion src/components/views/messages/MAudioBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,13 @@ export default class MAudioBody extends React.Component {

const contentUrl = this._getContentUrl();

const shouldAutoPlay = MatrixClientPeg.get().credentials.userId !==
this.props.mxEvent.sender.userId &&
content.autoplay;

return (
<span className="mx_MAudioBody">
<audio src={contentUrl} controls />
<audio src={contentUrl} controls autoPlay={shouldAutoPlay} />
<MFileBody {...this.props} decryptedBlob={this.state.decryptedBlob} />
</span>
);
Expand Down
82 changes: 82 additions & 0 deletions src/components/views/rooms/AudioRecorder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//@flow

import React from 'react';

import sdk from '../../../index';
import Modal from '../../../Modal';
import ErrorDialog from '../dialogs/ErrorDialog';
import MediaStreamRecorder from 'msr';

export default class AudioRecorder extends React.Component {
static propTypes = {
sendAudioBlob: React.PropTypes.func.isRequired,
};

mediaStream: ?MediaStream = null;
recorder: ?MediaStreamRecorder = null;
blobs: Array<Blob> = [];

constructor(props: Object) {
super(props);

this.state = {
recording: false,
};
}

onRecordClicked = async () => {
if(this.state.recording && this.mediaStream) {
this.recorder.stop();
window.ConcatenateBlobs(this.blobs, this.blobs[0].type, (blob) => {
console.log(blob);
this.props.sendAudioBlob(blob);
this.blobs = [];
this.recorder = null;
this.mediaStream.getTracks().forEach(track => track.stop());
this.mediaStream = null;
});
} else {
try {
const mediaStream = await navigator.mediaDevices.getUserMedia({
audio: true,
});
this.onUserMediaSuccess(mediaStream);
} catch (e) {
this.onUserMediaFailure(e);
}
}
};

onUserMediaFailure = () => {
Modal.createDialog(ErrorDialog, {
description: "Failed to start recording.",
});
};

onUserMediaSuccess = (mediaStream: MediaStream) => {
this.mediaStream = mediaStream;
this.recorder = new MediaStreamRecorder(this.mediaStream);
this.recorder.recorderType = class extends MediaStreamRecorder.StereoAudioRecorder {
constructor(mediaStream: MediaStream) {
super(mediaStream);
this.audioChannels = 1;
}
};
this.recorder.ondataavailable = (blob) => {
this.blobs.push(blob);
};
this.recorder.mimeType = 'audio/wav';
this.recorder.start(100);
this.setState({recording: true});
};

render() {
const TintableSvg = sdk.getComponent("elements.TintableSvg");
return (
<div key="controls_ptt" className="mx_MessageComposer_voicecall"
onClick={this.onRecordClicked} title="Record & send message">
<TintableSvg src="img/voice.svg" width="22" height="22"/>
</div>
);
}
}
13 changes: 13 additions & 0 deletions src/components/views/rooms/MessageComposer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var sdk = require('../../../index');
var dis = require('../../../dispatcher');
import Autocomplete from './Autocomplete';
import classNames from 'classnames';
import AudioRecorder from './AudioRecorder';

import UserSettingsStore from '../../../UserSettingsStore';

Expand Down Expand Up @@ -262,6 +263,17 @@ export default class MessageComposer extends React.Component {
MatrixClientPeg.get().credentials.userId);

if (canSendMessages) {
const sendAudioBlob = (blob) => {
const file = new File([blob], `${+new Date()}.wav`, {
type: blob.type,
});
this.props.uploadFile(file, (content) => {
content.autoplay = true;
return content;
});
};
const pttButton = <AudioRecorder sendAudioBlob={sendAudioBlob} />;

// This also currently includes the call buttons. Really we should
// check separately for whether we can call, but this is slightly
// complex because of conference calls.
Expand Down Expand Up @@ -299,6 +311,7 @@ export default class MessageComposer extends React.Component {
onContentChanged={this.onInputContentChanged}
onInputStateChanged={this.onInputStateChanged} />,
formattingButton,
pttButton,
uploadButton,
hangupButton,
callButton,
Expand Down

0 comments on commit f85bf00

Please sign in to comment.