diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index 98dc48c23..f69340766 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -885,6 +885,7 @@ define([ if (fPath) { // This is a shared folder, we have to fix the paths in the search results results.forEach(function (r) { + r.inSharedFolder = true; r.paths.forEach(function (p) { Array.prototype.unshift.apply(p, fPath); }); @@ -899,8 +900,8 @@ define([ var getRecentPads = function (Env) { return Env.user.userObject.getRecentPads(); }; - var getOwnedPads = function (Env, edPublic) { - return Env.user.userObject.getOwnedPads(edPublic); + var getOwnedPads = function (Env) { + return Env.user.userObject.getOwnedPads(Env.edPublic); }; var getSharedFolderData = function (Env, id) { @@ -961,10 +962,27 @@ define([ return Env.user.userObject.hasFile(el, trashRoot); }; - var createInner = function (proxy, sframeChan, uoConfig) { + // Get the owned files in the main drive that are also duplicated in shared folders + var isDuplicateOwned = function (Env, path) { + if (isInSharedFolder(Env, path)) { return; } + var data = getFileData(Env, Env.user.userObject.find(path)); + if (!data) { return; } + if (!_ownedByMe(Env, data.owners)) { return; } + var channel = data.channel; + if (!channel) { return; } + var foldersUO = Object.keys(Env.folders).map(function (k) { + return Env.folders[k].userObject; + }); + return foldersUO.some(function (uo) { + return uo.findChannels([channel]).length; + }); + }; + + var createInner = function (proxy, sframeChan, edPublic, uoConfig) { var Env = { cfg: uoConfig, sframeChan: sframeChan, + edPublic: edPublic, user: { proxy: proxy, userObject: UserObject.init(proxy, uoConfig) @@ -1006,6 +1024,7 @@ define([ getSharedFolderData: callWithEnv(getSharedFolderData), isInSharedFolder: callWithEnv(isInSharedFolder), getUserObjectPath: callWithEnv(getUserObjectPath), + isDuplicateOwned: callWithEnv(isDuplicateOwned), // Generic isFile: callWithEnv(isFile), isFolder: callWithEnv(isFolder), diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index d29afcc18..86990f50b 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -275,7 +275,7 @@ define([ forceCreationScreen: forceCreationScreen, password: password, channel: secret.channel, - enableSF: localStorage.CryptPad_SF === "1" // TODO to remove when enabled by default + enableSF: localStorage.CryptPad_SF === "1", // TODO to remove when enabled by default }; if (window.CryptPad_newSharedFolder) { additionalPriv.newSharedFolder = window.CryptPad_newSharedFolder; diff --git a/www/common/translations/messages.js b/www/common/translations/messages.js index a1de74bc4..588d90653 100644 --- a/www/common/translations/messages.js +++ b/www/common/translations/messages.js @@ -646,6 +646,10 @@ define(function () { out.settings_logoutEverywhere = "Force log out of all other web sessions"; out.settings_logoutEverywhereConfirm = "Are you sure? You will need to log in with all your devices."; + out.settings_driveDuplicateTitle = "Duplicated owned pads"; + out.settings_driveDuplicateHint = "To make sure you always have control over your owned pads, whenever you try to move one into a shared folder, a copy is kept in your drive. You can choose here to hide these duplicated files. You will only see the version stored the shared folder until it is removed from the shared folder or the shared folder itself is removed, then the copy will reappear."; + out.settings_driveDuplicateLabel = "Hide duplicates"; + out.settings_codeIndentation = 'Code editor indentation (spaces)'; out.settings_codeUseTabs = "Indent using tabs (instead of spaces)"; out.settings_codeFontSize = "Font size in the code editor"; diff --git a/www/drive/inner.js b/www/drive/inner.js index b64c0283b..58067e6d9 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -363,8 +363,9 @@ define([ APP.origin = priv.origin; config.loggedIn = APP.loggedIn; config.sframeChan = sframeChan; + APP.hideDuplicateOwned = Util.find(priv, ['settings', 'drive', 'hideDuplicate']); - var manager = ProxyManager.createInner(files, sframeChan, config); + var manager = ProxyManager.createInner(files, sframeChan, edPublic, config); Object.keys(folders).forEach(function (id) { var f = folders[id]; @@ -2374,6 +2375,8 @@ define([ var filesList = manager.search(value); filesList.forEach(function (r) { r.paths.forEach(function (path) { + if (!r.inSharedFolder && + APP.hideDuplicateOwned && manager.isDuplicateOwned(path)) { return; } var href = r.data.href; var parsed = Hash.parsePadUrl(href); var $table = $(''); @@ -2481,7 +2484,7 @@ define([ // Owned pads category var displayOwned = function ($container) { - var list = manager.getOwnedPads(edPublic); + var list = manager.getOwnedPads(); if (list.length === 0) { return; } var $fileHeader = getFileListHeader(false); $container.append($fileHeader); @@ -2743,6 +2746,9 @@ define([ // display files sortedFiles.forEach(function (key) { if (manager.isFolder(root[key])) { return; } + var p = path.slice(); + p.push(key); + if (APP.hideDuplicateOwned && manager.isDuplicateOwned(p)) { return; } var $element = createElement(path, key, root, false); if (!$element) { return; } $element.appendTo($list); diff --git a/www/settings/inner.js b/www/settings/inner.js index ec9de6100..2bd20749a 100644 --- a/www/settings/inner.js +++ b/www/settings/inner.js @@ -63,6 +63,7 @@ define([ 'cp-settings-creation-template' ], 'drive': [ + 'cp-settings-drive-duplicate', 'cp-settings-resettips', 'cp-settings-thumbnails', 'cp-settings-drive-backup', @@ -777,6 +778,44 @@ define([ // Drive settings + create['drive-duplicate'] = function () { + var $div = $('
', { + 'class': 'cp-settings-drive-duplicate cp-sidebarlayout-element' + }); + $('