diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 984cd9376..6816b89ad 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -2378,16 +2378,53 @@ define([ $gridButton.attr('title', Messages.fm_viewGridButton); $container.append($listButton).append($gridButton); }; + var emptyTrashModal = function () { + var ownedInTrash = manager.ownedInTrash(); + var hasOwned = Array.isArray(ownedInTrash) && ownedInTrash.length; + Messages.fm_emptyTrashOwned = "Your trash contains documents you own. You can remove them for everyone or only from your drive"; // XXX + var content = h('p', [ + Messages.fm_emptyTrashDialog, + hasOwned ? h('br') : undefined, + hasOwned ? Messages.fm_emptyTrashOwned : undefined // XXX update UI? + ]); + var buttons = [{ + className: 'cancel', + name: Messages.cancelButton, + onClick: function () {}, + keys: [27] + }]; + if (hasOwned) { + buttons.push({ + className: 'secondary', + name: Messages.fc_delete_owned, + onClick: function () { + manager.emptyTrash(true, refresh); + }, + keys: [] + }); + } + buttons.push({ + className: 'primary', + // XXX fc_remove: Remove from your CryptDrive + // We may want to use a new key here + name: hasOwned ? Messages.fc_remove : Messages.okButton, + onClick: function () { + manager.emptyTrash(false, refresh); + }, + keys: [13] + }); + var m = UI.dialog.customModal(content, { + buttons: buttons + }); + UI.openCustomModal(m); + }; var createEmptyTrashButton = function () { var button = h('button.btn.btn-danger', [ h('i.fa.'+faTrash), h('span', Messages.fc_empty) ]); $(button).click(function () { - UI.confirm(Messages.fm_emptyTrashDialog, function(res) { - if (!res) { return; } - manager.emptyTrash(refresh); - }); + emptyTrashModal(); }); return $(h('div.cp-app-drive-button', button)); }; @@ -4379,10 +4416,7 @@ define([ log(Messages.fm_forbidden); return; } - UI.confirm(Messages.fm_emptyTrashDialog, function(res) { - if (!res) { return; } - manager.emptyTrash(refresh); - }); + emptyTrashModal(); } else if ($this.hasClass("cp-app-drive-context-remove")) { return void deletePaths(paths); diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index 950f7c679..0637a91ea 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -129,14 +129,13 @@ define([ }; // Find files in FILES_DATA that are not anymore in the drive, and remove them from - // FILES_DATA. If there are owned pads, remove them from server too. + // FILES_DATA. exp.checkDeletedFiles = function (cb) { if (!loggedIn && !config.testMode) { return void cb(); } if (readOnly) { return void cb('EFORBIDDEN'); } var filesList = exp.getFiles([ROOT, 'hrefArray', TRASH]); var toClean = []; - var ownedRemoved = []; exp.getFiles([FILES_DATA, SHARED_FOLDERS]).forEach(function (id) { if (filesList.indexOf(id) === -1) { var fd = exp.isSharedFolder(id) ? files[SHARED_FOLDERS][id] : exp.getFileData(id); @@ -153,7 +152,7 @@ define([ } }); if (!toClean.length) { return void cb(); } - cb(null, toClean, ownedRemoved); + cb(null, toClean); }; var deleteHrefs = function (ids) { if (readOnly) { return; } diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index 49876a8b1..b57a8a24f 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -857,16 +857,49 @@ define([ // Empty the trash (main drive only) var _emptyTrash = function (Env, data, cb) { - Env.user.userObject.emptyTrash(function (err, toClean) { - cb(); + nThen(function (waitFor) { + if (data && data.deleteOwned) { + // Delete owned pads in the trash from the server + var owned = Env.user.userObject.ownedInTrash(function (owners) { + return _ownedByMe(Env, owners); + }); + owned.forEach(function (chan) { + Env.removeOwnedChannel(chan, waitFor(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_EMPTYTRASH_OWNED=' + chan + '|' + obj.error, true); + } + console.warn('DELETED', chan); + })); + }); + } - // Check if need need to restore a full hash (hidden hash deleted from drive) - if (!Array.isArray(toClean)) { return; } - var toCheck = Util.deduplicateString(toClean); - toCheck.forEach(function (chan) { - Env.Store.checkDeletedPad(chan); - }); - }); + // Empty the trash + Env.user.userObject.emptyTrash(waitFor(function (err, toClean) { + cb(); + + // Don't block nThen for the lower-priority tasks + setTimeout(function () { + // Unpin deleted pads if needed + // Check if we need to restore a full hash (hidden hash deleted from drive) + if (!Array.isArray(toClean)) { return; } + var toCheck = Util.deduplicateString(toClean); + var toUnpin = []; + toCheck.forEach(function (channel) { + // Check unpin + var data = findChannel(Env, channel, true); + if (!data.length) { toUnpin.push(channel); } + // Check hidden hash + Env.Store.checkDeletedPad(channel); + }); + Env.unpinPads(toUnpin, function () {}); + }); + })); + }).nThen(cb); }; // Rename files or folders var _rename = function (Env, data, cb) { @@ -1221,10 +1254,12 @@ define([ } }, cb); }; - var emptyTrashInner = function (Env, cb) { + var emptyTrashInner = function (Env, deleteOwned, cb) { return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", { cmd: "emptyTrash", - data: null + data: { + deleteOwned: deleteOwned + } }, cb); }; var addFolderInner = function (Env, path, name, cb) { @@ -1435,6 +1470,11 @@ define([ } return Env.user.userObject.hasFile(el, trashRoot); }; + var ownedInTrash = function (Env) { + return Env.user.userObject.ownedInTrash(function (owners) { + return _ownedByMe(Env, owners); + }); + }; var isDuplicateOwned = _isDuplicateOwned; @@ -1490,6 +1530,7 @@ define([ isInSharedFolder: callWithEnv(isInSharedFolder), getUserObjectPath: callWithEnv(getUserObjectPath), isDuplicateOwned: callWithEnv(isDuplicateOwned), + ownedInTrash: callWithEnv(ownedInTrash), // Generic isValidDrive: callWithEnv(isValidDrive), isFile: callWithEnv(isFile), diff --git a/www/common/userObject.js b/www/common/userObject.js index fbe28864a..4c123284c 100644 --- a/www/common/userObject.js +++ b/www/common/userObject.js @@ -842,6 +842,12 @@ define([ files[TRASH] = {}; exp.checkDeletedFiles(cb); }; + exp.ownedInTrash = function (isOwned) { + return getFiles([TRASH]).map(function (id) { + var data = exp.getFileData(id); + return isOwned(data.owners) ? data.channel : undefined; + }).filter(Boolean); + }; // RENAME exp.rename = function (path, newName, cb) {