From 969c19b2e926331e2686208507c2643107caf5a1 Mon Sep 17 00:00:00 2001 From: Michael Jobst Date: Mon, 21 Nov 2016 15:03:45 +0100 Subject: [PATCH] Fixed size issues on main detail view and disappearing of share recipients (#26603) * fixed size issues on main detail view and disappearing of share recipients * Changes due to code comments * Moved reloadProperties() to FileInfoModel * Solved Scrutinizer issues * Bugfix: undefined value used on error * check if options are set for FileInfoModel.initialize() Signed-off-by: Arthur Schiwon --- apps/comments/js/commentmodel.js | 33 ++++++++----- apps/comments/js/commentsummarymodel.js | 11 +++-- apps/comments/js/filesplugin.js | 11 +++-- apps/dav/lib/Connector/Sabre/FilesPlugin.php | 3 ++ .../unit/Connector/Sabre/FilesPluginTest.php | 2 - apps/files/js/fileinfomodel.js | 47 ++++++++++++++++++- apps/files/js/filelist.js | 12 +++-- apps/files/js/mainfileinfodetailview.js | 13 +++++ apps/files/js/tagsplugin.js | 17 ++++--- apps/files_sharing/js/share.js | 28 +++++++---- core/js/files/client.js | 36 +++++++++----- core/js/systemtags/systemtagmodel.js | 21 ++++++--- 12 files changed, 173 insertions(+), 61 deletions(-) diff --git a/apps/comments/js/commentmodel.js b/apps/comments/js/commentmodel.js index e75c79b3f08..a594753cd45 100644 --- a/apps/comments/js/commentmodel.js +++ b/apps/comments/js/commentmodel.js @@ -9,7 +9,19 @@ */ (function(OC, OCA) { - var NS_OWNCLOUD = 'http://owncloud.org/ns'; + + _.extend(OC.Files.Client, { + PROPERTY_FILEID: '{' + OC.Files.Client.NS_OWNCLOUD + '}id', + PROPERTY_MESSAGE: '{' + OC.Files.Client.NS_OWNCLOUD + '}message', + PROPERTY_ACTORTYPE: '{' + OC.Files.Client.NS_OWNCLOUD + '}actorType', + PROPERTY_ACTORID: '{' + OC.Files.Client.NS_OWNCLOUD + '}actorId', + PROPERTY_ISUNREAD: '{' + OC.Files.Client.NS_OWNCLOUD + '}isUnread', + PROPERTY_OBJECTID: '{' + OC.Files.Client.NS_OWNCLOUD + '}objectId', + PROPERTY_OBJECTTYPE: '{' + OC.Files.Client.NS_OWNCLOUD + '}objectType', + PROPERTY_ACTORDISPLAYNAME: '{' + OC.Files.Client.NS_OWNCLOUD + '}actorDisplayName', + PROPERTY_CREATIONDATETIME: '{' + OC.Files.Client.NS_OWNCLOUD + '}creationDateTime' + }); + /** * @class OCA.Comments.CommentModel * @classdesc @@ -27,15 +39,15 @@ }, davProperties: { - 'id': '{' + NS_OWNCLOUD + '}id', - 'message': '{' + NS_OWNCLOUD + '}message', - 'actorType': '{' + NS_OWNCLOUD + '}actorType', - 'actorId': '{' + NS_OWNCLOUD + '}actorId', - 'actorDisplayName': '{' + NS_OWNCLOUD + '}actorDisplayName', - 'creationDateTime': '{' + NS_OWNCLOUD + '}creationDateTime', - 'objectType': '{' + NS_OWNCLOUD + '}objectType', - 'objectId': '{' + NS_OWNCLOUD + '}objectId', - 'isUnread': '{' + NS_OWNCLOUD + '}isUnread', + 'id': OC.Files.Client.PROPERTY_FILEID, + 'message': OC.Files.Client.PROPERTY_MESSAGE, + 'actorType': OC.Files.Client.PROPERTY_ACTORTYPE, + 'actorId': OC.Files.Client.PROPERTY_ACTORID, + 'actorDisplayName': OC.Files.Client.PROPERTY_ACTORDISPLAYNAME, + 'creationDateTime': OC.Files.Client.PROPERTY_CREATIONDATETIME, + 'objectType': OC.Files.Client.PROPERTY_OBJECTTYPE, + 'objectId': OC.Files.Client.PROPERTY_OBJECTID, + 'isUnread': OC.Files.Client.PROPERTY_ISUNREAD 'mentions': '{' + NS_OWNCLOUD + '}mentions' }, @@ -78,4 +90,3 @@ OCA.Comments.CommentModel = CommentModel; })(OC, OCA); - diff --git a/apps/comments/js/commentsummarymodel.js b/apps/comments/js/commentsummarymodel.js index d405315ca1f..ffabbc30fb4 100644 --- a/apps/comments/js/commentsummarymodel.js +++ b/apps/comments/js/commentsummarymodel.js @@ -9,13 +9,17 @@ */ (function(OC, OCA) { - var NS_OWNCLOUD = 'http://owncloud.org/ns'; + + _.extend(OC.Files.Client, { + PROPERTY_READMARKER: '{' + OC.Files.Client.NS_OWNCLOUD + '}readMarker' + }); + /** * @class OCA.Comments.CommentSummaryModel * @classdesc * * Model containing summary information related to comments - * like the read marker. + * like the read marker. * */ var CommentSummaryModel = OC.Backbone.Model.extend( @@ -37,7 +41,7 @@ _objectId: null, davProperties: { - 'readMarker': '{' + NS_OWNCLOUD + '}readMarker' + 'readMarker': OC.Files.Client.PROPERTY_READMARKER }, /** @@ -62,4 +66,3 @@ OCA.Comments.CommentSummaryModel = CommentSummaryModel; })(OC, OCA); - diff --git a/apps/comments/js/filesplugin.js b/apps/comments/js/filesplugin.js index cc419c18ddb..8c5762065a1 100644 --- a/apps/comments/js/filesplugin.js +++ b/apps/comments/js/filesplugin.js @@ -11,6 +11,11 @@ /* global Handlebars */ (function() { + + _.extend(OC.Files.Client, { + PROPERTY_COMMENTS_UNREAD: '{' + OC.Files.Client.NS_OWNCLOUD + '}comments-unread' + }); + var TEMPLATE_COMMENTS_UNREAD = '' + '' + @@ -52,19 +57,17 @@ fileList.registerTabView(new OCA.Comments.CommentsTabView('commentsTabView')); - var NS_OC = 'http://owncloud.org/ns'; - var oldGetWebdavProperties = fileList._getWebdavProperties; fileList._getWebdavProperties = function() { var props = oldGetWebdavProperties.apply(this, arguments); - props.push('{' + NS_OC + '}comments-unread'); + props.push(OC.Files.Client.PROPERTY_COMMENTS_UNREAD); return props; }; fileList.filesClient.addFileInfoParser(function(response) { var data = {}; var props = response.propStat[0].properties; - var commentsUnread = props['{' + NS_OC + '}comments-unread']; + var commentsUnread = props[OC.Files.Client.PROPERTY_COMMENTS_UNREAD]; if (!_.isUndefined(commentsUnread) && commentsUnread !== '') { data.commentsUnread = parseInt(commentsUnread, 10); } diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php index 54d91db5c06..5e401b88481 100644 --- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php @@ -328,6 +328,9 @@ class FilesPlugin extends ServerPlugin { $propFind->handle(self::HAS_PREVIEW_PROPERTYNAME, function () use ($node) { return json_encode($this->previewManager->isAvailable($node->getFileInfo())); }); + $propFind->handle(self::SIZE_PROPERTYNAME, function() use ($node) { + return $node->getSize(); + }); } if ($node instanceof \OCA\DAV\Connector\Sabre\Node) { diff --git a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php index c6e833033d5..1c9ebdd09b6 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php @@ -188,8 +188,6 @@ class FilesPluginTest extends TestCase { $node->expects($this->exactly(2)) ->method('getOwner') ->will($this->returnValue($user)); - $node->expects($this->never()) - ->method('getSize'); $this->plugin->handleGetProperties( $propFind, diff --git a/apps/files/js/fileinfomodel.js b/apps/files/js/fileinfomodel.js index de1b143a160..9d1eac31940 100644 --- a/apps/files/js/fileinfomodel.js +++ b/apps/files/js/fileinfomodel.js @@ -36,10 +36,18 @@ path: '' }, - initialize: function(data) { + _filesClient: null, + + initialize: function(data, options) { if (!_.isUndefined(data.id)) { data.id = parseInt(data.id, 10); } + + if( options ){ + if (options.filesClient) { + this._filesClient = options.filesClient; + } + } }, /** @@ -73,6 +81,42 @@ */ getFullPath: function() { return OC.joinPaths(this.get('path'), this.get('name')); + }, + + /** + * Reloads missing properties from server and set them in the model. + * @param properties array of properties to be reloaded + * @return ajax call object + */ + reloadProperties: function(properties) { + if( !this._filesClient ){ + return; + } + + var self = this; + var deferred = $.Deferred(); + + var targetPath = OC.joinPaths(this.get('path') + '/', this.get('name')); + + this._filesClient.getFileInfo(targetPath, { + properties: properties + }) + .then(function(status, data) { + // the following lines should be extracted to a mapper + + if( properties.indexOf(OC.Files.Client.PROPERTY_GETCONTENTLENGTH) !== -1 + || properties.indexOf(OC.Files.Client.PROPERTY_SIZE) !== -1 ) { + self.set('size', data.size); + } + + deferred.resolve(status, data); + }) + .fail(function(status) { + OC.Notification.showTemporary(t('files', 'Could not load info for file "{file}"', {file: self.get('name')})); + deferred.reject(status); + }); + + return deferred.promise(); } }); @@ -82,4 +126,3 @@ OCA.Files.FileInfoModel = FileInfoModel; })(OC, OCA); - diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index a8daeadfd26..cd0eb390ee3 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -442,7 +442,9 @@ // In the future the FileList should work with Backbone.Collection // and contain existing models that can be used. // This method would in the future simply retrieve the matching model from the collection. - var model = new OCA.Files.FileInfoModel(this.elementToFile($tr)); + var model = new OCA.Files.FileInfoModel(this.elementToFile($tr), { + filesClient: this.filesClient + }); if (!model.get('path')) { model.set('path', this.getCurrentDirectory(), {silent: true}); } @@ -891,11 +893,14 @@ mimetype: $el.attr('data-mime'), mtime: parseInt($el.attr('data-mtime'), 10), type: $el.attr('data-type'), - size: parseInt($el.attr('data-size'), 10), etag: $el.attr('data-etag'), permissions: parseInt($el.attr('data-permissions'), 10), hasPreview: $el.attr('data-has-preview') === 'true' }; + var size = $el.attr('data-size'); + if (size) { + data.size = parseInt(size, 10); + } var icon = $el.attr('data-icon'); if (icon) { data.icon = icon; @@ -1029,7 +1034,7 @@ * Returns whether the given file info must be hidden * * @param {OC.Files.FileInfo} fileInfo file info - * + * * @return {boolean} true if the file is a hidden file, false otherwise */ _isHiddenFile: function(file) { @@ -2828,7 +2833,6 @@ }); uploader.on('fail', function(e, data) { self._uploader.log('filelist handle fileuploadfail', e, data); - self._uploads = []; //if user pressed cancel hide upload chrome diff --git a/apps/files/js/mainfileinfodetailview.js b/apps/files/js/mainfileinfodetailview.js index 1a69528fd17..e815fa70ecb 100644 --- a/apps/files/js/mainfileinfodetailview.js +++ b/apps/files/js/mainfileinfodetailview.js @@ -130,6 +130,19 @@ if (this.model) { this.model.on('change', this._onModelChanged, this); } + + if (this.model) { + var properties = []; + if( !this.model.has('size') ) { + properties.push(OC.Files.Client.PROPERTY_SIZE); + properties.push(OC.Files.Client.PROPERTY_GETCONTENTLENGTH); + } + + if( properties.length > 0){ + this.model.reloadProperties(properties); + } + } + this.render(); }, diff --git a/apps/files/js/tagsplugin.js b/apps/files/js/tagsplugin.js index 3c0a231d003..9bb4ba33598 100644 --- a/apps/files/js/tagsplugin.js +++ b/apps/files/js/tagsplugin.js @@ -12,6 +12,11 @@ (function(OCA) { + _.extend(OC.Files.Client, { + PROPERTY_TAGS: '{' + OC.Files.Client.NS_OWNCLOUD + '}tags', + PROPERTY_FAVORITE: '{' + OC.Files.Client.NS_OWNCLOUD + '}favorite' + }); + var TEMPLATE_FAVORITE_ACTION = '' + @@ -162,24 +167,22 @@ return fileInfo; }; - var NS_OC = 'http://owncloud.org/ns'; - var oldGetWebdavProperties = fileList._getWebdavProperties; fileList._getWebdavProperties = function() { var props = oldGetWebdavProperties.apply(this, arguments); - props.push('{' + NS_OC + '}tags'); - props.push('{' + NS_OC + '}favorite'); + props.push(OC.Files.Client.PROPERTY_TAGS); + props.push(OC.Files.Client.PROPERTY_FAVORITE); return props; }; fileList.filesClient.addFileInfoParser(function(response) { var data = {}; var props = response.propStat[0].properties; - var tags = props['{' + NS_OC + '}tags']; - var favorite = props['{' + NS_OC + '}favorite']; + var tags = props[OC.Files.Client.PROPERTY_TAGS]; + var favorite = props[OC.Files.Client.PROPERTY_FAVORITE]; if (tags && tags.length) { tags = _.chain(tags).filter(function(xmlvalue) { - return (xmlvalue.namespaceURI === NS_OC && xmlvalue.nodeName.split(':')[1] === 'tag'); + return (xmlvalue.namespaceURI === OC.Files.Client.NS_OWNCLOUD && xmlvalue.nodeName.split(':')[1] === 'tag'); }).map(function(xmlvalue) { return xmlvalue.textContent || xmlvalue.text; }).value(); diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 01c2ccfb863..fcae7bc9a58 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -9,6 +9,12 @@ */ (function() { + + _.extend(OC.Files.Client, { + PROPERTY_SHARE_TYPES: '{' + OC.Files.Client.NS_OWNCLOUD + '}share-types', + PROPERTY_OWNER_DISPLAY_NAME: '{' + OC.Files.Client.NS_OWNCLOUD + '}owner-display-name' + }); + if (!OCA.Sharing) { OCA.Sharing = {}; } @@ -65,32 +71,38 @@ fileInfo.shareTypes = shareTypes; } + if( $el.attr('data-expiration')){ + var expirationTimestamp = parseInt($el.attr('data-expiration')); + fileInfo.shares = []; + fileInfo.shares.push({expiration: expirationTimestamp}); + } + + fileInfo.recipientsDisplayName = $el.attr('data-share-recipients') || undefined; + return fileInfo; }; - var NS_OC = 'http://owncloud.org/ns'; - var oldGetWebdavProperties = fileList._getWebdavProperties; fileList._getWebdavProperties = function() { var props = oldGetWebdavProperties.apply(this, arguments); - props.push('{' + NS_OC + '}owner-display-name'); - props.push('{' + NS_OC + '}share-types'); + props.push(OC.Files.Client.PROPERTY_OWNER_DISPLAY_NAME); + props.push(OC.Files.Client.PROPERTY_SHARE_TYPES); return props; }; fileList.filesClient.addFileInfoParser(function(response) { var data = {}; var props = response.propStat[0].properties; - var permissionsProp = props['{' + NS_OC + '}permissions']; + var permissionsProp = props[OC.Files.Client.PROPERTY_PERMISSIONS]; if (permissionsProp && permissionsProp.indexOf('S') >= 0) { - data.shareOwner = props['{' + NS_OC + '}owner-display-name']; + data.shareOwner = props[OC.Files.Client.PROPERTY_OWNER_DISPLAY_NAME]; } - var shareTypesProp = props['{' + NS_OC + '}share-types']; + var shareTypesProp = props[OC.Files.Client.PROPERTY_SHARE_TYPES]; if (shareTypesProp) { data.shareTypes = _.chain(shareTypesProp).filter(function(xmlvalue) { - return (xmlvalue.namespaceURI === NS_OC && xmlvalue.nodeName.split(':')[1] === 'share-type'); + return (xmlvalue.namespaceURI === OC.Files.Client.NS_OWNCLOUD && xmlvalue.nodeName.split(':')[1] === 'share-type'); }).map(function(xmlvalue) { return parseInt(xmlvalue.textContent || xmlvalue.text, 10); }).value(); diff --git a/core/js/files/client.js b/core/js/files/client.js index 87559b2084c..cde3afde9d7 100644 --- a/core/js/files/client.js +++ b/core/js/files/client.js @@ -31,9 +31,9 @@ this._root = this._root.substr(0, this._root.length - 1); } - var url = 'http://'; + var url = Client.PROTOCOL_HTTP + '://'; if (options.useHTTPS) { - url = 'https://'; + url = Client.PROTOCOL_HTTPS + '://'; } url += options.host + this._root; @@ -64,6 +64,19 @@ Client.NS_OWNCLOUD = 'http://owncloud.org/ns'; Client.NS_NEXTCLOUD = 'http://nextcloud.org/ns'; Client.NS_DAV = 'DAV:'; + + Client.PROPERTY_GETLASTMODIFIED = '{' + Client.NS_DAV + '}getlastmodified'; + Client.PROPERTY_GETETAG = '{' + Client.NS_DAV + '}getetag'; + Client.PROPERTY_GETCONTENTTYPE = '{' + Client.NS_DAV + '}getcontenttype'; + Client.PROPERTY_RESOURCETYPE = '{' + Client.NS_DAV + '}resourcetype'; + Client.PROPERTY_INTERNAL_FILEID = '{' + Client.NS_OWNCLOUD + '}fileid'; + Client.PROPERTY_PERMISSIONS = '{' + Client.NS_OWNCLOUD + '}permissions'; + Client.PROPERTY_SIZE = '{' + Client.NS_OWNCLOUD + '}size'; + Client.PROPERTY_GETCONTENTLENGTH = '{' + Client.NS_DAV + '}getcontentlength'; + + Client.PROTOCOL_HTTP = 'http'; + Client.PROTOCOL_HTTPS = 'https'; + Client._PROPFIND_PROPERTIES = [ /** * Modified time @@ -259,23 +272,23 @@ var props = response.propStat[0].properties; var data = { - id: props['{' + Client.NS_OWNCLOUD + '}fileid'], + id: props[Client.PROPERTY_INTERNAL_FILEID], path: OC.dirname(path) || '/', name: OC.basename(path), - mtime: (new Date(props['{' + Client.NS_DAV + '}getlastmodified'])).getTime() + mtime: (new Date(props[Client.PROPERTY_GETLASTMODIFIED])).getTime() }; - var etagProp = props['{' + Client.NS_DAV + '}getetag']; + var etagProp = props[Client.PROPERTY_GETETAG]; if (!_.isUndefined(etagProp)) { data.etag = this._parseEtag(etagProp); } - var sizeProp = props['{' + Client.NS_DAV + '}getcontentlength']; + var sizeProp = props[Client.PROPERTY_GETCONTENTLENGTH]; if (!_.isUndefined(sizeProp)) { data.size = parseInt(sizeProp, 10); } - sizeProp = props['{' + Client.NS_OWNCLOUD + '}size']; + sizeProp = props[Client.PROPERTY_SIZE]; if (!_.isUndefined(sizeProp)) { data.size = parseInt(sizeProp, 10); } @@ -294,12 +307,12 @@ data.isFavorite = false; } - var contentType = props['{' + Client.NS_DAV + '}getcontenttype']; + var contentType = props[Client.PROPERTY_GETCONTENTTYPE]; if (!_.isUndefined(contentType)) { data.mimetype = contentType; } - var resType = props['{' + Client.NS_DAV + '}resourcetype']; + var resType = props[Client.PROPERTY_RESOURCETYPE]; var isFile = true; if (!data.mimetype && resType) { var xmlvalue = resType[0]; @@ -310,7 +323,7 @@ } data.permissions = OC.PERMISSION_READ; - var permissionProp = props['{' + Client.NS_OWNCLOUD + '}permissions']; + var permissionProp = props[Client.PROPERTY_PERMISSIONS]; if (!_.isUndefined(permissionProp)) { var permString = permissionProp || ''; data.mountType = null; @@ -752,7 +765,7 @@ }, /** - * Returns the password + * Returns the password * * @since 11.0.0 * @return {String} password @@ -816,4 +829,3 @@ OC.Files.Client = Client; })(OC, OC.Files.FileInfo); - diff --git a/core/js/systemtags/systemtagmodel.js b/core/js/systemtags/systemtagmodel.js index 89728357e25..72450a2abd0 100644 --- a/core/js/systemtags/systemtagmodel.js +++ b/core/js/systemtags/systemtagmodel.js @@ -9,7 +9,15 @@ */ (function(OC) { - var NS_OWNCLOUD = 'http://owncloud.org/ns'; + + _.extend(OC.Files.Client, { + PROPERTY_FILEID: '{' + OC.Files.Client.NS_OWNCLOUD + '}id', + PROPERTY_CAN_ASSIGN:'{' + OC.Files.Client.NS_OWNCLOUD + '}can-assign', + PROPERTY_DISPLAYNAME: '{' + OC.Files.Client.NS_OWNCLOUD + '}display-name', + PROPERTY_USERVISIBLE: '{' + OC.Files.Client.NS_OWNCLOUD + '}user-visible', + PROPERTY_USERASSIGNABLE:'{' + OC.Files.Client.NS_OWNCLOUD + '}user-assignable', + }); + /** * @class OCA.SystemTags.SystemTagsCollection * @classdesc @@ -28,12 +36,12 @@ }, davProperties: { - 'id': '{' + NS_OWNCLOUD + '}id', - 'name': '{' + NS_OWNCLOUD + '}display-name', - 'userVisible': '{' + NS_OWNCLOUD + '}user-visible', - 'userAssignable': '{' + NS_OWNCLOUD + '}user-assignable', + 'id': OC.Files.Client.PROPERTY_FILEID, + 'name': OC.Files.Client.PROPERTY_DISPLAYNAME, + 'userVisible': OC.Files.Client.PROPERTY_USERVISIBLE, + 'userAssignable': OC.Files.Client.PROPERTY_USERASSIGNABLE, // read-only, effective permissions computed by the server, - 'canAssign': '{' + NS_OWNCLOUD + '}can-assign' + 'canAssign': OC.Files.Client.PROPERTY_CAN_ASSIGN }, parse: function(data) { @@ -50,4 +58,3 @@ OC.SystemTags = OC.SystemTags || {}; OC.SystemTags.SystemTagModel = SystemTagModel; })(OC); -