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,