Basic frontend support for image attachments
This commit is contained in:
parent
d362d0d978
commit
229007040c
5 changed files with 76 additions and 6 deletions
|
@ -38,7 +38,9 @@
|
||||||
<div class='message-composer'>
|
<div class='message-composer'>
|
||||||
<form class='send'>
|
<form class='send'>
|
||||||
<input class='send-message' rows='6' type='textarea'>
|
<input class='send-message' rows='6' type='textarea'>
|
||||||
<div class='attachments'> Add Files </div>
|
<div class='attachments'>
|
||||||
|
<input type='file' name='files[]' multiple class='file-input'>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class='extension-details'>
|
<div class='extension-details'>
|
||||||
|
@ -143,6 +145,7 @@
|
||||||
|
|
||||||
<script type="text/javascript" src="js/chromium.js"></script>
|
<script type="text/javascript" src="js/chromium.js"></script>
|
||||||
<script type="text/javascript" src="js/views/notifications.js"></script>
|
<script type="text/javascript" src="js/views/notifications.js"></script>
|
||||||
|
<script type="text/javascript" src="js/views/file_input_view.js"></script>
|
||||||
<script type="text/javascript" src="js/views/list_view.js"></script>
|
<script type="text/javascript" src="js/views/list_view.js"></script>
|
||||||
<script type="text/javascript" src="js/views/message_view.js"></script>
|
<script type="text/javascript" src="js/views/message_view.js"></script>
|
||||||
<script type="text/javascript" src="js/views/message_list_view.js"></script>
|
<script type="text/javascript" src="js/views/message_list_view.js"></script>
|
||||||
|
|
|
@ -21,7 +21,7 @@ var Whisper = Whisper || {};
|
||||||
if (missing.length) { return "Thread must have " + missing; }
|
if (missing.length) { return "Thread must have " + missing; }
|
||||||
},
|
},
|
||||||
|
|
||||||
sendMessage: function(message) {
|
sendMessage: function(message, attachments) {
|
||||||
var timestamp = Date.now();
|
var timestamp = Date.now();
|
||||||
|
|
||||||
this.messages().add({ type: 'outgoing',
|
this.messages().add({ type: 'outgoing',
|
||||||
|
@ -34,10 +34,10 @@ var Whisper = Whisper || {};
|
||||||
active: true});
|
active: true});
|
||||||
|
|
||||||
if (this.get('type') == 'private') {
|
if (this.get('type') == 'private') {
|
||||||
var promise = textsecure.messaging.sendMessageToNumber(this.get('id'), message, []);
|
var promise = textsecure.messaging.sendMessageToNumber(this.get('id'), message, attachments)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var promise = textsecure.messaging.sendMessageToGroup(this.get('groupId'), message, []);
|
var promise = textsecure.messaging.sendMessageToGroup(this.get('groupId'), message, attachments);
|
||||||
}
|
}
|
||||||
promise.then(
|
promise.then(
|
||||||
function(result) {
|
function(result) {
|
||||||
|
|
|
@ -14,6 +14,8 @@ var Whisper = Whisper || {};
|
||||||
this.view = new Whisper.MessageListView({collection: this.model.messages()});
|
this.view = new Whisper.MessageListView({collection: this.model.messages()});
|
||||||
this.listenTo(this.model.messages(), 'add', this.scrollToBottom);
|
this.listenTo(this.model.messages(), 'add', this.scrollToBottom);
|
||||||
|
|
||||||
|
this.fileInput = new Whisper.FileInputView({el: this.$el.find('.attachments')});
|
||||||
|
|
||||||
this.model.messages().fetch({reset: true});
|
this.model.messages().fetch({reset: true});
|
||||||
this.$el.find('.discussion-container').append(this.view.el);
|
this.$el.find('.discussion-container').append(this.view.el);
|
||||||
window.addEventListener('storage', (function(){
|
window.addEventListener('storage', (function(){
|
||||||
|
@ -28,8 +30,13 @@ var Whisper = Whisper || {};
|
||||||
sendMessage: function(e) {
|
sendMessage: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var input = this.$el.find('.send input');
|
var input = this.$el.find('.send input');
|
||||||
if (input.val().length > 0) {
|
var message = input.val();
|
||||||
this.model.sendMessage(input.val());
|
var thread = this.model;
|
||||||
|
|
||||||
|
if (message.length > 0 || this.fileInput.hasFiles()) {
|
||||||
|
this.fileInput.getFiles().then(function(attachments) {
|
||||||
|
thread.sendMessage(message, attachments);
|
||||||
|
});
|
||||||
input.val("");
|
input.val("");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
55
js/views/file_input_view.js
Normal file
55
js/views/file_input_view.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
var Whisper = Whisper || {};
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
Whisper.FileInputView = Backbone.View.extend({
|
||||||
|
tagName: 'span',
|
||||||
|
className: 'file-input',
|
||||||
|
initialize: function() {
|
||||||
|
this.$input = this.$el.find('input[type=file]');
|
||||||
|
},
|
||||||
|
|
||||||
|
events: {
|
||||||
|
'change': 'previewImages'
|
||||||
|
},
|
||||||
|
|
||||||
|
addThumb: function(e) {
|
||||||
|
this.$el.append($('<img>').attr( "src", e.target.result ));
|
||||||
|
},
|
||||||
|
|
||||||
|
previewImages: function() {
|
||||||
|
this.$el.find('img').remove();
|
||||||
|
var files = this.$input.prop('files');
|
||||||
|
var onload = this.addThumb.bind(this);
|
||||||
|
for (var i = 0; i < files.length; i++) {
|
||||||
|
var FR = new FileReader();
|
||||||
|
FR.onload = onload;
|
||||||
|
FR.readAsDataURL(files[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
hasFiles: function() {
|
||||||
|
var files = this.$input.prop('files');
|
||||||
|
return files && files.length && files.length > 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
getFiles: function() {
|
||||||
|
var promises = [];
|
||||||
|
var files = this.$input.prop('files');
|
||||||
|
for (var i = 0; i < files.length; i++) {
|
||||||
|
var contentType = files[i].type;
|
||||||
|
var p = new Promise(function(resolve, reject) {
|
||||||
|
var FR = new FileReader();
|
||||||
|
FR.onload = function(e) {
|
||||||
|
resolve({data: e.target.result, contentType: contentType});
|
||||||
|
};
|
||||||
|
FR.readAsArrayBuffer(files[i]);
|
||||||
|
}.bind(this));
|
||||||
|
promises.push(p);
|
||||||
|
}
|
||||||
|
this.$el.find('img').remove();
|
||||||
|
return Promise.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
})();
|
|
@ -56,3 +56,8 @@ li.entry .avatar {
|
||||||
li.entry.outgoing .avatar {
|
li.entry.outgoing .avatar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.attachments img {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue