diff --git a/synctl b/synctl new file mode 120000 index 0000000000..1bdceda20a --- /dev/null +++ b/synctl @@ -0,0 +1 @@ +./synapse/app/synctl.py \ No newline at end of file diff --git a/syweb/webclient/app.css b/syweb/webclient/app.css index 25f7208a11..1264ac787c 100755 --- a/syweb/webclient/app.css +++ b/syweb/webclient/app.css @@ -699,7 +699,7 @@ textarea, input { vertical-align: middle; */ display: inline-block; - max-width: 90%; + max-width: 80%; padding-left: 1em; padding-right: 1em; padding-top: 2px; @@ -721,6 +721,7 @@ textarea, input { text-align: right; } +/* .text.emote .bubble, .text.membership .bubble, .mine .text.emote .bubble, @@ -729,6 +730,7 @@ textarea, input { background-color: transparent ! important; border: 0px ! important; } +*/ .mine .text .bubble { /* diff --git a/syweb/webclient/components/fileInput/file-input-directive.js b/syweb/webclient/components/fileInput/file-input-directive.js index 9c849a140f..e530c06085 100644 --- a/syweb/webclient/components/fileInput/file-input-directive.js +++ b/syweb/webclient/components/fileInput/file-input-directive.js @@ -25,7 +25,8 @@ angular.module('mFileInput', []) return { restrict: 'A', transclude: 'true', - template: '
', + // FIXME: add back in accept="image/*" when needed - e.g. for avatars + template: '', scope: { selectedFile: '=mFileInput' }, diff --git a/syweb/webclient/components/fileUpload/file-upload-service.js b/syweb/webclient/components/fileUpload/file-upload-service.js index b544e29509..9a67096c5f 100644 --- a/syweb/webclient/components/fileUpload/file-upload-service.js +++ b/syweb/webclient/components/fileUpload/file-upload-service.js @@ -47,30 +47,31 @@ angular.module('mFileUpload', ['matrixService', 'mUtilities']) }; /* - * Upload an image file plus generate a thumbnail of it and upload it so that - * we will have all information to fulfill an image message request data. - * @param {File} imageFile the imageFile to send + * Upload an file plus generate a thumbnail of it (if possible) and upload it so that + * we will have all information to fulfill an file/image message request + * @param {File} file the file to send * @param {Integer} thumbnailSize the max side size of the thumbnail to create - * @returns {promise} A promise that will be resolved by a image message object + * @returns {promise} A promise that will be resolved by a message object * ready to be send with the Matrix API */ - this.uploadImageAndThumbnail = function(imageFile, thumbnailSize) { + this.uploadFileAndThumbnail = function(file, thumbnailSize) { var self = this; var deferred = $q.defer(); - console.log("uploadImageAndThumbnail " + imageFile.name + " - thumbnailSize: " + thumbnailSize); + console.log("uploadFileAndThumbnail " + file.name + " - thumbnailSize: " + thumbnailSize); - // The message structure that will be returned in the promise - var imageMessage = { + // The message structure that will be returned in the promise will look something like: + var message = { +/* msgtype: "m.image", url: undefined, body: "Image", info: { size: undefined, - w: undefined, - h: undefined, + w: undefined, + h: undefined, mimetype: undefined - }, + }, thumbnail_url: undefined, thumbnail_info: { size: undefined, @@ -78,101 +79,128 @@ angular.module('mFileUpload', ['matrixService', 'mUtilities']) h: undefined, mimetype: undefined } +*/ }; - // First, get the image size - mUtilities.getImageSize(imageFile).then( - function(size) { - console.log("image size: " + JSON.stringify(size)); + if (file.type.indexOf("image/") === 0) { + // it's an image - try to do clientside thumbnailing. + mUtilities.getImageSize(file).then( + function(size) { + console.log("image size: " + JSON.stringify(size)); - // The final operation: send imageFile - var uploadImage = function() { - self.uploadFile(imageFile).then( - function(url) { - // Update message metadata - imageMessage.url = url; - imageMessage.info = { - size: imageFile.size, - w: size.width, - h: size.height, - mimetype: imageFile.type - }; + // The final operation: send file + var uploadImage = function() { + self.uploadFile(file).then( + function(url) { + // Update message metadata + message.url = url; + message.msgtype = "m.image"; + message.body = file.name; + message.info = { + size: file.size, + w: size.width, + h: size.height, + mimetype: file.type + }; - // If there is no thumbnail (because the original image is smaller than thumbnailSize), - // reuse the original image info for thumbnail data - if (!imageMessage.thumbnail_url) { - imageMessage.thumbnail_url = imageMessage.url; - imageMessage.thumbnail_info = imageMessage.info; - } - - // We are done - deferred.resolve(imageMessage); - }, - function(error) { - console.log(" -> Can't upload image"); - deferred.reject(error); - } - ); - }; - - // Create a thumbnail if the image size exceeds thumbnailSize - if (Math.max(size.width, size.height) > thumbnailSize) { - console.log(" Creating thumbnail..."); - mUtilities.resizeImage(imageFile, thumbnailSize).then( - function(thumbnailBlob) { - - // Get its size - mUtilities.getImageSize(thumbnailBlob).then( - function(thumbnailSize) { - console.log(" -> Thumbnail size: " + JSON.stringify(thumbnailSize)); - - // Upload it to the server - self.uploadFile(thumbnailBlob).then( - function(thumbnailUrl) { - - // Update image message data - imageMessage.thumbnail_url = thumbnailUrl; - imageMessage.thumbnail_info = { - size: thumbnailBlob.size, - w: thumbnailSize.width, - h: thumbnailSize.height, - mimetype: thumbnailBlob.type - }; - - // Then, upload the original image - uploadImage(); - }, - function(error) { - console.log(" -> Can't upload thumbnail"); - deferred.reject(error); - } - ); - }, - function(error) { - console.log(" -> Failed to get thumbnail size"); - deferred.reject(error); + // If there is no thumbnail (because the original image is smaller than thumbnailSize), + // reuse the original image info for thumbnail data + if (!message.thumbnail_url) { + message.thumbnail_url = message.url; + message.thumbnail_info = message.info; } - ); - }, - function(error) { - console.log(" -> Failed to create thumbnail: " + error); - deferred.reject(error); - } - ); - } - else { - // No need of thumbnail - console.log(" Thumbnail is not required"); - uploadImage(); - } + // We are done + deferred.resolve(message); + }, + function(error) { + console.log(" -> Can't upload image"); + deferred.reject(error); + } + ); + }; - }, - function(error) { - console.log(" -> Failed to get image size"); - deferred.reject(error); - } - ); + // Create a thumbnail if the image size exceeds thumbnailSize + if (Math.max(size.width, size.height) > thumbnailSize) { + console.log(" Creating thumbnail..."); + mUtilities.resizeImage(file, thumbnailSize).then( + function(thumbnailBlob) { + + // Get its size + mUtilities.getImageSize(thumbnailBlob).then( + function(thumbnailSize) { + console.log(" -> Thumbnail size: " + JSON.stringify(thumbnailSize)); + + // Upload it to the server + self.uploadFile(thumbnailBlob).then( + function(thumbnailUrl) { + + // Update image message data + message.thumbnail_url = thumbnailUrl; + message.thumbnail_info = { + size: thumbnailBlob.size, + w: thumbnailSize.width, + h: thumbnailSize.height, + mimetype: thumbnailBlob.type + }; + + // Then, upload the original image + uploadImage(); + }, + function(error) { + console.log(" -> Can't upload thumbnail"); + deferred.reject(error); + } + ); + }, + function(error) { + console.log(" -> Failed to get thumbnail size"); + deferred.reject(error); + } + ); + + }, + function(error) { + console.log(" -> Failed to create thumbnail: " + error); + deferred.reject(error); + } + ); + } + else { + // No need of thumbnail + console.log(" Thumbnail is not required"); + uploadImage(); + } + + }, + function(error) { + console.log(" -> Failed to get image size"); + deferred.reject(error); + } + ); + } + else { + // it's a random file - just upload it. + self.uploadFile(file).then( + function(url) { + // Update message metadata + message.url = url; + message.msgtype = "m.file"; + message.body = file.name; + message.info = { + size: file.size, + mimetype: file.type + }; + + // We are done + deferred.resolve(message); + }, + function(error) { + console.log(" -> Can't upload file"); + deferred.reject(error); + } + ); + } return deferred.promise; }; diff --git a/syweb/webclient/components/matrix/event-handler-service.js b/syweb/webclient/components/matrix/event-handler-service.js index 8a32d06696..20ed89f161 100644 --- a/syweb/webclient/components/matrix/event-handler-service.js +++ b/syweb/webclient/components/matrix/event-handler-service.js @@ -501,51 +501,7 @@ function(matrixService, $rootScope, $q, $timeout, $filter, mPresence, notificati eventContainsBingWord: function(event) { return containsBingWord(event); - }, - - /** - * Return the last message event of a room - * @param {String} room_id the room id - * @param {Boolean} filterFake true to not take into account fake messages - * @returns {undefined | Event} the last message event if available - */ - getLastMessage: function(room_id, filterEcho) { - var lastMessage; - - var events = modelService.getRoom(room_id).events; - for (var i = events.length - 1; i >= 0; i--) { - var message = events[i]; - - if (!filterEcho || undefined === message.echo_msg_state) { - lastMessage = message; - break; - } - } - - return lastMessage; - }, - - /** - * Compute the room users number, ie the number of members who has joined the room. - * @param {String} room_id the room id - * @returns {undefined | Number} the room users number if available - */ - getUsersCountInRoom: function(room_id) { - var memberCount; - - var room = modelService.getRoom(room_id); - memberCount = 0; - for (var i in room.current_room_state.members) { - if (!room.current_room_state.members.hasOwnProperty(i)) continue; - - var member = room.current_room_state.members[i].event; - - if ("join" === member.content.membership) { - memberCount = memberCount + 1; - } - } - - return memberCount; } + }; }]); diff --git a/syweb/webclient/components/matrix/model-service.js b/syweb/webclient/components/matrix/model-service.js index b4d59e7324..d34981a9ff 100644 --- a/syweb/webclient/components/matrix/model-service.js +++ b/syweb/webclient/components/matrix/model-service.js @@ -284,6 +284,52 @@ angular.module('modelService', []) } } return powerLevel; + }, + + /** + * Compute the room users number, ie the number of members who has joined the room. + * @param {String} room_id the room id + * @returns {undefined | Number} the room users number if available + */ + getUserCountInRoom: function(room_id) { + var memberCount; + + var room = this.getRoom(room_id); + memberCount = 0; + for (var i in room.current_room_state.members) { + if (!room.current_room_state.members.hasOwnProperty(i)) continue; + + var member = room.current_room_state.members[i].event; + + if ("join" === member.content.membership) { + memberCount = memberCount + 1; + } + } + + return memberCount; + }, + + /** + * Return the last message event of a room + * @param {String} room_id the room id + * @param {Boolean} filterFake true to not take into account fake messages + * @returns {undefined | Event} the last message event if available + */ + getLastMessage: function(room_id, filterEcho) { + var lastMessage; + + var events = this.getRoom(room_id).events; + for (var i = events.length - 1; i >= 0; i--) { + var message = events[i]; + + // TODO: define a better marker than echo_msg_state + if (!filterEcho || undefined === message.echo_msg_state) { + lastMessage = message; + break; + } + } + + return lastMessage; } }; diff --git a/syweb/webclient/index.html b/syweb/webclient/index.html index d9c67333af..2dddd14cfc 100644 --- a/syweb/webclient/index.html +++ b/syweb/webclient/index.html @@ -11,17 +11,17 @@ - - + + - - - - + + + + diff --git a/syweb/webclient/js/recaptcha_ajax.js b/syweb/webclient/js/recaptcha_ajax.js new file mode 100644 index 0000000000..d0e71e5b88 --- /dev/null +++ b/syweb/webclient/js/recaptcha_ajax.js @@ -0,0 +1,195 @@ +(function(){var h,k=this,l=function(a){return void 0!==a},ba=function(){},n=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&& +!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==b&&"undefined"==typeof a.call)return"object";return b},p=function(a){return"array"==n(a)},ca=function(a){var b=n(a);return"array"==b||"object"==b&&"number"==typeof a.length},q=function(a){return"string"==typeof a},r=function(a){return"function"==n(a)},da=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b},ea=function(a,b,c){return a.call.apply(a.bind,arguments)},fa=function(a,b,c){if(!a)throw Error(); +if(2 |