diff --git a/index.html b/index.html index 3653670a..5db22d9a 100644 --- a/index.html +++ b/index.html @@ -38,7 +38,9 @@
-
Add Files
+
+ +
@@ -143,6 +145,7 @@ + diff --git a/js/models/threads.js b/js/models/threads.js index 090f34b7..ac40d307 100644 --- a/js/models/threads.js +++ b/js/models/threads.js @@ -21,7 +21,7 @@ var Whisper = Whisper || {}; if (missing.length) { return "Thread must have " + missing; } }, - sendMessage: function(message) { + sendMessage: function(message, attachments) { var timestamp = Date.now(); this.messages().add({ type: 'outgoing', @@ -34,10 +34,10 @@ var Whisper = Whisper || {}; active: true}); 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 { - var promise = textsecure.messaging.sendMessageToGroup(this.get('groupId'), message, []); + var promise = textsecure.messaging.sendMessageToGroup(this.get('groupId'), message, attachments); } promise.then( function(result) { diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 9dd5bd7b..fa746c3f 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -14,6 +14,8 @@ var Whisper = Whisper || {}; this.view = new Whisper.MessageListView({collection: this.model.messages()}); 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.$el.find('.discussion-container').append(this.view.el); window.addEventListener('storage', (function(){ @@ -28,8 +30,13 @@ var Whisper = Whisper || {}; sendMessage: function(e) { e.preventDefault(); var input = this.$el.find('.send input'); - if (input.val().length > 0) { - this.model.sendMessage(input.val()); + var message = 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(""); } }, diff --git a/js/views/file_input_view.js b/js/views/file_input_view.js new file mode 100644 index 00000000..824d072b --- /dev/null +++ b/js/views/file_input_view.js @@ -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($('').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); + } + + }); +})(); diff --git a/stylesheets/index.css b/stylesheets/index.css index 1de2cb07..803486d8 100644 --- a/stylesheets/index.css +++ b/stylesheets/index.css @@ -56,3 +56,8 @@ li.entry .avatar { li.entry.outgoing .avatar { display: none; } + +.attachments img { + width: 30px; + height: 30px; +}