From 36ecbfc87f6dec746aa5472d89321ec73beb4f81 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 8 Jul 2015 14:34:26 +0100 Subject: [PATCH] Upload files and images --- package.json | 1 + src/ContentMessages.js | 82 +++++++++++++++++++++++++++ src/controllers/organisms/RoomView.js | 36 ++++++++++-- 3 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 src/ContentMessages.js diff --git a/package.json b/package.json index ab6f8c41..8168a47d 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "classnames": "^2.1.2", "flux": "^2.0.3", "matrix-js-sdk": "0.1.1", + "q": "^1.4.1", "react": "^0.13.0", "react-loader": "^1.4.0" }, diff --git a/src/ContentMessages.js b/src/ContentMessages.js new file mode 100644 index 00000000..fdd29fd5 --- /dev/null +++ b/src/ContentMessages.js @@ -0,0 +1,82 @@ +/* +Copyright 2015 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +var q = require('q'); +var extend = require('./extend'); + +function infoForImageFile(imageFile) { + var deferred = q.defer(); + + // Load the file into an html element + var img = document.createElement("img"); + + var reader = new FileReader(); + reader.onload = function(e) { + img.src = e.target.result; + + // Once ready, returns its size + img.onload = function() { + deferred.resolve({ + w: img.width, + h: img.height + }); + }; + img.onerror = function(e) { + deferred.reject(e); + }; + }; + reader.onerror = function(e) { + deferred.reject(e); + }; + reader.readAsDataURL(imageFile); + + return deferred.promise; +} + +function sendContentToRoom(file, roomId, matrixClient) { + var content = { + body: file.name, + info: { + size: file.size, + mimetype: file.type + } + }; + + var def = q.defer(); + if (file.type.indexOf('image/') == 0) { + content.msgtype = 'm.image'; + infoForImageFile(file).then(function(imageInfo) { + extend(content.info, imageInfo); + def.resolve(); + }); + } else { + content.msgtype = 'm.file'; + def.resolve(); + } + + return def.promise.then(function() { + return matrixClient.uploadContent(file); + }).then(function(url) { + content.url = url; + return matrixClient.sendMessage(roomId, content); + }); +} + +module.exports = { + sendContentToRoom: sendContentToRoom +}; diff --git a/src/controllers/organisms/RoomView.js b/src/controllers/organisms/RoomView.js index cb8d1944..6049eee0 100644 --- a/src/controllers/organisms/RoomView.js +++ b/src/controllers/organisms/RoomView.js @@ -18,6 +18,8 @@ limitations under the License. var MatrixClientPeg = require("../../MatrixClientPeg"); var React = require("react"); +var q = require("q"); +var ContentMessages = require("../../ContentMessages"); var dis = require("../../dispatcher"); @@ -48,7 +50,7 @@ module.exports = { componentWillUnmount: function() { if (this.refs.messageWrapper) { var messageWrapper = this.refs.messageWrapper.getDOMNode(); - messageWrapper.removeEventListener('drop', this.handleDrop); + messageWrapper.removeEventListener('drop', this.onDrop); } dis.unregister(this.dispatcherRef); if (MatrixClientPeg.get()) { @@ -103,7 +105,8 @@ module.exports = { if (this.refs.messageWrapper) { var messageWrapper = this.refs.messageWrapper.getDOMNode(); - messageWrapper.addEventListener('drop', this.handleDrop); + messageWrapper.addEventListener('drop', this.onDrop); + messageWrapper.addEventListener('dragover', this.onDragOver); messageWrapper.scrollTop = messageWrapper.scrollHeight; @@ -186,11 +189,34 @@ module.exports = { if (!this.state.paginating) this.fillSpace(); }, - handleDrop: function(ev) { + onDragOver: function(ev) { ev.stopPropagation(); - var files = evt.dataTransfer.files; + ev.preventDefault(); - + ev.dataTransfer.dropEffect = 'none'; + + var items = ev.dataTransfer.items; + if (items.length == 1) { + if (items[0].kind == 'file') { + ev.dataTransfer.dropEffect = 'copy'; + } + } + }, + + onDrop: function(ev) { + ev.stopPropagation(); + ev.preventDefault(); + var files = ev.dataTransfer.files; + + if (files.length == 1) { + ContentMessages.sendContentToRoom( + files[0], this.props.roomId, MatrixClientPeg.get() + ).progress(function(ev) { + //console.log("Upload: "+ev.loaded+" / "+ev.total); + }).done(undefined, function() { + // display error message + }); + } }, getEventTiles: function() {