From 580e5b95603a34d79d1ad8a6727d603ff2583bba Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 10 Jun 2020 15:43:01 +0200 Subject: [PATCH 1/7] temp --- www/common/outer/userObject.js | 2 ++ www/common/proxy-manager.js | 20 ++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index 9d5740113..295498641 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -147,6 +147,7 @@ define([ var fd = exp.isSharedFolder(id) ? files[SHARED_FOLDERS][id] : exp.getFileData(id); var channelId = fd.channel; // If trying to remove an owned pad, remove it from server also + /* if (!sharedFolder && fd.owners && fd.owners.indexOf(edPublic) !== -1 && channelId) { if (channelId) { ownedRemoved.push(channelId); } @@ -168,6 +169,7 @@ define([ removeOwnedChannel(fd.rtChannel, function () {}); } } + */ if (fd.lastVersion) { toClean.push(Hash.hrefToHexChannelId(fd.lastVersion)); } if (fd.rtChannel) { toClean.push(fd.rtChannel); } if (channelId) { toClean.push(channelId); } diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index df46cb884..3df00d023 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -704,6 +704,8 @@ define([ }; // Delete permanently some pads or folders + var _deleteOwned = function (Env, data, cb) { + }; var _delete = function (Env, data, cb) { data = data || {}; var resolved = _resolvePaths(Env, data.paths); @@ -742,8 +744,8 @@ define([ }); }); } - uo.delete(resolved.main, waitFor(function (err, _toUnpin, _ownedRemoved) { - ownedRemoved = _ownedRemoved; + uo.delete(resolved.main, waitFor(function (err, _toUnpin/*, _ownedRemoved*/) { + //ownedRemoved = _ownedRemoved; if (!Env.unpinPads || !_toUnpin) { return; } Array.prototype.push.apply(toUnpin, _toUnpin); })); @@ -752,7 +754,7 @@ define([ // Check if removed owned pads are duplicated in some shared folders // If that's the case, we have to remove them from the shared folders too // We can do that by adding their paths to the list of pads to remove from shared folders - if (ownedRemoved) { + /*if (ownedRemoved) { var ids = _findChannels(Env, ownedRemoved); ids.forEach(function (id) { var paths = findFile(Env, id); @@ -765,7 +767,7 @@ define([ } }); }); - } + }*/ // Delete paths from the shared folders Object.keys(resolved.folders).forEach(function (id) { Env.folders[id].userObject.delete(resolved.folders[id], waitFor(function (err, _toUnpin) { @@ -1140,6 +1142,7 @@ define([ getChannelsList: callWithEnv(getChannelsList), addPad: callWithEnv(addPad), delete: callWithEnv(_delete), + deleteOwned: callWithEnv(_deleteOwned), // Tools findChannel: callWithEnv(findChannel), findHref: callWithEnv(findHref), @@ -1228,6 +1231,14 @@ define([ } }, cb); }; + var deleteOwnedInner = function (Env, paths, cb) { + return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", { + cmd: "deleteOwned", + data: { + paths: paths, + } + }, cb); + }; var restoreInner = function (Env, path, cb) { return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", { cmd: "restore", @@ -1416,6 +1427,7 @@ define([ restoreSharedFolder: callWithEnv(restoreSharedFolderInner), convertFolderToSharedFolder: callWithEnv(convertFolderToSharedFolderInner), delete: callWithEnv(deleteInner), + deleteOwned: callWithEnv(deleteOwnedInner), restore: callWithEnv(restoreInner), setFolderData: callWithEnv(setFolderDataInner), // Tools From 84f1ea7bfb3af95c1abe6cf49a48534cefa2cab3 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 12 Jun 2020 15:49:50 +0200 Subject: [PATCH 2/7] Allow user to remove owned pads from the drive without deleting them --- www/common/drive-ui.js | 41 +++++------------- www/common/outer/async-store.js | 2 +- www/common/outer/team.js | 6 +-- www/common/outer/userObject.js | 3 +- www/common/proxy-manager.js | 77 ++++++++++++++++++++++++++++++--- 5 files changed, 88 insertions(+), 41 deletions(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 93c36597a..37d47a96d 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -447,19 +447,19 @@ define([ h('li', h('a.cp-app-drive-context-delete.dropdown-item.cp-app-drive-context-editable', { 'tabindex': '-1', 'data-icon': faTrash, - }, Messages.fc_delete)), + }, Messages.fc_delete)), // "Move to trash" h('li', h('a.cp-app-drive-context-deleteowned.dropdown-item.cp-app-drive-context-editable', { 'tabindex': '-1', 'data-icon': faDelete, - }, Messages.fc_delete_owned)), + }, Messages.fc_delete_owned)), // XXX update key? "Delete from the server" h('li', h('a.cp-app-drive-context-remove.dropdown-item.cp-app-drive-context-editable', { 'tabindex': '-1', - 'data-icon': faDelete, - }, Messages.fc_remove)), + 'data-icon': faTrash, + }, Messages.fc_remove)), // XXX update key? "Remove from your CryptDrive" h('li', h('a.cp-app-drive-context-removesf.dropdown-item.cp-app-drive-context-editable', { 'tabindex': '-1', - 'data-icon': faDelete, - }, Messages.fc_remove_sharedfolder)), + 'data-icon': faTrash, + }, Messages.fc_remove_sharedfolder)), // XXX update key? "Remove" $separator.clone()[0], h('li', h('a.cp-app-drive-context-properties.dropdown-item', { 'tabindex': '-1', @@ -1279,18 +1279,12 @@ define([ // If we're not in the trash nor in a shared folder, hide "remove" if (!manager.isInSharedFolder(path) && !$element.is('.cp-app-drive-element-sharedf')) { + // This isn't a shared folder: can't delete shared folder hide.push('removesf'); } else if (type === "tree") { + // This is a shared folder or an element inside a shsared folder + // ==> can't move to trash hide.push('delete'); - // Don't hide the deleteowned link if the element is a shared folder and - // it is owned - if (manager.isInSharedFolder(path) || - !$element.is('.cp-app-drive-element-owned')) { - hide.push('deleteowned'); - } else { - // This is a shared folder and it is owned - hide.push('removesf'); - } } if ($element.closest('[data-ro]').length) { editable = false; @@ -1657,22 +1651,11 @@ define([ if (paths) { paths.forEach(function (p) { pathsList.push(p.path); }); } - var hasOwned = pathsList.some(function (p) { - // NOTE: Owned pads in shared folders won't be removed from the server - // so we don't have to check, we can use the default message - if (manager.isInSharedFolder(p)) { return false; } - - var el = manager.find(p); - var data = manager.isSharedFolder(el) ? manager.getSharedFolderData(el) - : manager.getFileData(el); - return data.owners && data.owners.indexOf(edPublic) !== -1; - }); var msg = Messages._getKey("fm_removeSeveralPermanentlyDialog", [pathsList.length]); if (pathsList.length === 1) { - msg = hasOwned ? Messages.fm_deleteOwnedPad : Messages.fm_removePermanentlyDialog; - } else if (hasOwned) { - msg = msg + '
' + Messages.fm_removePermanentlyNote + ''; + msg = Messages.fm_removePermanentlyDialog; } + // XXX update key to tell the user that these pads will still be avialble to other users UI.confirm(msg, function(res) { $(window).focus(); if (!res) { return; } @@ -3995,7 +3978,7 @@ define([ UI.confirm(msgD, function(res) { $(window).focus(); if (!res) { return; } - manager.delete(pathsList, function () { + manager.deleteOwned(pathsList, function () { pathsList.forEach(LS.removeFoldersOpened); removeSelected(); refresh(); diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index df2e2a710..750a21678 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -2383,10 +2383,10 @@ define([ unpin: unpin, loadSharedFolder: loadSharedFolder, settings: proxy.settings, + removeOwnedChannel: function (channel, cb) { Store.removeOwnedChannel('', channel, cb); }, Store: Store }, { outer: true, - removeOwnedChannel: function (channel, cb) { Store.removeOwnedChannel('', channel, cb); }, edPublic: store.proxy.edPublic, loggedIn: store.loggedIn, log: function (msg) { diff --git a/www/common/outer/team.js b/www/common/outer/team.js index c151de004..9038debb5 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -285,9 +285,6 @@ define([ settings: { drive: Util.find(ctx.store, ['proxy', 'settings', 'drive']) }, - Store: ctx.Store - }, { - outer: true, removeOwnedChannel: function (channel, cb) { var data; if (typeof(channel) === "object") { @@ -301,6 +298,9 @@ define([ } ctx.Store.removeOwnedChannel('', data, cb); }, + Store: ctx.Store + }, { + outer: true, edPublic: keys.drive.edPublic, loggedIn: true, log: function (msg) { diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index 295498641..75a33090d 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -3,9 +3,8 @@ define([ '/common/common-util.js', '/common/common-hash.js', '/common/common-realtime.js', - '/common/common-feedback.js', '/customize/messages.js' -], function (AppConfig, Util, Hash, Realtime, Feedback, Messages) { +], function (AppConfig, Util, Hash, Realtime, Messages) { var module = {}; var clone = function (o) { diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index 3df00d023..9a03d7af2 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -4,8 +4,9 @@ define([ '/common/common-hash.js', '/common/outer/sharedfolder.js', '/customize/messages.js', + '/common/common-feedback.js', '/bower_components/nthen/index.js', -], function (UserObject, Util, Hash, SF, Messages, nThen) { +], function (UserObject, Util, Hash, SF, Messages, Feedback, nThen) { var getConfig = function (Env) { @@ -703,18 +704,16 @@ define([ }); }; - // Delete permanently some pads or folders - var _deleteOwned = function (Env, data, cb) { - }; var _delete = function (Env, data, cb) { data = data || {}; - var resolved = _resolvePaths(Env, data.paths); + var resolved = data.resolved || _resolvePaths(Env, data.paths); if (!resolved.main.length && !Object.keys(resolved.folders).length) { return void cb({error: 'E_NOTFOUND'}); } // Deleted or password changed for a shared folder - if (data.paths.length === 1 && data.paths[0][0] === UserObject.SHARED_FOLDERS_TEMP) { + if (data.paths && data.paths.length === 1 && + data.paths[0][0] === UserObject.SHARED_FOLDERS_TEMP) { var temp = Util.find(Env, ['user', 'proxy', UserObject.SHARED_FOLDERS_TEMP]); delete temp[data.paths[0][1]]; return void Env.onSync(cb); @@ -807,6 +806,69 @@ define([ cb(); }); }; + // Delete permanently some pads or folders + var _deleteOwned = function (Env, data, cb) { + data = data || {}; + var resolved = _resolvePaths(Env, data.paths); + if (!resolved.main.length && !Object.keys(resolved.folders).length) { + return void cb({error: 'E_NOTFOUND'}); + } + var toDelete = { + main: [], + folders: {} + }; + var todo = function (id, uo, p, _cb) { + var cb = Util.once(Util.mkAsync(_cb)); + var el = uo.find(p); + if (!uo.isFile(el) && !uo.isSharedFolder(el)) { return; } + var data = uo.isFile(el) ? uo.getFileData(el) : getSharedFolderData(Env, el); + var chan = data.channel; + Env.removeOwnedChannel(chan, function (obj) { + // If the error is that the file is already removed, nothing to + // report, it's a normal behavior (pad expired probably) + if (obj && obj.error && obj.error.code !== "ENOENT") { + // RPC may not be responding + // Send a report that can be handled manually + console.error(obj.error, chan); + Feedback.send('ERROR_DELETING_OWNED_PAD=' + chan + '|' + obj.error, true); + return void cb(); + } + + // No error: delete the pads and all its copies from our drive and shared folders + var ids = _findChannels(Env, [chan]); + ids.forEach(function (id) { + var paths = findFile(Env, id); + var _resolved = _resolvePaths(Env, paths); + + Array.prototype.push.apply(toDelete.main, _resolved.main); + Object.keys(_resolved.folders).forEach(function (fId) { + if (toDelete.folders[fId]) { + Array.prototype.push.apply(toDelete.folders[fId], _resolved.folders[fId]); + } else { + toDelete.folders[fId] = _resolved.folders[fId]; + } + }); + }); + cb(); + }); + }; + nThen(function (w) { + // Delete owned pads from the server + resolved.main.forEach(function (p) { + todo(null, Env.user.userObject, p, w()); + }); + Object.keys(resolved.folders).forEach(function (id) { + var uo = Env.folders[id].userObject; + resolved.folders[id].forEach(function (p) { + todo(id, uo, p, w()); + }); + }); + }).nThen(function () { + // Remove deleted pads from the drive + _delete(Env, { resolved: toDelete }, cb); + }); + }; + // Empty the trash (main drive only) var _emptyTrash = function (Env, data, cb) { Env.user.userObject.emptyTrash(function (err, toClean) { @@ -870,6 +932,8 @@ define([ _convertFolderToSharedFolder(Env, data, cb); break; case 'delete': _delete(Env, data, cb); break; + case 'deleteOwned': + _deleteOwned(Env, data, cb); break; case 'emptyTrash': _emptyTrash(Env, data, cb); break; case 'rename': @@ -1103,6 +1167,7 @@ define([ unpinPads: data.unpin, onSync: data.onSync, Store: data.Store, + removeOwnedChannel: data.removeOwnedChannel, loadSharedFolder: data.loadSharedFolder, cfg: uoConfig, edPublic: data.edPublic, From c09dde1df01a122081014a1a73e243247455391e Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 12 Jun 2020 16:07:49 +0200 Subject: [PATCH 3/7] Don't duplicate owned pads anymore --- www/common/proxy-manager.js | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index 9a03d7af2..35cb340ee 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -398,26 +398,13 @@ define([ // Copy the elements to the new location var toCopy = _getCopyFromPaths(Env, resolved.main, Env.user.userObject); var newUserObject = newResolved.userObject; - var ownedPads = []; toCopy.forEach(function (obj) { newUserObject.copyFromOtherDrive(newResolved.path, obj.el, obj.data, obj.key); - var _owned = Object.keys(obj.data).filter(function (id) { - var owners = obj.data[id].owners; - return _ownedByMe(Env, owners); - }); - Array.prototype.push.apply(ownedPads, _owned); }); if (copy) { return; } if (resolved.main.length) { - var rootPath = resolved.main[0].slice(); - rootPath.pop(); - ownedPads = Util.deduplicateString(ownedPads); - ownedPads.forEach(function (id) { - Env.user.userObject.add(Number(id), rootPath); - }); - // Remove the elements from the old location (without unpinning) Env.user.userObject.delete(resolved.main, waitFor()); // FIXME waitFor() is called synchronously } @@ -1142,14 +1129,6 @@ define([ if (e) { error = e; return; } uo.add(id, p); })); - if (uo.id && _ownedByMe(Env, pad.owners)) { - // Creating an owned pad in a shared folder: - // We must add a copy in the user's personnal drive - Env.user.userObject.pushData(pad, waitFor(function (e, id) { - if (e) { error = e; return; } - Env.user.userObject.add(id, ['root']); - })); - } }).nThen(function () { cb(error); }); From accc26cafa1a94a8eb5cafea021e417a789a0f7b Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 12 Jun 2020 16:42:34 +0200 Subject: [PATCH 4/7] Remove empty trash button from toolbar and move it next to the content --- customize.dist/src/less2/include/drive.less | 11 ++++++++ www/common/drive-ui.js | 28 +++++++++++++-------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/customize.dist/src/less2/include/drive.less b/customize.dist/src/less2/include/drive.less index 0eb400587..9f569a0f9 100644 --- a/customize.dist/src/less2/include/drive.less +++ b/customize.dist/src/less2/include/drive.less @@ -4,6 +4,7 @@ @import (reference) "./limit-bar.less"; @import (reference) "./tokenfield.less"; @import (reference) "./dropdown.less"; +@import (reference) "./buttons.less"; .drive_main() { --LessLoader_require: LessLoader_currentFile(); @@ -471,6 +472,7 @@ margin-top: 10px; } .cp-app-drive-content-info-box { + order: 10; line-height: 2em; padding: 0.25em 0.75em; margin: 1em; @@ -493,6 +495,7 @@ } } #cp-app-drive-content-folder { + order: 20; li { &.cp-app-drive-search-result { display: flex; @@ -754,6 +757,7 @@ } & > .cp-app-drive-path { + order: 1; width: 100%; height: @variables_bar-height; line-height: @variables_bar-height; @@ -927,5 +931,12 @@ text-transform: uppercase; cursor: default; } + + .cp-app-drive-button { + order: 15; + margin: 0 1em; + .buttons_main(); + } + } diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 37d47a96d..984cd9376 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -114,7 +114,6 @@ define([ var $trashEmptyIcon = $('', {"class": "fa fa-trash-o"}); //var $collapseIcon = $('', {"class": "fa fa-minus-square-o cp-app-drive-icon-expcol"}); var $expandIcon = $('', {"class": "fa fa-plus-square-o cp-app-drive-icon-expcol"}); - var $emptyTrashIcon = $('