diff --git a/apps/files/css/files.css b/apps/files/css/files.css index e63e3012f24e..f9c47737a0b1 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -512,7 +512,7 @@ table td.filename .uploadtext { } /* File checkboxes */ -html:not(.ie8) #fileList tr td.filename > .selectCheckBox + label:before { +#fileList tr td.filename > .selectCheckBox + label:before { opacity: 0; position: absolute; bottom: 4px; @@ -520,13 +520,21 @@ html:not(.ie8) #fileList tr td.filename > .selectCheckBox + label:before { z-index: 10; } -html.ie8 #fileList tr td.filename > .selectCheckBox { - filter: alpha(opacity=0); - opacity: 0; - float: left; - top: 0; - margin: 32px 0 4px 32px; - /* bigger clickable area doesn’t work in FF width:2.8em; height:2.4em;*/ +#fileList tr:not(:hover):not(.selected) td.filename .thumbnail.sharetree-item:after { + position: absolute; + display: block; + content: ''; + bottom: 0px; + right: -5px; + z-index: 10; + background-image: url(../../../core/img/actions/shared.svg); + width: 14px; + height: 14px; + background-repeat: no-repeat; + background-position: center; + background-size: 10px; + background-color: #bfbfbf; + border-radius: 50%; } /* Show checkbox when hovering, checked, or selected */ diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index e76008dc344b..2ff6f92a2ce2 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -168,6 +168,13 @@ */ _sortComparator: null, + /** + * Stores shareTree items and infos + * + * @type Array + */ + _shareTreeCache: {}, + /** * Whether to do a client side sort. * When false, clicking on a table header will call reload(). @@ -379,6 +386,7 @@ // remove summary this.$el.find('tfoot tr.summary').remove(); this.$fileList.empty(); + }, /** @@ -1048,6 +1056,7 @@ $(window).scrollTop(0); this.$fileList.trigger(jQuery.Event('updated')); + _.defer(function() { self.$el.closest('#app-content').trigger(jQuery.Event('apprendered')); }); @@ -1389,6 +1398,10 @@ tr.addClass('hidden-file'); } + if(_.keys(this._shareTreeCache).length) { + filenameTd.find('.thumbnail:not(.sharetree-item)').addClass('sharetree-item'); + } + // display actions this.fileActions.display(filenameTd, !options.silent, this); @@ -1445,17 +1458,28 @@ var self = this; var currentDir = this.getCurrentDirectory(); targetDir = targetDir || '/'; - if (!force && currentDir === targetDir) { - return; - } - this._setCurrentDir(targetDir, changeUrl, fileId); - // discard finished uploads list, we'll get it through a regular reload - this._uploads = {}; - this.reload().then(function(success){ - if (!success) { - self.changeDirectory(currentDir, true); + + return new Promise(function(resolve, reject) { + + if (!force && currentDir === targetDir) { + resolve() + return } - }); + self._setCurrentDir(targetDir, changeUrl, fileId); + // discard finished uploads list, we'll get it through a regular reload + self._uploads = {}; + self.reload().then(function(success){ + if (!success) { + self.changeDirectory(currentDir, true); + reject() + } + resolve() + }); + + self._updateShareTree().then(function() { + self._setShareTreeIcons(); + }) + }) }, linkTo: function(dir) { return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); @@ -1723,6 +1747,197 @@ return OC.linkToRemoteBase('dav') + '/files/' + uid + encodedPath; }, + /** + * Fetch shareTypes of a certain directory + * @param {String} dir directory string + * @return {Promise} object with name and shareTypes + */ + getDirShareInfo: function(dir) { + // Dir can't be empty + if (typeof dir !== 'string' || dir.length === 0) { + return Promise.reject('getDirShareInfo(). param must be typeof string and can not be empty!') + } + + // avoiding a unnessesary API calls + if (typeof this._shareTreeCache[dir] !== 'undefined' || dir === '/') { + return Promise.resolve() + } + + // trim trailing slashes + dir = dir.replace(/\/$/, "") + + var self = this; + var client = this.filesClient; + var options = { + properties : ['{' + OC.Files.Client.NS_OWNCLOUD + '}share-types'] + } + + return new Promise( function(resolve, reject) { + client.getFileInfo(dir, options).done(function(s, dir) { + + var path = OC.joinPaths(dir.path, dir.name) + + if (dir.shareTypes !== undefined) { + // Fetch all shares for directory in question + $.get( OC.linkToOCS('apps/files_sharing/api/v1', 2) + 'shares?' + OC.buildQueryString({format: 'json', path: path }), function(e) { + self._shareTreeCache[path] = { + name : dir.name, + shares : e.ocs.data + } + resolve() + }) + } + else { + resolve() + } + }).fail(function(error) { + reject(error) + }) + }) + }, + + /** + * Fetch shareInfos recursively from current + * directory down to root + * @param {String} dir directory string + * @return {Promise} array of objects with name and shareTypes + */ + getPathShareInfo: function(path) { + if (typeof path !== 'string') { + console.error('getDirShareInfo(). param must be typeof string!') + return false + } + + var crumbs = []; + var pathToHere = ''; + var parts = (path === '/' || path.length === 0) ? ['/'] : path.split('/') + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + pathToHere += part + '/'; + + crumbs.push(this.getDirShareInfo(pathToHere)) + } + + return Promise.all(crumbs) + }, + + _updateShareTree: function() { + var self = this; + var dir = this.getCurrentDirectory(); + + // Purge shareTreeCache in root dir + if (dir === '/') { + this._purgeShareTreeCache() + return Promise.resolve() + } + + return this.getPathShareInfo(dir).then(function () { + var breadcrumbs = dir.split('/') + + // Diff keys in shareTreeCache agains the current dir + // removing deeper nested shares + var cache = _.omit(self._shareTreeCache, function(value, key) { + var diffs = _.difference(key.split('/'), breadcrumbs) + return diffs.length > 0 + }); + + self._setShareTreeCache(cache) + }) + + }, + + _setShareTreeCache: function(data) { + this._shareTreeCache = data; + }, + + _purgeShareTreeCache: function() { + this._setShareTreeCache({}); + }, + + _setShareTreeIcons: function() { + // Add share-tree icon to files and folders + // each per in the table + + if (_.keys(this._shareTreeCache).length > 0) + this.$fileList.find('tr td.filename .thumbnail:not(.sharetree-item)').addClass('sharetree-item') + else + this.$fileList.find('tr td.filename .thumbnail.sharetree-item').removeClass('sharetree-item') + + }, + + _setShareTreeUserGroupView: function() { + var self = this; + var $list = $('