Add voice notes
// FREEBIE
This commit is contained in:
parent
cc15af549b
commit
4f46a164ba
22 changed files with 47762 additions and 14 deletions
|
@ -101,13 +101,40 @@
|
|||
'click' : 'onClick',
|
||||
'click .bottom-bar': 'focusMessageField',
|
||||
'click .back': 'resetPanel',
|
||||
'click .microphone': 'captureAudio',
|
||||
'focus .send-message': 'focusBottomBar',
|
||||
'change .file-input': 'toggleMicrophone',
|
||||
'blur .send-message': 'unfocusBottomBar',
|
||||
'loadMore .message-list': 'fetchMessages',
|
||||
'close .menu': 'closeMenu',
|
||||
'select .message-list .entry': 'messageDetail',
|
||||
'force-resize': 'forceUpdateMessageFieldSize'
|
||||
},
|
||||
toggleMicrophone: function() {
|
||||
if (this.$('.send-message').val().length > 0 || this.fileInput.hasFiles()) {
|
||||
this.$('.capture-audio').hide();
|
||||
} else {
|
||||
this.$('.capture-audio').show();
|
||||
}
|
||||
},
|
||||
captureAudio: function(e) {
|
||||
e.preventDefault();
|
||||
var view = new Whisper.RecorderView().render();
|
||||
view.on('send', this.handleAudioCapture.bind(this));
|
||||
view.on('closed', this.endCaptureAudio.bind(this));
|
||||
view.$el.appendTo(this.$('.capture-audio'));
|
||||
this.$('.send-message').attr('disabled','disabled');
|
||||
this.$('.microphone').hide();
|
||||
},
|
||||
handleAudioCapture: function(blob) {
|
||||
this.fileInput.file = blob;
|
||||
this.fileInput.previewImages();
|
||||
this.$('.bottom-bar form').submit();
|
||||
},
|
||||
endCaptureAudio: function() {
|
||||
this.$('.send-message').removeAttr('disabled');
|
||||
this.$('.microphone').show();
|
||||
},
|
||||
|
||||
unfocusBottomBar: function() {
|
||||
this.$('.bottom-bar form').removeClass('active');
|
||||
|
@ -295,6 +322,7 @@
|
|||
event.preventDefault();
|
||||
return this.$('.bottom-bar form').submit();
|
||||
}
|
||||
this.toggleMicrophone();
|
||||
|
||||
this.view.measureScrollPosition();
|
||||
window.autosize(this.$messageField);
|
||||
|
|
|
@ -248,6 +248,7 @@
|
|||
this.$input.wrap('<form>').parent('form').trigger('reset');
|
||||
this.$input.unwrap();
|
||||
this.file = null;
|
||||
this.$input.trigger('change');
|
||||
},
|
||||
|
||||
openDropped: function(e) {
|
||||
|
|
|
@ -116,7 +116,7 @@
|
|||
restartSignal : i18n('restartSignal'),
|
||||
},
|
||||
events: {
|
||||
'click': 'closeMenu',
|
||||
'click': 'onClick',
|
||||
'click #header': 'focusHeader',
|
||||
'click .conversation': 'focusConversation',
|
||||
'click .global-menu .hamburger': 'toggleMenu',
|
||||
|
@ -173,12 +173,22 @@
|
|||
showLightbox: function(e) {
|
||||
this.$el.append(e.target);
|
||||
},
|
||||
closeRecording: function(e) {
|
||||
if (e && this.$(e.target).closest('.capture-audio').length > 0 ) {
|
||||
return;
|
||||
}
|
||||
this.$('.conversation:first .audio-capture').trigger('close');
|
||||
},
|
||||
closeMenu: function(e) {
|
||||
if (e && this.$(e.target).parent('.global-menu').length > 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$('.global-menu .menu-list').hide();
|
||||
},
|
||||
onClick: function(e) {
|
||||
this.closeMenu(e);
|
||||
this.closeRecording(e);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
74
js/views/recorder_view.js
Normal file
74
js/views/recorder_view.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* vim: ts=4:sw=4:expandtab
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
window.Whisper = window.Whisper || {};
|
||||
|
||||
Whisper.RecorderView = Whisper.View.extend({
|
||||
className: 'recorder clearfix',
|
||||
templateName: 'recorder',
|
||||
initialize: function() {
|
||||
this.startTime = Date.now();
|
||||
this.interval = setInterval(this.updateTime.bind(this), 1000);
|
||||
this.start();
|
||||
},
|
||||
events: {
|
||||
'click .close': 'close',
|
||||
'click .finish': 'finish',
|
||||
'close': 'close'
|
||||
},
|
||||
updateTime: function() {
|
||||
var duration = moment.duration(Date.now() - this.startTime, 'ms');
|
||||
var minutes = '' + Math.trunc(duration.asMinutes());
|
||||
var seconds = '' + duration.seconds();
|
||||
if (seconds.length < 2) {
|
||||
seconds = '0' + seconds;
|
||||
}
|
||||
this.$('.time').text(minutes + ':' + seconds);
|
||||
},
|
||||
close: function() {
|
||||
if (this.recorder.isRecording()) {
|
||||
this.recorder.cancelRecording();
|
||||
}
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
this.source.disconnect();
|
||||
if (this.context) {
|
||||
this.context.close().then(function() {
|
||||
console.log('audio context closed');
|
||||
});
|
||||
}
|
||||
this.remove();
|
||||
this.trigger('closed');
|
||||
},
|
||||
finish: function() {
|
||||
this.recorder.finishRecording();
|
||||
this.close();
|
||||
},
|
||||
handleBlob: function(recorder, blob) {
|
||||
if (blob) {
|
||||
this.trigger('send', blob);
|
||||
}
|
||||
},
|
||||
start: function() {
|
||||
this.context = new AudioContext();
|
||||
this.input = this.context.createGain();
|
||||
this.recorder = new WebAudioRecorder(this.input, {
|
||||
encoding: 'mp3',
|
||||
workerDir: 'js/' // must end with slash
|
||||
});
|
||||
this.recorder.onComplete = this.handleBlob.bind(this);
|
||||
this.recorder.onError = this.onError;
|
||||
navigator.webkitGetUserMedia({ audio: true }, function(stream) {
|
||||
this.source = this.context.createMediaStreamSource(stream);
|
||||
this.source.connect(this.input);
|
||||
}.bind(this), this.onError);
|
||||
this.recorder.startRecording();
|
||||
},
|
||||
onError: function(error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
})();
|
Loading…
Add table
Add a link
Reference in a new issue