From fa8074965814d371ad38fa5eaf005301e2f79092 Mon Sep 17 00:00:00 2001 From: worlword Date: Wed, 11 Apr 2018 15:29:41 +0200 Subject: [PATCH] refactoring based on the review from jcbrand 06.Apr.2018 --- spec/http-file-upload.js | 1 + src/build.js | 2 +- src/config.js | 2 +- src/converse-chatboxes.js | 121 +++++++++++++- src/converse-chatview.js | 36 ++--- src/converse-core.js | 2 +- src/converse-http-file-upload.js | 35 ++++ src/converse-httpFileUpload.js | 269 ------------------------------- src/converse-muc-views.js | 15 +- src/converse-muc.js | 12 ++ src/converse.js | 2 +- src/inverse.js | 2 +- tests/runner-transpiled.js | 2 +- 13 files changed, 182 insertions(+), 319 deletions(-) create mode 100644 src/converse-http-file-upload.js delete mode 100644 src/converse-httpFileUpload.js diff --git a/spec/http-file-upload.js b/spec/http-file-upload.js index e17866c18..3541f8f4f 100644 --- a/spec/http-file-upload.js +++ b/spec/http-file-upload.js @@ -158,6 +158,7 @@ expect(entities.get('localhost').items.get('upload.localhost').identities.where({'category': 'store'}).length).toBe(1); _converse.api.disco.supports(Strophe.NS.HTTPUPLOAD, _converse.domain).then( function (result) { + console.log("in the test the service is supported"); expect(result.length).toBe(1); expect(result[0].get('jid')).toBe('upload.localhost'); done(); diff --git a/src/build.js b/src/build.js index a2a1f3b4f..8aab2a903 100644 --- a/src/build.js +++ b/src/build.js @@ -13,7 +13,7 @@ "converse-dragresize": "builds/converse-dragresize", "converse-fullscreen": "builds/converse-fullscreen", "converse-headline": "builds/converse-headline", - "converse-httpFileUpload": "builds/converse-httpFileUpload", + "converse-http-file-upload":"builds/converse-http-file-upload", "converse-mam": "builds/converse-mam", "converse-minimize": "builds/converse-minimize", "converse-modal": "builds/converse-modal", diff --git a/src/config.js b/src/config.js index 96758d97e..18f4073fa 100644 --- a/src/config.js +++ b/src/config.js @@ -74,7 +74,7 @@ require.config({ "converse-dragresize": "src/converse-dragresize", "converse-fullscreen": "src/converse-fullscreen", "converse-headline": "src/converse-headline", - "converse-httpFileUpload": "src/converse-httpFileUpload", + "converse-http-file-upload":"src/converse-http-file-upload", "converse-mam": "src/converse-mam", "converse-minimize": "src/converse-minimize", "converse-modal": "src/converse-modal", diff --git a/src/converse-chatboxes.js b/src/converse-chatboxes.js index 3a0457a0f..9eff30d6a 100644 --- a/src/converse-chatboxes.js +++ b/src/converse-chatboxes.js @@ -15,8 +15,8 @@ }(this, function (converse, tpl_chatboxes) { "use strict"; - const { Backbone, Promise, Strophe, b64_sha1, moment, utils, _ } = converse.env; - + const { $msg, Backbone, Promise, Strophe, b64_sha1, moment, utils, _ } = converse.env; + Strophe.addNamespace('OUTOFBAND', 'jabber:x:oob'); converse.plugins.add('converse-chatboxes', { @@ -50,7 +50,8 @@ /* The initialize function gets called as soon as the plugin is * loaded by converse.js's plugin machinery. */ - const { _converse } = this; + const { _converse } = this, + { __ } = _converse; _converse.api.promises.add([ 'chatBoxesFetched', @@ -115,6 +116,120 @@ }); }, + createFileMessageStanza(message, to){ + const stanza = $msg({ + 'from': _converse.connection.jid, + 'to': to, + 'type': 'chat', + 'id': message.get('msgid') + }).c('body').t(message.get('message')).up() + .c(_converse.ACTIVE, {'xmlns': Strophe.NS.CHATSTATES}).up() + .c('x', {'xmlns': Strophe.NS.OUTOFBAND}).c('url').t(message.get('message')).up(); + + return stanza; + }, + + sendFile (file, chatbox) { + const self = this; + console.log('Send file via http upload'); + const request_slot_url = 'upload.' + _converse.domain; + _converse.api.disco.supports(Strophe.NS.HTTPUPLOAD, request_slot_url) + .then((result) => { + chatbox.showHelpMessages([__('The file upload starts now')],'info'); + self.requestSlot(file, request_slot_url, function(data) { + if (!data) { + // general error + console.log('Unknown error while requesting upload slot.'); + alert(__('File upload failed. Please check the log.')); + } else if (data.error) { + // specific error + console.log('The XMPP-Server return an error of the type: ' + data.error.type); + alert(__('File upload failed. Please check the log.')); + } else if (data.get && data.put) { + console.log('slot received, start upload to ' + data.put); + self.uploadFile(data.put, file, function() { + console.log(data.put); + chatbox.onMessageSubmitted(data.put, null, file); + }); + } + }); + }); + }, + + requestSlot (file, request_slot_url, cb) { + const self = this; + console.log("try sending file to: " + request_slot_url); + const iq = converse.env.$iq({ + to: request_slot_url, + type: 'get' + }).c('request', { + xmlns: Strophe.NS.HTTPUPLOAD + }).c('filename').t(file.name) + .up() + .c('size').t(file.size); + + _converse.connection.sendIQ(iq, function(stanza) { + self.successfulRequestSlotCB(stanza, cb); + }, function(stanza) { + self.failedRequestSlotCB(stanza, cb); + }); + }, + + /** + * Upload the given file to the given url. + */ + uploadFile (url, file, success_cb) { + console.log("uploadFile start"); + const xmlhttp = new XMLHttpRequest(); + const contentType = 'application/octet-stream'; + xmlhttp.onreadystatechange = function() { + if (xmlhttp.readyState === XMLHttpRequest.DONE) { + console.log("Status: " + xmlhttp.status); + if (xmlhttp.status === 200 || xmlhttp.status === 201) { + console.log('file successful uploaded'); + if (success_cb) { + success_cb(); + } + } + else { + console.log('error while uploading file to ' + url); + alert(__('Could not upload File please try again.')); + } + } + }; + + xmlhttp.open('PUT', url, true); + xmlhttp.setRequestHeader("Content-type", contentType); + xmlhttp.send(file); + + console.log("uploadFile end"); + }, + + /** + * Process successful response to slot request. + */ + successfulRequestSlotCB (stanza, cb) { + const slot = stanza.getElementsByTagName('slot')[0]; + + if (slot != undefined) { + var put = slot.getElementsByTagName('put')[0].textContent; + var get = slot.getElementsByTagName('get')[0].textContent; + cb({ + put: put, + get: get + }); + } else { + this.failedRequestSlotCB(stanza, cb); + } + }, + + /** + * Process failed response to slot request. + */ + failedRequestSlotCB (stanza, cb) { + alert(__('Could not upload File please try again.')); + }, + getMessageBody (message) { const type = message.getAttribute('type'); return (type === 'error') ? diff --git a/src/converse-chatview.js b/src/converse-chatview.js index 344e9b54f..7b8b79746 100644 --- a/src/converse-chatview.js +++ b/src/converse-chatview.js @@ -25,7 +25,7 @@ "tpl!spoiler_button", "tpl!spoiler_message", "tpl!toolbar", - "converse-httpFileUpload", + "converse-http-file-upload", "converse-chatboxes" ], factory); }(this, function ( @@ -56,8 +56,6 @@ FORWARD_SLASH: 47 }; - Strophe.addNamespace('OUTOFBAND', 'jabber:x:oob'); - converse.plugins.add('converse-chatview', { /* Plugin dependencies are other plugins which might be * overridden or relied upon, and therefore need to be loaded before @@ -236,7 +234,6 @@ } }); - _converse.ChatBoxView = Backbone.NativeView.extend({ length: 200, className: 'chatbox hidden', @@ -257,17 +254,14 @@ 'change .fileUpload_input': 'handleFileSelect' }, - toggleFileUpload(ev) { - _converse.FileUpload.prototype.initFiletransfer(_converse.connection); - var uploadDialog = this.el.querySelector('.fileUpload_input'); - uploadDialog.click(); + toggleFileUpload (ev) { + this.el.querySelector('.fileUpload_input').click(); }, - handleFileSelect(evt) { + handleFileSelect (evt) { var files = evt.target.files; var file = files[0]; - var jid = this.jid; - _converse.FileUpload.prototype.setFile(file,this); + this.model.sendFile(file, this); }, initialize () { @@ -662,9 +656,9 @@ this.renderSpoilerMessage(msg, attrs) } - if(msg_content.textContent.endsWith('mp4')){ + if (msg_content.textContent.endsWith('mp4')) { msg_content.innerHTML = u.renderMovieURLs(msg_content); - } else if(msg_content.textContent.endsWith('mp3')){ + } else if (msg_content.textContent.endsWith('mp3')) { msg_content.innerHTML = u.renderAudioURLs(msg_content); } else { u.renderImageURLs(msg_content).then(this.scrollDown.bind(this)); @@ -800,18 +794,7 @@ return stanza; }, - createFileMessageStanza(message){ - const stanza = $msg({ - 'from': _converse.connection.jid, - 'to': this.model.get('jid'), - 'type': 'chat', - 'id': message.get('msgid') - }).c('body').t(message.get('message')).up() - .c(_converse.ACTIVE, {'xmlns': Strophe.NS.CHATSTATES}).up() - .c('x', {'xmlns': Strophe.NS.OUTOFBAND}).c('url').t(message.get('message')).up(); - return stanza; - }, sendMessage (message, file=null) { /* Responsible for sending off a text message. @@ -823,7 +806,7 @@ // Especially in the OTR case. var messageStanza; if(file !== null){ - messageStanza = this.createFileMessageStanza(message); + messageStanza = this.createFileMessageStanza(message, this.model.get('jid')); } else { messageStanza = this.createMessageStanza(message); @@ -883,8 +866,7 @@ } const attrs = this.getOutgoingMessageAttributes(text, spoiler_hint); const message = this.model.messages.create(attrs); - - /* check, if a file was send. If true it will send the file with XEP-0066. */ + this.sendMessage(message, file); }, diff --git a/src/converse-core.js b/src/converse-core.js index a3a95a358..2e827918f 100644 --- a/src/converse-core.js +++ b/src/converse-core.js @@ -78,7 +78,7 @@ 'converse-dropdown', 'converse-fullscreen', 'converse-headline', - 'converse-httpFileUpload', + 'converse-http-file-upload', 'converse-mam', 'converse-minimize', 'converse-modal', diff --git a/src/converse-http-file-upload.js b/src/converse-http-file-upload.js new file mode 100644 index 000000000..34fdf1272 --- /dev/null +++ b/src/converse-http-file-upload.js @@ -0,0 +1,35 @@ +/** + * Adds Support for Http File Upload (XEP-0363) + * + * @see {@link http://xmpp.org/extensions/xep-0363.html} + */ +(function (root, factory) { + define([ + "converse-core", + ], factory); +}(this, function ( + converse + ) { + "use strict"; + const { $msg, Backbone, Strophe, _, b64_sha1, moment, utils } = converse.env; + Strophe.addNamespace('HTTPUPLOAD', 'urn:xmpp:http:upload'); + + converse.plugins.add('converse-http-file-upload', { + + dependencies: ["converse-chatboxes", "converse-chatview"], + + initialize () { + const { _converse } = this, + { __ } = _converse; + + _converse.FileUpload = Backbone.NativeView.extend({ + /** + * Request upload slot from xmpp-server + */ + + }) + } + }); + + return converse; +})); diff --git a/src/converse-httpFileUpload.js b/src/converse-httpFileUpload.js deleted file mode 100644 index 0ea3ed982..000000000 --- a/src/converse-httpFileUpload.js +++ /dev/null @@ -1,269 +0,0 @@ -/* - The MIT License (MIT) - - Copyright (c) 2014 Klaus Herberth - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/** - * Implements Http File Upload (XEP-0363) - * - * @see {@link http://xmpp.org/extensions/xep-0363.html} - */ -(function (root, factory) { - define([ - "converse-core", - ], factory); -}(this, function ( - converse - ) { - "use strict"; - const { $msg, Backbone, Strophe, _, b64_sha1, moment, utils } = converse.env; - - Strophe.addNamespace('HTTPUPLOAD', 'urn:xmpp:http:upload'); - - var requestSlotUrl; - var ready; - var httpUploadOption = { - enable: true - } - - converse.plugins.add('converse-httpFileUpload', { - - dependencies: ["converse-chatboxes", "converse-disco"], - - initialize() { - const { _converse } = this, - { __ } = _converse; - var connection = _converse.connection; - var domain; - var file; - var chatBox; - - _converse.FileUpload = Backbone.NativeView.extend({ - /** - * Set up http file upload. - * - * @param {*} connection the current strophe-connection - */ - initFiletransfer () { - connection = _converse.connection; - domain = _converse.connection.domain; - - if (httpUploadOption && requestSlotUrl != undefined) { - ready = true; - return; - } - this.discoverUploadService(); - }, - - /** - * Discover upload service for http upload. - * - */ - discoverUploadService () { - var self = this; - console.log('discover http upload service'); - connection.disco.items(domain, null, function(items) { - var childs = items.getElementsByTagName('item'); - for(var i = 0; i < childs.length; i++){ - var jid = childs[i].attributes.jid.value; - if (ready) { - // abort, because we already found a service - return false; - } - self.queryItemForUploadService(jid); - } - }); - }, - - /** - * Query item for upload service. - * - * @param {String} jid of the logged-in user - * @param {Function} cb Callback on success - */ - queryItemForUploadService (jid) { - var self = this; - console.log('query ' + jid + ' for upload service'); - - connection.disco.info(jid, null, function(info) { - var httpUploadFeature; - var temp = info.getElementsByTagName('feature'); - for(var i = 0; i < temp.length; i++){ - var feature = temp[i].attributes.var; - if(feature != undefined && feature.value === Strophe.NS.HTTPUPLOAD){ - requestSlotUrl = jid; - ready = true; - self.sendFile(); - } - } - }); - }, - - /** - * Saves the file the user has picked. - * - * @param {*} file the name of the file the user has picked. - * @param {*} chatBox the chatbox from which the user initiated the file-upload - */ - setFile (file1, chatBox1){ - file = file1; - chatBox = chatBox1; - this.sendFile(); - }, - - /** - * Upload file. - * Waits till the Upload-Service is discovered and till the user has picked a file. - * - */ - sendFile () { - var self = this; - if(file === undefined){ - console.log("waiting to choose a file"); - return; - } - else if(requestSlotUrl === undefined){ - console.log("waiting for service discovery"); - return; - } - - console.log('Send file via http upload'); - chatBox.showHelpMessages([__('The file upload starts now')],'info'); - this.requestSlot(file, function(data) { - if (!data) { - // general error - console.log('Unknown error while requesting upload slot.'); - alert(__('File upload failed. Please check the log.')); - } else if (data.error) { - // specific error - console.log('The XMPP-Server return an error of the type: ' + data.error.type); - alert(__('File upload failed. Please check the log.')); - } else if (data.get && data.put) { - console.log('slot received, start upload to ' + data.put); - self.uploadFile(data.put, file, function() { - console.log(data.put); - - chatBox.onMessageSubmitted(data.put, null, file); - file = undefined; - }); - } - }); - }, - - /** - * Request upload slot from xmpp-server - * - * @param {File} file the file the user picked - * @param {Function} cb Callback after finished request - */ - requestSlot (file, cb) { - var self = this; - console.log("try sending file to: " + requestSlotUrl); - var iq = converse.env.$iq({ - to: requestSlotUrl, - type: 'get' - }).c('request', { - xmlns: Strophe.NS.HTTPUPLOAD - }).c('filename').t(file.name) - .up() - .c('size').t(file.size); - - connection.sendIQ(iq, function(stanza) { - self.successfulRequestSlotCB(stanza, cb); - }, function(stanza) { - self.failedRequestSlotCB(stanza, cb); - }); - }, - - /** - * Upload the given file to the given url. - * - * @param {String} url upload url - * @param {File} file the file the user picked - * @param {Function} success_cb callback on successful transition - */ - uploadFile (url, file, success_cb) { - console.log("uploadFile start"); - var xmlhttp = new XMLHttpRequest(); - var type = 'PUT'; - var contentType = 'application/octet-stream'; - var data = file; - var processData = false; - xmlhttp.onreadystatechange = function() { - if (xmlhttp.readyState == XMLHttpRequest.DONE) { - console.log("Status: " + xmlhttp.status); - if (xmlhttp.status == 200 || xmlhttp.status == 201) { - console.log('file successful uploaded'); - if (success_cb) { - success_cb(); - } - } - else { - console.log('error while uploading file to ' + url); - alert(__('Could not upload File please try again.')); - } - } - }; - - xmlhttp.open(type, url, true); - xmlhttp.setRequestHeader("Content-type", contentType); - xmlhttp.send(data); - - console.log("uploadFile end"); - }, - - /** - * Process successful response to slot request. - * - * @param {String} stanza - * @param {Function} cb - */ - successfulRequestSlotCB (stanza, cb) { - var slot = stanza.getElementsByTagName('slot')[0]; - - if (slot != undefined) { - var put = slot.getElementsByTagName('put')[0].textContent; - var get = slot.getElementsByTagName('get')[0].textContent; - cb({ - put: put, - get: get - }); - } else { - this.failedRequestSlotCB(stanza, cb); - } - }, - - /** - * Process failed response to slot request. - * - * @param {String} stanza - * @param {Function} cb - */ - failedRequestSlotCB (stanza, cb) { - chatBox.showHelpMessages([__('Fileupload failed')],'info'); - } - }) - } - }); - - return converse; -})); diff --git a/src/converse-muc-views.js b/src/converse-muc-views.js index d70385a57..dc5f13700 100644 --- a/src/converse-muc-views.js +++ b/src/converse-muc-views.js @@ -82,8 +82,6 @@ 'unmoderated': 'moderated' }; - Strophe.addNamespace('OUTOFBAND', 'jabber:x:oob'); - converse.plugins.add('converse-muc-views', { /* Dependencies are other plugins which might be * overridden or relied upon, and therefore need to be loaded before @@ -697,17 +695,6 @@ msgid }); }, - sendChatRoomFile (text) { - const msgid = _converse.connection.getUniqueId(); - const stanza = $msg({ - 'from': _converse.connection.jid, - 'to': this.model.get('jid'), - 'type': 'groupchat', - 'id': msgid - }).c("body").t(text).up() - .c("x", {'xmlns': Strophe.NS.OUTOFBAND}).c('url').t(text).up(); - _converse.connection.send(stanza); - }, modifyRole(room, nick, role, reason, onSuccess, onError) { const item = $build("item", {nick, role}); @@ -757,7 +744,7 @@ * (String) text - The message text. */ if(file !== null){ - return this.sendChatRoomFile(text); + return this.model.sendChatRoomFile(text,this.model.get('jid')); } if (_converse.muc_disable_moderator_commands) { return this.sendChatRoomMessage(text); diff --git a/src/converse-muc.js b/src/converse-muc.js index 0265b1770..feaf4c1a7 100644 --- a/src/converse-muc.js +++ b/src/converse-muc.js @@ -275,6 +275,18 @@ ); }, + sendChatRoomFile (text, to) { + const msgid = _converse.connection.getUniqueId(); + const stanza = $msg({ + 'from': _converse.connection.jid, + 'to': to, + 'type': 'groupchat', + 'id': msgid + }).c("body").t(text).up() + .c("x", {'xmlns': Strophe.NS.OUTOFBAND}).c('url').t(text).up(); + _converse.connection.send(stanza); + }, + directInvite (recipient, reason) { /* Send a direct invitation as per XEP-0249 * diff --git a/src/converse.js b/src/converse.js index 6c8a48ee2..4aeae0c52 100644 --- a/src/converse.js +++ b/src/converse.js @@ -24,7 +24,7 @@ if (typeof define !== 'undefined') { "converse-minimize", // Allows chat boxes to be minimized "converse-dragresize", // Allows chat boxes to be resized by dragging them "converse-headline", // Support for headline messages - "converse-httpFileUpload", // Support for XEP-0363 + "converse-http-file-upload", // Support for XEP-0363 "converse-fullscreen" /* END: Removable components */ ], function (converse) { diff --git a/src/inverse.js b/src/inverse.js index 6ead412e9..8ee2c8136 100644 --- a/src/inverse.js +++ b/src/inverse.js @@ -25,7 +25,7 @@ if (typeof define !== 'undefined') { "converse-register", // XEP-0077 In-band registration "converse-roomslist", // Show currently open chat rooms "converse-vcard", // XEP-0054 VCard-temp - "converse-httpFileUpload", // Support for XEP-0363 + "converse-http-file-upload", // Support for XEP-0363 /* END: Removable components */ "converse-inverse", // Inverse plugin for converse.js diff --git a/tests/runner-transpiled.js b/tests/runner-transpiled.js index 06d4cb0fa..8faaebb6e 100644 --- a/tests/runner-transpiled.js +++ b/tests/runner-transpiled.js @@ -24,7 +24,7 @@ config.paths["converse-core"] = "builds/converse-core"; config.paths["converse-disco"] = "builds/converse-disco"; config.paths["converse-dragresize"] = "builds/converse-dragresize"; config.paths["converse-headline"] = "builds/converse-headline"; -config.paths["converse-httpFileUpload"]="builds/converse-httpFileUpload"; +config.paths["converse-http-file-upload"]="builds/converse-http-file-upload"; config.paths["converse-fullscreen"] = "builds/converse-fullscreen"; config.paths["converse-mam"] = "builds/converse-mam"; config.paths["converse-minimize"] = "builds/converse-minimize";