diff --git a/static/js/conversations.js b/static/js/conversations.js
index 223bf98..23946cd 100644
--- a/static/js/conversations.js
+++ b/static/js/conversations.js
@@ -1244,9 +1244,10 @@
handler: function() {
var html = state.quill.root.innerHTML;
var text = state.quill.getText().trim();
- if (text) {
+ var hasContent = text || html.indexOf('
+ state.quill.root.addEventListener('paste', function(e) {
+ var clipboardData = e.clipboardData || window.clipboardData;
+ if (!clipboardData || !clipboardData.items) return;
+ for (var i = 0; i < clipboardData.items.length; i++) {
+ var item = clipboardData.items[i];
+ if (item.type.indexOf('image') !== -1) {
+ e.preventDefault();
+ e.stopPropagation();
+ var file = item.getAsFile();
+ if (file) {
+ // Upload image as attachment
+ var fd = new FormData();
+ fd.append('image', file, 'pasted-image.png');
+ api('/api/messages/upload-image', 'POST', fd)
+ .then(function(result) {
+ if (result && result.url) {
+ var range = state.quill.getSelection(true);
+ state.quill.insertEmbed(range.index, 'image', result.url);
+ state.quill.setSelection(range.index + 1);
+ }
+ })
+ .catch(function(err) {
+ // Fallback: insert as base64
+ var reader = new FileReader();
+ reader.onload = function(ev) {
+ var range = state.quill.getSelection(true);
+ state.quill.insertEmbed(range.index, 'image', ev.target.result);
+ state.quill.setSelection(range.index + 1);
+ };
+ reader.readAsDataURL(file);
+ });
+ }
+ return;
+ }
+ }
+ });
+
// Typing indicator
state.quill.on('text-change', function () {
Composer.sendTyping();
diff --git a/templates/messages/conversations.html b/templates/messages/conversations.html
index f515826..5baa853 100644
--- a/templates/messages/conversations.html
+++ b/templates/messages/conversations.html
@@ -10,6 +10,23 @@