From 8105173c20aca6f5e549e446c8cbb0ba9862a263 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Tue, 8 Oct 2019 14:10:40 +0200 Subject: [PATCH 01/37] Add dir/path sharing info --- apps/files/js/filelist.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index e76008dc344b..d86f024ec335 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1723,6 +1723,38 @@ return OC.linkToRemoteBase('dav') + '/files/' + uid + encodedPath; }, + getDirShareInfo: function(dir) { + 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) { + resolve({ + name : dir.name, + shareTypes : dir.shareTypes + }) + }).fail(function(error) { + reject(error) + }) + }) + }, + + getPathShareInfo: function(path) { + var crumbs = []; + var pathToHere = ''; + var parts = (path === '/') ? ['/'] : 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) + }, + /** * Generates a preview URL based on the URL space. * @param urlSpec attributes for the URL From 0f4ce7cc24a2fe70aec85d96109a91cdb689caff Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Tue, 8 Oct 2019 16:38:17 +0200 Subject: [PATCH 02/37] Add method documentation add param checks --- apps/files/js/filelist.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index d86f024ec335..ed4642c056f7 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1723,7 +1723,18 @@ 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) { + console.error('getDirShareInfo(). param must be typeof string and can not be empty!') + return false + } + var client = this.filesClient var options = { properties : ['{' + OC.Files.Client.NS_OWNCLOUD + '}share-types'] @@ -1741,10 +1752,21 @@ }) }, + /** + * 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 dir !== 'string') { + console.error('getDirShareInfo(). param must be typeof string!') + return false + } + var crumbs = []; var pathToHere = ''; - var parts = (path === '/') ? ['/'] : path.split('/') + var parts = (path === '/' || path.length === 0) ? ['/'] : path.split('/') for (var i = 0; i < parts.length; i++) { var part = parts[i]; From 729717e01843b867450c4dec32c85b31b4d0d842 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Fri, 11 Oct 2019 11:41:49 +0200 Subject: [PATCH 03/37] Add fileShare indicator method --- apps/files/css/files.css | 51 +++++++++++++++++++++++++++++++++++++++ apps/files/js/filelist.js | 32 ++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index e63e3012f24e..1902f6b604e9 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -983,3 +983,54 @@ html.ie8 #controls .button.new { position: inherit; right: inherit; } + +/* + * Directory sharing indocator + * + * #fff4cc - Background yellow + * #d5c999 - Border dirty yellow + * #927800 - Text dark dirty yellow + */ + +#controls #shareinfo_indicator { + float: right; + height: 32px; + position: relative; + align-items: center; + padding: 6px 7px 0 0; +} + +#controls #shareinfo_indicator .text { + display: block; + background-color: #fff4cc; + border: 1px solid #d5c999; + border-radius: 3px; + color: #927800; + padding: 4px 30px 4px 12px; + position: relative; + cursor: pointer; +} + +#controls #shareinfo_indicator .text:after { + content: ""; + position: absolute; + width: 0; + height: 0; + border-style: solid; + border-width: 4px 4px 0 4px; + border-color: #927800 transparent transparent transparent; + right: 10px; + top: calc(50% - 2px); +} + +#controls #shareinfo_indicator:not(:hover) .list { + display: none; +} + +#controls #shareinfo_indicator .list { + position: absolute; + top: 42px; + right: 7px; + + background: rebeccapurple; +} \ No newline at end of file diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index ed4642c056f7..cea6f67114c2 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -356,6 +356,34 @@ OC.Plugins.attach('OCA.Files.FileList', this); }, + dirShareInfoIndicator: function () { + var $el = $('#shareinfo_indicator') + + if ( !$el.length ) { + + $el = $('
', { id : 'shareinfo_indicator' }); + $textbox = $('', { class : "text", text : t('core', 'shared') }) + $sharelist = $('
', { class : 'list', html : '
    ' }) + + $el.append($textbox, $sharelist).appendTo($('#controls')).hide() + } + + this.getPathShareInfo(this.getCurrentDirectory()).then(function(path) { + var shares = path.filter( function(dir) { + return dir.shareTypes.length > 0 + }) + + // Stop if there are no shares present + if (shares.length === 0) { + $el.fadeOut('fast') + return + } + + $el.fadeIn('fast') + $el.find('.list ul').append('
  • Hallo
  • ') + }); + }, + /** * Destroy / uninitialize this instance. */ @@ -1744,7 +1772,7 @@ client.getFileInfo(dir, options).done(function(s, dir) { resolve({ name : dir.name, - shareTypes : dir.shareTypes + shareTypes : (dir.shareTypes !== undefined) ? dir.shareTypes : [] }) }).fail(function(error) { reject(error) @@ -1759,7 +1787,7 @@ * @return {Promise} array of objects with name and shareTypes */ getPathShareInfo: function(path) { - if (typeof dir !== 'string') { + if (typeof path !== 'string') { console.error('getDirShareInfo(). param must be typeof string!') return false } From 7a43227fd990b1b6d6cd18853e0cbfceb4565723 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Thu, 17 Oct 2019 10:48:46 +0200 Subject: [PATCH 04/37] WIP --- apps/files/js/filelist.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index cea6f67114c2..76a58b24770e 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1363,6 +1363,8 @@ this.updateEmptyContent(); } + this._setSharedIcon() + return $tr; }, @@ -1484,6 +1486,8 @@ self.changeDirectory(currentDir, true); } }); + + this._setSharedIcon() }, linkTo: function(dir) { return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); @@ -1805,6 +1809,37 @@ return Promise.all(crumbs) }, + + _chechPathHasShares: function() { + let self = this; + + return this.getPathShareInfo(this.getCurrentDirectory()).then(function(path) { + + let sharedFolders = _.filter(path, function(dir) { + return dir.shareTypes.length > 0 + }) + + if (sharedFolders.length > 0) + return true + + return false + }) + }, + + _setSharedIcon: function() { + var self = this; + setTimeout(function(){ + // Sad, but there is no ready callback + // so let's do it this way 4 now. + + self._chechPathHasShares().then(function(e) { + if (e) { + $('tr[data-type="dir"] .thumbnail').css({'backgroundImage' : 'url(' + OC.MimeType.getIconUrl('dir-shared') + ')'}) + } + }) + }, 250) + }, + /** * Generates a preview URL based on the URL space. * @param urlSpec attributes for the URL From e3969f9da18c6bdec738bff8ff74ff93d65c3751 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Thu, 17 Oct 2019 12:48:20 +0200 Subject: [PATCH 05/37] in share-tree icon --- apps/files/css/files.css | 21 +++++++++++++-------- apps/files/img/shareinfo.svg | 1 + apps/files/js/filelist.js | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 apps/files/img/shareinfo.svg diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 1902f6b604e9..8e2e1bd3f3c7 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,18 @@ 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(../img/shareinfo.svg); + width: 14px; + height: 14px; + background-repeat: no-repeat; + background-position: center; } /* Show checkbox when hovering, checked, or selected */ diff --git a/apps/files/img/shareinfo.svg b/apps/files/img/shareinfo.svg new file mode 100644 index 000000000000..d57051def255 --- /dev/null +++ b/apps/files/img/shareinfo.svg @@ -0,0 +1 @@ +shareinfo \ No newline at end of file diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 76a58b24770e..6e1969d4f25a 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1834,7 +1834,7 @@ self._chechPathHasShares().then(function(e) { if (e) { - $('tr[data-type="dir"] .thumbnail').css({'backgroundImage' : 'url(' + OC.MimeType.getIconUrl('dir-shared') + ')'}) + $('#fileList tr td.filename .thumbnail').addClass('sharetree-item') } }) }, 250) From 845bf20a083789418f774092de6c97934a26fd4f Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Mon, 21 Oct 2019 18:35:13 +0200 Subject: [PATCH 06/37] [WIP] Append shareTree Info in shareTab --- apps/files/img/shareinfo.svg | 2 +- apps/files/js/filelist.js | 57 +++++++++++++++++++++++++++++------- core/js/sharedialogview.js | 3 +- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/apps/files/img/shareinfo.svg b/apps/files/img/shareinfo.svg index d57051def255..381ceb2c0613 100644 --- a/apps/files/img/shareinfo.svg +++ b/apps/files/img/shareinfo.svg @@ -1 +1 @@ -shareinfo \ No newline at end of file +shareinfo \ No newline at end of file diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 6e1969d4f25a..9f7262f64ebc 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1774,10 +1774,21 @@ return new Promise( function(resolve, reject) { client.getFileInfo(dir, options).done(function(s, dir) { - resolve({ + var shareInfo = { name : dir.name, - shareTypes : (dir.shareTypes !== undefined) ? dir.shareTypes : [] - }) + path : dir.path + } + + if (dir.shareTypes === undefined) { + Object.assign(shareInfo, { shares : [] }) + resolve(shareInfo) + } + else { + $.get( OC.linkToOCS('apps/files_sharing/api/v1', 2) + 'shares?' + OC.buildQueryString({format: 'json', path: (dir.path + '/' + dir.name)}), function(e) { + Object.assign(shareInfo, { shares : e.ocs.data }) + resolve(shareInfo) + }) + } }).fail(function(error) { reject(error) }) @@ -1816,7 +1827,7 @@ return this.getPathShareInfo(this.getCurrentDirectory()).then(function(path) { let sharedFolders = _.filter(path, function(dir) { - return dir.shareTypes.length > 0 + return dir.shares.length > 0 }) if (sharedFolders.length > 0) @@ -1828,16 +1839,42 @@ _setSharedIcon: function() { var self = this; - setTimeout(function(){ - // Sad, but there is no ready callback - // so let's do it this way 4 now. + var $shareTreeView = $('#app-sidebar .shareeTreeView'); + var shareTreeItems = ''; + + var template = + '
  • ' + + ' share_with_displayname
    ' + + ' path
    ' + + '
  • '; + + $shareTreeView.ready( function(){ + + // Remove content's + $shareTreeView.text('') self._chechPathHasShares().then(function(e) { - if (e) { - $('#fileList tr td.filename .thumbnail').addClass('sharetree-item') + + if (!e) return + + // Add share-tree icon to files and folders + $('#fileList tr td.filename .thumbnail').addClass('sharetree-item') + + // Add items to the sharefiev in the sidebar + if ($shareTreeView.length) { + self.getPathShareInfo( self.getCurrentDirectory() ).then( share => { + share.filter( share => share.shares.length).forEach( item => { + item.shares.forEach( share => { + shareTreeItems += template.replace(/share_with_displayname|path/g, key => share[key] ) + }) + }) + + $shareTreeView.append(`
      ${shareTreeItems}
    `) + }) } + }) - }, 250) + }) }, /** diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index ee4453769013..dc9c155ce3a5 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -29,9 +29,10 @@ '
    ' + ' ' + ' '+ - '{{{remoteShareInfo}}}' + + ' {{{remoteShareInfo}}}' + '
    ' + '
    ' + + '
    ' + '
    ' + ' ' + '
    ' + From 055dea2309a7bfc234369ad242cb0e66278fc509 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Wed, 23 Oct 2019 13:33:16 +0200 Subject: [PATCH 07/37] Adding icons and tree info in sidebar --- apps/files/css/files.css | 41 +++++++++++ apps/files/js/filelist.js | 114 +++++++++++++++++------------ core/js/sharedialoglinklistview.js | 3 + core/js/sharedialogview.js | 2 - 4 files changed, 112 insertions(+), 48 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 8e2e1bd3f3c7..532ee12c5c38 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -534,6 +534,47 @@ table td.filename .uploadtext { background-position: center; } +.shareTree { + border-top: 1px solid #eee; +} + +.shareTree-item { + margin: 10px 0; + position: relative; + cursor: pointer; +} + +.shareTree-item * { + cursor: pointer; +} + +.shareTree-item-avatar { + border-radius: 50%; + float: left; + margin-right: 10px; + transform: translateY(5px); +} + +.shareTree-item-icon { + display: block; + float: left; + transform: translateY(5px); +} + +.shareTree-item-name { + display: block; +} + +.shareTree-item-path { + display: block; +} + +.shareTree-item-path:before, +.shareTree-item-path:after { + content: '"'; +} + + /* Show checkbox when hovering, checked, or selected */ html.ie8 #fileList tr td.filename > .selectCheckBox:checked, html.ie8 #fileList tr.selected td.filename > .selectCheckBox, diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 9f7262f64ebc..dbb8e690c576 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 + */ + _shareTree: [], + /** * Whether to do a client side sort. * When false, clicking on a table header will call reload(). @@ -1076,6 +1083,11 @@ $(window).scrollTop(0); this.$fileList.trigger(jQuery.Event('updated')); + + this._setShareTree().then(function() { + $('#filestable').trigger(jQuery.Event('shareTreeSet')); + }); + _.defer(function() { self.$el.closest('#app-content').trigger(jQuery.Event('apprendered')); }); @@ -1363,7 +1375,8 @@ this.updateEmptyContent(); } - this._setSharedIcon() + this._setShareTreeIcons() + this._setShareTreeView() return $tr; }, @@ -1487,7 +1500,9 @@ } }); - this._setSharedIcon() + $('#filestable').on('shareTreeSet', function() { + self._setShareTreeIcons(); + }) }, linkTo: function(dir) { return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); @@ -1820,60 +1835,67 @@ return Promise.all(crumbs) }, - - _chechPathHasShares: function() { + _setShareTree: function() { let self = this; return this.getPathShareInfo(this.getCurrentDirectory()).then(function(path) { - - let sharedFolders = _.filter(path, function(dir) { + self._shareTree = _.filter(path, function(dir) { return dir.shares.length > 0 }) + }) + }, - if (sharedFolders.length > 0) - return true + _setShareTreeIcons: function() { + if (!this._shareTree.length) + return - return false - }) + // Add share-tree icon to files and folders + // each per in the table + $('#fileList tr td.filename .thumbnail:not(.sharetree-item)').addClass('sharetree-item') }, - - _setSharedIcon: function() { - var self = this; - var $shareTreeView = $('#app-sidebar .shareeTreeView'); - var shareTreeItems = ''; - - var template = - '
  • ' + - ' share_with_displayname
    ' + - ' path
    ' + - '
  • '; - - $shareTreeView.ready( function(){ - - // Remove content's - $shareTreeView.text('') - - self._chechPathHasShares().then(function(e) { - - if (!e) return - - // Add share-tree icon to files and folders - $('#fileList tr td.filename .thumbnail').addClass('sharetree-item') - - // Add items to the sharefiev in the sidebar - if ($shareTreeView.length) { - self.getPathShareInfo( self.getCurrentDirectory() ).then( share => { - share.filter( share => share.shares.length).forEach( item => { - item.shares.forEach( share => { - shareTreeItems += template.replace(/share_with_displayname|path/g, key => share[key] ) - }) - }) - $shareTreeView.append(`
      ${shareTreeItems}
    `) - }) - } + _setShareTreeView: function() { + var self = this; + var $shareTabView = $('#shareTabView .dialogContainer'); + var $shareTreeView = $('
    ', { class : 'shareTreeView' , html : '
      '}); - }) + $shareTabView.ready( function() { + + if (!self._shareTree.length) + return + + // Add items to the shareview in the sidebar ... if it's open + if (!$('#app-sidebar').hasClass('disappear')) { + + $shareTabView.append($shareTreeView) + + // Shared folders + self._shareTree.forEach( folder => { + + // Shares by folder + folder.shares.forEach( share => { + + let $path = $('', { class : 'shareTree-item-path', text : folder.name }) + + // user/group shares + if (share.share_type === 0) { + let $name = $('', { class : 'shareTree-item-name', text : share.share_with_displayname }) + let $avatar = $('
      ', { class : 'shareTree-item-avatar' }) + + $('
    • ').append( $avatar, $name, $path).appendTo($shareTreeView.find('> ul')) + $avatar.avatar(share.share_with, 32) + } + + // link shares + else if (share.share_type === 3) { + let $name = $('', { class : 'shareTree-item-name', text : share.name }) + let $icon = $('', { class : 'shareTree-item-icon link-entry--icon icon-public-white' }) + + $('
    • ').append( $icon, $name, $path).appendTo($shareTreeView.find('> ul')) + } + }) + }) + } }) }, diff --git a/core/js/sharedialoglinklistview.js b/core/js/sharedialoglinklistview.js index 4e1900687d76..a37b775142fa 100644 --- a/core/js/sharedialoglinklistview.js +++ b/core/js/sharedialoglinklistview.js @@ -51,6 +51,9 @@ '
      ' + ' ' + '
      ' + + '
      '+ + '
        ' + '
        ' + '
        {{privacyWarningMessage}}
        '; /** diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index dc9c155ce3a5..c19617420599 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -31,8 +31,6 @@ ' '+ ' {{{remoteShareInfo}}}' + '
      • ' + - '
        ' + - '
        ' + '
        ' + ' ' + '' + From f9387dd998cbcb6c63a24f004c89ef8235149dda Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Wed, 23 Oct 2019 14:16:38 +0200 Subject: [PATCH 08/37] Fix IE11 JS compatibility issues --- apps/files/js/filelist.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index dbb8e690c576..d5216d38af38 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1795,12 +1795,12 @@ } if (dir.shareTypes === undefined) { - Object.assign(shareInfo, { shares : [] }) + shareInfo.shares = [] resolve(shareInfo) } else { $.get( OC.linkToOCS('apps/files_sharing/api/v1', 2) + 'shares?' + OC.buildQueryString({format: 'json', path: (dir.path + '/' + dir.name)}), function(e) { - Object.assign(shareInfo, { shares : e.ocs.data }) + shareInfo.shares = e.ocs.data resolve(shareInfo) }) } @@ -1870,10 +1870,10 @@ $shareTabView.append($shareTreeView) // Shared folders - self._shareTree.forEach( folder => { + self._shareTree.forEach( function(folder) { // Shares by folder - folder.shares.forEach( share => { + folder.shares.forEach( function(share) { let $path = $('', { class : 'shareTree-item-path', text : folder.name }) From 774e8f3b5244358be52e3b1f49e4c7be5e80dd53 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Fri, 25 Oct 2019 13:37:44 +0200 Subject: [PATCH 09/37] Prevent reduntant API calls --- apps/files/js/filelist.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index d5216d38af38..b3efb3bd9b19 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1778,11 +1778,22 @@ getDirShareInfo: function(dir) { // Dir can't be empty if (typeof dir !== 'string' || dir.length === 0) { - console.error('getDirShareInfo(). param must be typeof string and can not be empty!') - return false + return Promise.reject('getDirShareInfo(). param must be typeof string and can not be empty!') + } + + // Shareinfo may already exist + var fromTree = this._shareTree.filter(function(item) { + return item.path === (dir !== '/') ? dir.replace(/\/$/, "") : '/' + }) + + // Return existing data + // avoiding a new API call + if (fromTree.length) { + return Promise.resolve(fromTree[0]) } - var client = this.filesClient + var self = this; + var client = this.filesClient; var options = { properties : ['{' + OC.Files.Client.NS_OWNCLOUD + '}share-types'] } @@ -1799,8 +1810,10 @@ resolve(shareInfo) } else { + // Fetch all shares for directory in question $.get( OC.linkToOCS('apps/files_sharing/api/v1', 2) + 'shares?' + OC.buildQueryString({format: 'json', path: (dir.path + '/' + dir.name)}), function(e) { shareInfo.shares = e.ocs.data + self._shareTree.push(shareInfo) resolve(shareInfo) }) } From 402cdeedcd532ef2ff70bbbd2d36459fffed4d18 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Fri, 25 Oct 2019 13:54:25 +0200 Subject: [PATCH 10/37] Adds OC.Apps.AppSidebarVisible() --- apps/files/js/filelist.js | 2 +- core/js/apps.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index b3efb3bd9b19..61a746e1fc4e 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1878,7 +1878,7 @@ return // Add items to the shareview in the sidebar ... if it's open - if (!$('#app-sidebar').hasClass('disappear')) { + if (OC.Apps.AppSidebarVisible()) { $shareTabView.append($shareTreeView) diff --git a/core/js/apps.js b/core/js/apps.js index d8f4bfdf1c54..64644458c0ae 100644 --- a/core/js/apps.js +++ b/core/js/apps.js @@ -44,6 +44,17 @@ $('#app-content').removeClass('with-app-sidebar').trigger(new $.Event('appresized')); }; + /** + * Check if sidebar is visible/hidden + * + * @param {Object} [$el] sidebar element to check, defaults to $('#app-sidebar') + */ + + exports.Apps.AppSidebarVisible = function($el) { + var $appSidebar = $el || $('#app-sidebar'); + return !$appSidebar.hasClass('disappear'); + }; + /** * Provides a way to slide down a target area through a button and slide it * up if the user clicks somewhere else. Used for the news app settings and From 9e155f3cf7fc01c53ac6e3fa2e4f426df01e8538 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Fri, 25 Oct 2019 15:42:14 +0200 Subject: [PATCH 11/37] Comment out code for shareIndicator (Usage TBD) --- apps/files/css/files.css | 10 ++++++++-- apps/files/js/filelist.js | 14 +++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 532ee12c5c38..23774f26d876 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -1031,13 +1031,19 @@ html.ie8 #controls .button.new { } /* - * Directory sharing indocator + * Directory sharing indicator * * #fff4cc - Background yellow * #d5c999 - Border dirty yellow * #927800 - Text dark dirty yellow */ + /* + --------------------------------------------------- + Keep the code, since final descision about + sharing indicator on the top right is still pending + --------------------------------------------------- + #controls #shareinfo_indicator { float: right; height: 32px; @@ -1079,4 +1085,4 @@ html.ie8 #controls .button.new { right: 7px; background: rebeccapurple; -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 61a746e1fc4e..c662a18d83c1 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -363,14 +363,21 @@ OC.Plugins.attach('OCA.Files.FileList', this); }, + /* + + --------------------------------------------------- + Keep the code, since final descision about + sharing indicator on the top right is still pending + --------------------------------------------------- + dirShareInfoIndicator: function () { var $el = $('#shareinfo_indicator') if ( !$el.length ) { - $el = $('
        ', { id : 'shareinfo_indicator' }); - $textbox = $('', { class : "text", text : t('core', 'shared') }) - $sharelist = $('
        ', { class : 'list', html : '
          ' }) + var $el = $('
          ', { id : 'shareinfo_indicator' }); + var $textbox = $('', { class : "text", text : t('core', 'shared') }) + var $sharelist = $('
          ', { class : 'list', html : '
            ' }) $el.append($textbox, $sharelist).appendTo($('#controls')).hide() } @@ -390,6 +397,7 @@ $el.find('.list ul').append('
          • Hallo
          • ') }); }, + */ /** * Destroy / uninitialize this instance. From 6606f0c19fce6e748f28bd456bc08bf88cb96cd6 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Fri, 25 Oct 2019 15:43:36 +0200 Subject: [PATCH 12/37] Minor cleanup --- apps/files/css/files.css | 50 +++++++++++++++++---------------------- apps/files/js/filelist.js | 10 ++++---- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 23774f26d876..8c3c7e4f462d 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -522,16 +522,16 @@ table td.filename .uploadtext { #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(../img/shareinfo.svg); - width: 14px; - height: 14px; - background-repeat: no-repeat; - background-position: center; + display: block; + content: ''; + bottom: 0px; + right: -5px; + z-index: 10; + background-image: url(../img/shareinfo.svg); + width: 14px; + height: 14px; + background-repeat: no-repeat; + background-position: center; } .shareTree { @@ -552,7 +552,7 @@ table td.filename .uploadtext { border-radius: 50%; float: left; margin-right: 10px; - transform: translateY(5px); + margin-top: 5px; } .shareTree-item-icon { @@ -569,12 +569,6 @@ table td.filename .uploadtext { display: block; } -.shareTree-item-path:before, -.shareTree-item-path:after { - content: '"'; -} - - /* Show checkbox when hovering, checked, or selected */ html.ie8 #fileList tr td.filename > .selectCheckBox:checked, html.ie8 #fileList tr.selected td.filename > .selectCheckBox, @@ -1044,11 +1038,11 @@ html.ie8 #controls .button.new { sharing indicator on the top right is still pending --------------------------------------------------- -#controls #shareinfo_indicator { + #controls #shareinfo_indicator { float: right; - height: 32px; - position: relative; - align-items: center; + height: 32px; + position: relative; + align-items: center; padding: 6px 7px 0 0; } @@ -1066,13 +1060,13 @@ html.ie8 #controls .button.new { #controls #shareinfo_indicator .text:after { content: ""; position: absolute; - width: 0; - height: 0; - border-style: solid; - border-width: 4px 4px 0 4px; - border-color: #927800 transparent transparent transparent; - right: 10px; - top: calc(50% - 2px); + width: 0; + height: 0; + border-style: solid; + border-width: 4px 4px 0 4px; + border-color: #927800 transparent transparent transparent; + right: 10px; + top: calc(50% - 2px); } #controls #shareinfo_indicator:not(:hover) .list { diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index c662a18d83c1..546a74618dd5 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1092,8 +1092,8 @@ this.$fileList.trigger(jQuery.Event('updated')); - this._setShareTree().then(function() { - $('#filestable').trigger(jQuery.Event('shareTreeSet')); + this._updateShareTree().then(function() { + $('#filestable').trigger(jQuery.Event('shareTreeUpdated')); }); _.defer(function() { @@ -1508,7 +1508,7 @@ } }); - $('#filestable').on('shareTreeSet', function() { + $('#filestable').on('shareTreeUpdated', function() { self._setShareTreeIcons(); }) }, @@ -1856,7 +1856,7 @@ return Promise.all(crumbs) }, - _setShareTree: function() { + _updateShareTree: function() { let self = this; return this.getPathShareInfo(this.getCurrentDirectory()).then(function(path) { @@ -1872,7 +1872,7 @@ // Add share-tree icon to files and folders // each per in the table - $('#fileList tr td.filename .thumbnail:not(.sharetree-item)').addClass('sharetree-item') + this.$el.find('#fileList tr td.filename .thumbnail:not(.sharetree-item)').addClass('sharetree-item') }, _setShareTreeView: function() { From e900982d9257f73d650615a8890d4950c48609c9 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Fri, 25 Oct 2019 17:08:00 +0200 Subject: [PATCH 13/37] Revert templates changes made in dialogviews --- core/js/sharedialoglinklistview.js | 3 --- core/js/sharedialogview.js | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/core/js/sharedialoglinklistview.js b/core/js/sharedialoglinklistview.js index a37b775142fa..4e1900687d76 100644 --- a/core/js/sharedialoglinklistview.js +++ b/core/js/sharedialoglinklistview.js @@ -51,9 +51,6 @@ '
            ' + ' ' + '
            ' + - '
            '+ - '
              ' - '
              ' + '
              {{privacyWarningMessage}}
              '; /** diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index c19617420599..ee4453769013 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -29,8 +29,9 @@ '
              ' + ' ' + ' '+ - ' {{{remoteShareInfo}}}' + + '{{{remoteShareInfo}}}' + '
              ' + + '
              ' + '
              ' + ' ' + '
              ' + From 996b880f231f02627b53522924d2d38125952f5a Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Mon, 28 Oct 2019 16:01:47 +0100 Subject: [PATCH 14/37] Store shareInfo by path as key --- apps/files/js/filelist.js | 72 ++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 546a74618dd5..ccb58fc513e1 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -173,7 +173,7 @@ * * @type Array */ - _shareTree: [], + _shareTree: {}, /** * Whether to do a client side sort. @@ -1508,7 +1508,7 @@ } }); - $('#filestable').on('shareTreeUpdated', function() { + $('#filestable').one('shareTreeUpdated', function() { self._setShareTreeIcons(); }) }, @@ -1789,15 +1789,13 @@ return Promise.reject('getDirShareInfo(). param must be typeof string and can not be empty!') } - // Shareinfo may already exist - var fromTree = this._shareTree.filter(function(item) { - return item.path === (dir !== '/') ? dir.replace(/\/$/, "") : '/' - }) + if (dir !== '/') + dir = dir.replace(/\/$/, "") // Return existing data // avoiding a new API call - if (fromTree.length) { - return Promise.resolve(fromTree[0]) + if (typeof this._shareTree[dir] !== 'undefined') { + return Promise.resolve(this._shareTree[dir]) } var self = this; @@ -1820,9 +1818,8 @@ else { // Fetch all shares for directory in question $.get( OC.linkToOCS('apps/files_sharing/api/v1', 2) + 'shares?' + OC.buildQueryString({format: 'json', path: (dir.path + '/' + dir.name)}), function(e) { - shareInfo.shares = e.ocs.data - self._shareTree.push(shareInfo) - resolve(shareInfo) + self._shareTree[e.ocs.data[0].path] = e.ocs.data + resolve(e.ocs.data) }) } }).fail(function(error) { @@ -1856,18 +1853,31 @@ return Promise.all(crumbs) }, - _updateShareTree: function() { - let self = this; + /** + * Check if dir is (sub)shared + * @param {String} dir to check + * @return {Boolen} + */ - return this.getPathShareInfo(this.getCurrentDirectory()).then(function(path) { - self._shareTree = _.filter(path, function(dir) { - return dir.shares.length > 0 - }) - }) + partOfSharePath: function(dir) { + var highShare = Object.keys(this._shareTree)[0] + var dir = (dir) ? dir : this.getCurrentDirectory() + + // Don't check root as + // it can't be shared + if (dir === '/') + return false + + return dir.indexOf(highShare) > -1 + }, + + _updateShareTree: function() { + return this.getPathShareInfo(this.getCurrentDirectory()) }, _setShareTreeIcons: function() { - if (!this._shareTree.length) + + if (!this.partOfSharePath()) return // Add share-tree icon to files and folders @@ -1876,27 +1886,33 @@ }, _setShareTreeView: function() { - var self = this; - var $shareTabView = $('#shareTabView .dialogContainer'); - var $shareTreeView = $('
              ', { class : 'shareTreeView' , html : '
                '}); + var self = this; + var $shareTabView = $('#shareTabView .dialogContainer'); + var $shareTreeView = $('
                ', { class : 'shareTreeView' , html : '
                  '}); + var $shareTreeViewDescription = $('

                  ', { class: 'shareTree-description', text : t('core', 'This item is part of the following shares:')}) $shareTabView.ready( function() { - if (!self._shareTree.length) + if (!self.partOfSharePath()) return - // Add items to the shareview in the sidebar ... if it's open if (OC.Apps.AppSidebarVisible()) { - $shareTabView.append($shareTreeView) + $shareTabView.append($shareTreeViewDescription, $shareTreeView) // Shared folders - self._shareTree.forEach( function(folder) { + _.each(self._shareTree, function(folder) { // Shares by folder - folder.shares.forEach( function(share) { + _.each(folder, function(share) { + + // Do not display shares deeper + // in the shareTree than current dir + if(share.path.length > self.getCurrentDirectory().length) + return - let $path = $('', { class : 'shareTree-item-path', text : folder.name }) + let dirName = share.path.substr(_.lastIndexOf(share.path, '/') + 1) + let $path = $('', { class : 'shareTree-item-path', text : dirName }) // user/group shares if (share.share_type === 0) { From ea7a0c208787034094d64f25617f1338379ec3f2 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Mon, 28 Oct 2019 16:12:38 +0100 Subject: [PATCH 15/37] Use existing share icon in file indicator --- apps/files/css/files.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 8c3c7e4f462d..6dc021f114d0 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -527,11 +527,14 @@ table td.filename .uploadtext { bottom: 0px; right: -5px; z-index: 10; - background-image: url(../img/shareinfo.svg); + 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%; } .shareTree { From 7e66f37ebb3b16077e631df220de0fde32ba25e7 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Mon, 28 Oct 2019 16:22:47 +0100 Subject: [PATCH 16/37] Prevent adding shareTabView multiple times --- apps/files/js/filelist.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index ccb58fc513e1..ce6dd38e3f54 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1896,7 +1896,7 @@ if (!self.partOfSharePath()) return - if (OC.Apps.AppSidebarVisible()) { + if (OC.Apps.AppSidebarVisible() && !$shareTabView.find('.shareTreeView').length) { $shareTabView.append($shareTreeViewDescription, $shareTreeView) From ebcc07c9c74fefe0cd2803b94caaac34ed371df1 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Tue, 29 Oct 2019 14:59:46 +0100 Subject: [PATCH 17/37] Remove unused methods and styles --- apps/files/css/files.css | 57 --------------------------------------- apps/files/js/filelist.js | 36 ------------------------- 2 files changed, 93 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 6dc021f114d0..5d4f2e3f62ed 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -1026,60 +1026,3 @@ html.ie8 #controls .button.new { position: inherit; right: inherit; } - -/* - * Directory sharing indicator - * - * #fff4cc - Background yellow - * #d5c999 - Border dirty yellow - * #927800 - Text dark dirty yellow - */ - - /* - --------------------------------------------------- - Keep the code, since final descision about - sharing indicator on the top right is still pending - --------------------------------------------------- - - #controls #shareinfo_indicator { - float: right; - height: 32px; - position: relative; - align-items: center; - padding: 6px 7px 0 0; -} - -#controls #shareinfo_indicator .text { - display: block; - background-color: #fff4cc; - border: 1px solid #d5c999; - border-radius: 3px; - color: #927800; - padding: 4px 30px 4px 12px; - position: relative; - cursor: pointer; -} - -#controls #shareinfo_indicator .text:after { - content: ""; - position: absolute; - width: 0; - height: 0; - border-style: solid; - border-width: 4px 4px 0 4px; - border-color: #927800 transparent transparent transparent; - right: 10px; - top: calc(50% - 2px); -} - -#controls #shareinfo_indicator:not(:hover) .list { - display: none; -} - -#controls #shareinfo_indicator .list { - position: absolute; - top: 42px; - right: 7px; - - background: rebeccapurple; -} */ \ No newline at end of file diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index ce6dd38e3f54..97364c3a13dd 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -363,42 +363,6 @@ OC.Plugins.attach('OCA.Files.FileList', this); }, - /* - - --------------------------------------------------- - Keep the code, since final descision about - sharing indicator on the top right is still pending - --------------------------------------------------- - - dirShareInfoIndicator: function () { - var $el = $('#shareinfo_indicator') - - if ( !$el.length ) { - - var $el = $('

                  ', { id : 'shareinfo_indicator' }); - var $textbox = $('', { class : "text", text : t('core', 'shared') }) - var $sharelist = $('
                  ', { class : 'list', html : '
                    ' }) - - $el.append($textbox, $sharelist).appendTo($('#controls')).hide() - } - - this.getPathShareInfo(this.getCurrentDirectory()).then(function(path) { - var shares = path.filter( function(dir) { - return dir.shareTypes.length > 0 - }) - - // Stop if there are no shares present - if (shares.length === 0) { - $el.fadeOut('fast') - return - } - - $el.fadeIn('fast') - $el.find('.list ul').append('
                  • Hallo
                  • ') - }); - }, - */ - /** * Destroy / uninitialize this instance. */ From c5ff1a61170f1c763a7b5382d68011fc3ea837fd Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Wed, 30 Oct 2019 09:46:31 +0100 Subject: [PATCH 18/37] Propper share_type check --- apps/files/js/filelist.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 97364c3a13dd..a3000549d207 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1879,7 +1879,7 @@ let $path = $('', { class : 'shareTree-item-path', text : dirName }) // user/group shares - if (share.share_type === 0) { + if (share.share_type === OC.Share.SHARE_TYPE_USER || share.share_type === OC.Share.SHARE_TYPE_GROUP) { let $name = $('', { class : 'shareTree-item-name', text : share.share_with_displayname }) let $avatar = $('
                    ', { class : 'shareTree-item-avatar' }) @@ -1888,7 +1888,7 @@ } // link shares - else if (share.share_type === 3) { + else if (share.share_type === OC.Share.SHARE_TYPE_LINK) { let $name = $('', { class : 'shareTree-item-name', text : share.name }) let $icon = $('', { class : 'shareTree-item-icon link-entry--icon icon-public-white' }) From 9509462aa17313369c406d191bf99c770b148147 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Wed, 30 Oct 2019 09:49:49 +0100 Subject: [PATCH 19/37] Add icon on rendering-row --- apps/files/js/filelist.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index a3000549d207..9da38efa42ad 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1347,7 +1347,6 @@ this.updateEmptyContent(); } - this._setShareTreeIcons() this._setShareTreeView() return $tr; @@ -1404,6 +1403,10 @@ tr.addClass('hidden-file'); } + if(this.partOfSharePath()) { + filenameTd.find('.thumbnail:not(.sharetree-item)').addClass('sharetree-item'); + } + // display actions this.fileActions.display(filenameTd, !options.silent, this); @@ -1840,13 +1843,13 @@ }, _setShareTreeIcons: function() { - if (!this.partOfSharePath()) return // Add share-tree icon to files and folders // each per in the table - this.$el.find('#fileList tr td.filename .thumbnail:not(.sharetree-item)').addClass('sharetree-item') + this.$fileList.find('tr td.filename .thumbnail:not(.sharetree-item)').addClass('sharetree-item') + }, _setShareTreeView: function() { From c8941e313cee0d6587eae1907a48e80466ccf4f0 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Wed, 30 Oct 2019 09:56:24 +0100 Subject: [PATCH 20/37] Delete shareinfo.svg --- apps/files/img/shareinfo.svg | 1 - 1 file changed, 1 deletion(-) delete mode 100644 apps/files/img/shareinfo.svg diff --git a/apps/files/img/shareinfo.svg b/apps/files/img/shareinfo.svg deleted file mode 100644 index 381ceb2c0613..000000000000 --- a/apps/files/img/shareinfo.svg +++ /dev/null @@ -1 +0,0 @@ -shareinfo \ No newline at end of file From 43f7a32f3241d2a97f89ec8829acb61352c92162 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Wed, 30 Oct 2019 16:11:40 +0100 Subject: [PATCH 21/37] Rework shareTreeCache --- apps/files/js/filelist.js | 100 ++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 58 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 9da38efa42ad..c7cddf8acd2d 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -173,7 +173,7 @@ * * @type Array */ - _shareTree: {}, + _shareTreeCache: {}, /** * Whether to do a client side sort. @@ -1056,10 +1056,6 @@ this.$fileList.trigger(jQuery.Event('updated')); - this._updateShareTree().then(function() { - $('#filestable').trigger(jQuery.Event('shareTreeUpdated')); - }); - _.defer(function() { self.$el.closest('#app-content').trigger(jQuery.Event('apprendered')); }); @@ -1403,7 +1399,7 @@ tr.addClass('hidden-file'); } - if(this.partOfSharePath()) { + if(_.keys(this._shareTreeCache).length) { filenameTd.find('.thumbnail:not(.sharetree-item)').addClass('sharetree-item'); } @@ -1475,7 +1471,7 @@ } }); - $('#filestable').one('shareTreeUpdated', function() { + this._updateShareTree().then(function() { self._setShareTreeIcons(); }) }, @@ -1756,15 +1752,14 @@ return Promise.reject('getDirShareInfo(). param must be typeof string and can not be empty!') } - if (dir !== '/') - dir = dir.replace(/\/$/, "") - - // Return existing data - // avoiding a new API call - if (typeof this._shareTree[dir] !== 'undefined') { - return Promise.resolve(this._shareTree[dir]) + // 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 = { @@ -1773,20 +1768,18 @@ return new Promise( function(resolve, reject) { client.getFileInfo(dir, options).done(function(s, dir) { - var shareInfo = { - name : dir.name, - path : dir.path - } - if (dir.shareTypes === undefined) { - shareInfo.shares = [] - resolve(shareInfo) - } - else { + var glue = (dir.path === '/') ? '' : '/' + var path = dir.path + glue + 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: (dir.path + '/' + dir.name)}), function(e) { - self._shareTree[e.ocs.data[0].path] = e.ocs.data - resolve(e.ocs.data) + $.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() }) } }).fail(function(error) { @@ -1814,42 +1807,39 @@ for (var i = 0; i < parts.length; i++) { var part = parts[i]; pathToHere += part + '/'; + crumbs.push(this.getDirShareInfo(pathToHere)) } return Promise.all(crumbs) }, - /** - * Check if dir is (sub)shared - * @param {String} dir to check - * @return {Boolen} - */ - - partOfSharePath: function(dir) { - var highShare = Object.keys(this._shareTree)[0] - var dir = (dir) ? dir : this.getCurrentDirectory() + _updateShareTree: function() { + var self = this; + var dir = this.getCurrentDirectory(); - // Don't check root as - // it can't be shared - if (dir === '/') - return false + // Purge shareTreeCache in root dir + if (dir === '/') { + this._shareTreeCache = {} + return Promise.resolve() + } - return dir.indexOf(highShare) > -1 - }, + return this.getPathShareInfo(dir).then(() => { - _updateShareTree: function() { - return this.getPathShareInfo(this.getCurrentDirectory()) + // Purge deeper children + _.each(self._shareTreeCache, function(path, key) { + if (key > dir) { + console.log('Removing', key) + delete self._shareTreeCache[key] + } + }) + }) }, _setShareTreeIcons: function() { - if (!this.partOfSharePath()) - return - // Add share-tree icon to files and folders // each per in the table this.$fileList.find('tr td.filename .thumbnail:not(.sharetree-item)').addClass('sharetree-item') - }, _setShareTreeView: function() { @@ -1860,26 +1850,20 @@ $shareTabView.ready( function() { - if (!self.partOfSharePath()) - return + if (! _.keys(self._shareTreeCache).length > 0) + return if (OC.Apps.AppSidebarVisible() && !$shareTabView.find('.shareTreeView').length) { $shareTabView.append($shareTreeViewDescription, $shareTreeView) // Shared folders - _.each(self._shareTree, function(folder) { + _.each(self._shareTreeCache, function(folder) { // Shares by folder - _.each(folder, function(share) { - - // Do not display shares deeper - // in the shareTree than current dir - if(share.path.length > self.getCurrentDirectory().length) - return + _.each(folder.shares, function(share) { - let dirName = share.path.substr(_.lastIndexOf(share.path, '/') + 1) - let $path = $('', { class : 'shareTree-item-path', text : dirName }) + let $path = $('', { class : 'shareTree-item-path', text : folder.name }) // user/group shares if (share.share_type === OC.Share.SHARE_TYPE_USER || share.share_type === OC.Share.SHARE_TYPE_GROUP) { From 410f6efe9ebd2fdd64df9ec4644c63379a493e9e Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Mon, 4 Nov 2019 15:50:18 +0100 Subject: [PATCH 22/37] Add info (i) about shareTree Open share by clicking on shareTree item --- apps/files/css/files.css | 4 +++ apps/files/js/filelist.js | 56 +++++++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 5d4f2e3f62ed..da4aa14b0afc 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -568,6 +568,10 @@ table td.filename .uploadtext { display: block; } +.shareTree-description .icon.icon-info { + transform: translate(5px, 3px); +} + .shareTree-item-path { display: block; } diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index c7cddf8acd2d..a9a1d30157a5 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1459,20 +1459,27 @@ 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() + }); - this._updateShareTree().then(function() { - self._setShareTreeIcons(); + self._updateShareTree().then(function() { + self._setShareTreeIcons(); + }) }) }, linkTo: function(dir) { @@ -1829,7 +1836,6 @@ // Purge deeper children _.each(self._shareTreeCache, function(path, key) { if (key > dir) { - console.log('Removing', key) delete self._shareTreeCache[key] } }) @@ -1847,6 +1853,7 @@ var $shareTabView = $('#shareTabView .dialogContainer'); var $shareTreeView = $('
                    ', { class : 'shareTreeView' , html : '
                      '}); var $shareTreeViewDescription = $('

                      ', { class: 'shareTree-description', text : t('core', 'This item is part of the following shares:')}) + var $shareTreeViewInfobox = $('', { class : 'icon icon-info', title : t('core', 'This items i accessible to others via shares listed below. Click on the item to navigate to the share.')}).tooltip() $shareTabView.ready( function() { @@ -1855,7 +1862,7 @@ if (OC.Apps.AppSidebarVisible() && !$shareTabView.find('.shareTreeView').length) { - $shareTabView.append($shareTreeViewDescription, $shareTreeView) + $shareTabView.append($shareTreeViewDescription.append($shareTreeViewInfobox), $shareTreeView) // Shared folders _.each(self._shareTreeCache, function(folder) { @@ -1863,24 +1870,27 @@ // Shares by folder _.each(folder.shares, function(share) { - let $path = $('', { class : 'shareTree-item-path', text : folder.name }) + var $path = $('', { class : 'shareTree-item-path', text : folder.name }) // user/group shares if (share.share_type === OC.Share.SHARE_TYPE_USER || share.share_type === OC.Share.SHARE_TYPE_GROUP) { - let $name = $('', { class : 'shareTree-item-name', text : share.share_with_displayname }) - let $avatar = $('

                      ', { class : 'shareTree-item-avatar' }) + var $name = $('', { class : 'shareTree-item-name', text : share.share_with_displayname }) + var $icon = $('
                      ', { class : 'shareTree-item-avatar' }) - $('
                    • ').append( $avatar, $name, $path).appendTo($shareTreeView.find('> ul')) - $avatar.avatar(share.share_with, 32) + $icon.avatar(share.share_with, 32) } // link shares else if (share.share_type === OC.Share.SHARE_TYPE_LINK) { - let $name = $('', { class : 'shareTree-item-name', text : share.name }) - let $icon = $('', { class : 'shareTree-item-icon link-entry--icon icon-public-white' }) - - $('
                    • ').append( $icon, $name, $path).appendTo($shareTreeView.find('> ul')) + var $name = $('', { class : 'shareTree-item-name', text : share.name }) + var $icon = $('', { class : 'shareTree-item-icon link-entry--icon icon-public-white' }) } + + $('
                    • ').append( $icon, $name, $path).appendTo($shareTreeView.find('> ul')).click(() => { + self.changeDirectory(share.path.replace(folder.name, ''), true).then(function() { + self._updateDetailsView(folder.name, true) + }).catch(e => console.error(e)) + }) }) }) } From 1da9ff069dbd2d7ee3c8ec9e898bc90f27c50949 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Mon, 4 Nov 2019 16:08:27 +0100 Subject: [PATCH 23/37] Use build in functions --- apps/files/js/filelist.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index a9a1d30157a5..a91042758355 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1776,8 +1776,7 @@ return new Promise( function(resolve, reject) { client.getFileInfo(dir, options).done(function(s, dir) { - var glue = (dir.path === '/') ? '' : '/' - var path = dir.path + glue + dir.name + var path = OC.joinPaths(dir.path, dir.name) if (dir.shareTypes !== undefined) { // Fetch all shares for directory in question From fc593bc164b82d29bc85593b950d36d202314b38 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Mon, 4 Nov 2019 16:27:33 +0100 Subject: [PATCH 24/37] Propper diff cache and current dir --- apps/files/js/filelist.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index a91042758355..2f109e1746a8 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1788,6 +1788,9 @@ resolve() }) } + else { + resolve() + } }).fail(function(error) { reject(error) }) @@ -1831,13 +1834,14 @@ } return this.getPathShareInfo(dir).then(() => { + var breadcrumbs = dir.split('/') - // Purge deeper children - _.each(self._shareTreeCache, function(path, key) { - if (key > dir) { - delete self._shareTreeCache[key] - } - }) + // Diff keys in shareTreeCache agains the current dir + // removing deeper nested shares + self._shareTreeCache = _.omit(self._shareTreeCache, function(value, key) { + var diffs = _.difference(key.split('/'), breadcrumbs) + return diffs.length > 0 + }); }) }, From 922bb99db4345873413f426718fa1fe67533fe15 Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Mon, 4 Nov 2019 16:46:34 +0100 Subject: [PATCH 25/37] Fix typos --- apps/files/js/filelist.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 2f109e1746a8..9d2b1be71669 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1856,7 +1856,7 @@ var $shareTabView = $('#shareTabView .dialogContainer'); var $shareTreeView = $('
                      ', { class : 'shareTreeView' , html : '
                        '}); var $shareTreeViewDescription = $('

                        ', { class: 'shareTree-description', text : t('core', 'This item is part of the following shares:')}) - var $shareTreeViewInfobox = $('', { class : 'icon icon-info', title : t('core', 'This items i accessible to others via shares listed below. Click on the item to navigate to the share.')}).tooltip() + var $shareTreeViewInfobox = $('', { class : 'icon icon-info', title : t('core', 'This item is accessible to others via shares listed below. Click on the item to navigate to the share.')}).tooltip() $shareTabView.ready( function() { From 9de5f647f5eaf511578552c2c98967b6c550b70b Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Tue, 12 Nov 2019 21:11:23 +0100 Subject: [PATCH 26/37] Add event system OCE --- core/js/events.js | 116 ++++++++++++++++++++++++++++++++ lib/private/legacy/template.php | 1 + 2 files changed, 117 insertions(+) create mode 100644 core/js/events.js diff --git a/core/js/events.js b/core/js/events.js new file mode 100644 index 000000000000..0193f97beaa7 --- /dev/null +++ b/core/js/events.js @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2019 Felix Heidecke + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +/** @namespace */ + +var OCE = { + + _queue : [], + + /** + * Trigger callbacks corresponding to events + * + * @param {String} event event name + * @param {Object} payload data to be used in the callback + * + */ + emit : function (event, payload) { + var self = this; + payload = payload || {} + + let listeners = _.where(this._queue, { + event : event + }) + + _.each(listeners, function(listener) { + listener.callback(payload) + + console.log('%cOCE.emit', self._style('emit'), '🏃‍♂️', event) + + if (listener.once) + self.off(event, listener.callback.name) + }) + }, + + /** + * Add eventlistener + * + * @param {String} event event name + * @param {Object} callback function to be run on emit. Expects a function name + * @param {Boolean} once remove listener after emit + * + */ + on: function(event, callback, once) { + once = once || false; + + if (callback.name.length === 0) { + console.error('OCE error:', '❌', 'No name for callback supplied.') + return + } + + else if (!!_.findWhere(this._queue, { event : event, name : callback.name })) { + console.warn('OCE warning:', '😵', callback.name + ' already exists for ' + event + '.') + return + } + + console.log('%cOCE.on', this._style('on'), event, callback.name) + + this._queue.push({ + event : event, + name : callback.name, + callback : callback, + once : once + }) + }, + + /** + * Remove eventlistener + * + * @param {String} event event name + * @param {Object} callback function to be removed + * + */ + off: function(event, name) { + console.log('%cOCE.off', this._style('off'), event, name) + + this._queue = _.reject(this._queue, { + event: event, + name : name + }) + }, + + _style: function(type) { + var style = ['padding: 0 5px'] + + switch (type) { + case 'emit': + style.push('background: yellow') + break; + + case 'on': + style.push('background: lime') + break; + + case 'off': + style.push('background: crimson', 'color: white') + break; + + default: + style.push('background: gray') + break; + } + + return style.join(';') + }, + + eventList() { + return this._queue + } +}; \ No newline at end of file diff --git a/lib/private/legacy/template.php b/lib/private/legacy/template.php index 6253dd99176f..2647d882ef24 100644 --- a/lib/private/legacy/template.php +++ b/lib/private/legacy/template.php @@ -133,6 +133,7 @@ public static function initTemplateEngine($renderAs) { \OC_Util::addScript('placeholder', null, true); } + OC_Util::addScript('events', null, true); OC_Util::addScript('oc-backbone-webdav', null, true); OC_Util::addScript('oc-backbone', null, true); OC_Util::addVendorScript('core', 'backbone/backbone', true); From 0c9614b1a5bf10bb72de064fd73058950f1106bb Mon Sep 17 00:00:00 2001 From: Felix Heidecke Date: Tue, 12 Nov 2019 21:13:20 +0100 Subject: [PATCH 27/37] Separate user/group- and link-shares in sidebar --- apps/files/css/files.css | 39 ---------- apps/files/js/filelist.js | 95 +++++++++++++++---------- apps/files_sharing/css/sharetabview.css | 31 ++++++++ core/js/sharedialogview.js | 3 + 4 files changed, 93 insertions(+), 75 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index da4aa14b0afc..f9c47737a0b1 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -537,45 +537,6 @@ table td.filename .uploadtext { border-radius: 50%; } -.shareTree { - border-top: 1px solid #eee; -} - -.shareTree-item { - margin: 10px 0; - position: relative; - cursor: pointer; -} - -.shareTree-item * { - cursor: pointer; -} - -.shareTree-item-avatar { - border-radius: 50%; - float: left; - margin-right: 10px; - margin-top: 5px; -} - -.shareTree-item-icon { - display: block; - float: left; - transform: translateY(5px); -} - -.shareTree-item-name { - display: block; -} - -.shareTree-description .icon.icon-info { - transform: translate(5px, 3px); -} - -.shareTree-item-path { - display: block; -} - /* Show checkbox when hovering, checked, or selected */ html.ie8 #fileList tr td.filename > .selectCheckBox:checked, html.ie8 #fileList tr.selected td.filename > .selectCheckBox, diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 9d2b1be71669..2605e872d93f 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -360,6 +360,15 @@ } } + // Setup event listeners + OCE.on('linkShareViewRendered', setShareTreeLinkView = function() { + self._setShareTreeLinkView() + }); + + OCE.on('shareeListViewRendered', setShareTreeLinkView = function() { + self._setShareTreeUserGroupView() + }); + OC.Plugins.attach('OCA.Files.FileList', this); }, @@ -386,6 +395,7 @@ // remove summary this.$el.find('tfoot tr.summary').remove(); this.$fileList.empty(); + }, /** @@ -1343,8 +1353,6 @@ this.updateEmptyContent(); } - this._setShareTreeView() - return $tr; }, @@ -1851,52 +1859,67 @@ this.$fileList.find('tr td.filename .thumbnail:not(.sharetree-item)').addClass('sharetree-item') }, - _setShareTreeView: function() { - var self = this; - var $shareTabView = $('#shareTabView .dialogContainer'); - var $shareTreeView = $('

                        ', { class : 'shareTreeView' , html : '
                          '}); - var $shareTreeViewDescription = $('

                          ', { class: 'shareTree-description', text : t('core', 'This item is part of the following shares:')}) - var $shareTreeViewInfobox = $('', { class : 'icon icon-info', title : t('core', 'This item is accessible to others via shares listed below. Click on the item to navigate to the share.')}).tooltip() + _setShareTreeUserGroupView: function() { + var self = this; + var $list = $('