diff --git a/index.html b/index.html
index 3653670a..5db22d9a 100644
--- a/index.html
+++ b/index.html
@@ -38,7 +38,9 @@
@@ -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;
+}