diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index f815b8e4f..7f7f8b5eb 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -994,7 +994,7 @@ load pinpad dynamically only after you know that it will be needed */ var userChannel = common.parseHash(userHash).channel; if (!userChannel) { return null; } - var list = fo.getFilesDataFiles().map(hrefToHexChannelId) + var list = fo.getFiles([fo.FILES_DATA]).map(hrefToHexChannelId) .filter(function (x) { return x; }); list.push(common.base64ToHex(userChannel)); diff --git a/www/common/fsStore.js b/www/common/fsStore.js index e2b283f4b..edab0e252 100644 --- a/www/common/fsStore.js +++ b/www/common/fsStore.js @@ -2,7 +2,7 @@ define([ '/bower_components/chainpad-listmap/chainpad-listmap.js', '/bower_components/chainpad-crypto/crypto.js?v=0.1.5', '/bower_components/textpatcher/TextPatcher.amd.js', - '/common/fileObject.js', + '/common/userObject.js', '/bower_components/jquery/dist/jquery.min.js', ], function (Listmap, Crypto, TextPatcher, FO) { /* @@ -125,7 +125,7 @@ define([ }; ret.replaceHref = function (o, n) { - return filesOp.replaceHref(o, n); + return filesOp.replace(o, n); }; var changeHandlers = ret.changeHandlers = []; diff --git a/www/common/mergeDrive.js b/www/common/mergeDrive.js index 688f1cedc..784817d1d 100644 --- a/www/common/mergeDrive.js +++ b/www/common/mergeDrive.js @@ -2,7 +2,7 @@ require.config({ paths: { 'json.sortify': '/bower_components/json.sortify/dist/J define([ '/common/cryptpad-common.js', '/common/cryptget.js', - '/common/fileObject.js', + '/common/userObject.js', 'json.sortify' ], function (Cryptpad, Crypt, FO, Sortify) { var exp = {}; @@ -76,8 +76,8 @@ define([ console.error(msg || "Unable to find that path", path); }; - if (path[0] === FO.TRASH && path.length === 4) { - href = oldFo.getTrashElementData(path); + if (oldFo.isInTrashRoot(path)) { + href = oldFo.find(path.slice(0,3)); path.pop(); } @@ -156,13 +156,13 @@ define([ var newData = Cryptpad.getStore().getProxy(); var newFo = newData.fo; var newRecentPads = proxy.drive[Cryptpad.storageKey]; - var newFiles = newFo.getFilesDataFiles(); - var oldFiles = oldFo.getFilesDataFiles(); + var newFiles = newFo.getFiles([newFo.FILES_DATA]); + var oldFiles = oldFo.getFiles([newFo.FILES_DATA]); oldFiles.forEach(function (href) { // Do not migrate a pad if we already have it, it would create a duplicate in the drive if (newFiles.indexOf(href) !== -1) { return; } // If we have a stronger version, do not add the current href - if (Cryptpad.findStronger(href, newRecentPads)) { return; } + if (Cryptpad.findStronger(href, newRecentPads)) { console.log(href); return; } // If we have a weaker version, replace the href by the new one // NOTE: if that weaker version is in the trash, the strong one will be put in unsorted var weaker = Cryptpad.findWeaker(href, newRecentPads); @@ -176,7 +176,7 @@ define([ return; }); // Update the file in the drive - newFo.replaceHref(weaker, href); + newFo.replace(weaker, href); return; } // Here it means we have a new href, so we should add it to the drive at its old location diff --git a/www/common/userObject.js b/www/common/userObject.js index 7e7f7b292..d9669c408 100644 --- a/www/common/userObject.js +++ b/www/common/userObject.js @@ -10,10 +10,11 @@ define([ var TEMPLATE = module.TEMPLATE = "template"; var init = module.init = function (files, config) { + var exp = {}; var Cryptpad = config.Cryptpad; var Messages = Cryptpad.Messages; - var FILES_DATA = Cryptpad.storageKey; + var FILES_DATA = module.FILES_DATA = exp.FILES_DATA = Cryptpad.storageKey; var NEW_FOLDER_NAME = Messages.fm_newFolder; var NEW_FILE_NAME = Messages.fm_newFile; @@ -33,8 +34,6 @@ define([ // TODO: workgroup var workgroup = config.workgroup; - var exp = {}; - /* * UTILS @@ -49,6 +48,10 @@ define([ a[TEMPLATE] = []; return a; }; + var getHrefArray = function () { + return [UNSORTED, TEMPLATE]; + }; + var compareFiles = function (fileA, fileB) { return fileA === fileB; }; @@ -151,13 +154,19 @@ define([ return result; }; - var isSubpath = exp.isSubpath = function (path, parentPaths) { + var isSubpath = exp.isSubpath = function (path, parentPath) { var pathA = parentPath.slice(); var pathB = path.slice(0, pathA.length); return comparePath(pathA, pathB); }; - var isPathIn = function (path, categories) { + var isPathIn = exp.isPathIn = function (path, categories) { + if (!categories) { return; } + var idx = categories.indexOf('hrefArray'); + if (idx !== -1) { + categories.splice(idx, 1); + categories = categories.concat(getHrefArray()); + } return categories.some(function (c) { return Array.isArray(path) && path[0] === c; }); @@ -205,21 +214,17 @@ define([ }; var _getFiles = {}; _getFiles['array'] = function (cat) { - if (!files[cat]) { - files[cat] = []; - } + if (!files[cat]) { files[cat] = []; } return files[cat].slice(); }; - _getFiles[UNSORTED] = function () { - return _getFiles['array'](UNSORTED); - }; - _getFiles[TEMPLATE] = function () { - return _getFiles['array'](TEMPLATE); - }; + getHrefArray().forEach(function (c) { + _getFiles[c] = function () { return _getFiles['array'](c); }; + }); _getFiles['hrefArray'] = function () { var ret = []; - ret = ret.concat(_getFiles[UNSORTED]); - ret = ret.concat(_getFiles[TEMPLATE]); + getHrefArray().forEach(function (c) { + ret = ret.concat(_getFiles[c]()); + }); return Cryptpad.deduplicateString(ret); }; _getFiles[ROOT] = function () { @@ -255,11 +260,14 @@ define([ }); return ret; }; - var getFiles = function (categories) { + var getFiles = exp.getFiles = function (categories) { var ret = []; + if (!categories || !categories.length) { + categories = [ROOT, 'hrefArray', TRASH, FILES_DATA]; + } categories.forEach(function (c) { if (typeof _getFiles[c] === "function") { - ret = ret.concat(_getFiles[c]); + ret = ret.concat(_getFiles[c]()); } }); return Cryptpad.deduplicateString(ret); @@ -267,7 +275,7 @@ define([ // SEARCH var _findFileInRoot = function (path, href) { - if (!isPathIn([ROOT, TRASH])) { return []; } + if (!isPathIn(path, [ROOT, TRASH])) { return []; } var paths = []; var root = find(path); var addPaths = function (p) { @@ -338,7 +346,7 @@ define([ } return paths; }; - var findFile = function (href) { + var findFile = exp.findFile = function (href) { var rootpaths = _findFileInRoot([ROOT], href); var unsortedpaths = _findFileInHrefArray(UNSORTED, href); var templatepaths = _findFileInHrefArray(TEMPLATE, href); @@ -423,6 +431,7 @@ define([ // FILES DATA var pushFileData = exp.pushData = function (data) { Cryptpad.pinPads([Cryptpad.hrefToHexChannelId(data.href)], function (e, hash) { + if (e) { console.log(e); return; } console.log(hash); }); files[FILES_DATA].push(data); @@ -431,6 +440,7 @@ define([ var data = files[FILES_DATA][idx]; if (typeof data === "object") { Cryptpad.unpinPads([Cryptpad.hrefToHexChannelId(data.href)], function (e, hash) { + if (e) { console.log(e); return; } console.log(hash); }); } @@ -496,7 +506,7 @@ define([ } else { name = elementPath[elementPath.length-1]; } - var newName = !isPathInRoot(elementPath) ? getAvailableName(newParent, name) : name; + var newName = !isPathIn(elementPath, [ROOT]) ? getAvailableName(newParent, name) : name; if (typeof(newParent[newName]) !== "undefined") { log(Messages.fo_unavailableName); @@ -517,6 +527,14 @@ define([ }); exp.delete(toRemove, cb); }; + var restore = exp.restore = function (path, cb) { + if (!isInTrashRoot(path)) { return; } + var parentPath = path.slice(); + parentPath.pop(); + var oldPath = find(parentPath).path; + move([path], oldPath, cb); + }; + // ADD var add = exp.add = function (href, path, name, cb) { @@ -599,7 +617,7 @@ define([ // Nothing in FILES_DATA for workgroups if (workgroup) { return; } - var filesList = getFiles[ROOT, 'hrefArray', TRASH]; + var filesList = getFiles([ROOT, 'hrefArray', TRASH]); var toRemove = []; files[FILES_DATA].forEach(function (arr) { var f = arr.href; @@ -629,9 +647,9 @@ define([ }); }; var deleteMultiplePermanently = function (paths) { - var hrefPaths = paths.filter(isPathInHrefArray); - var rootPaths = paths.filter(isPathInRoot); - var trashPaths = paths.filter(isPathInTrash); + var hrefPaths = paths.filter(function(x) { return isPathIn(x, ['hrefArray']); }); + var rootPaths = paths.filter(function(x) { return isPathIn(x, [ROOT]); }); + var trashPaths = paths.filter(function(x) { return isPathIn(x, [TRASH]); }); var hrefs = []; hrefPaths.forEach(function (path) { @@ -674,7 +692,7 @@ define([ checkDeletedFiles(); }; var deletePath = exp.delete = function (paths, cb) { - deletePathsPermanently(paths); + deleteMultiplePermanently(paths); if (typeof cb === "function") { cb(); } }; var emptyTrash = exp.emptyTrash = function (cb) { @@ -708,6 +726,49 @@ define([ cb(); }; + // REPLACE + var replaceFile = function (path, o, n) { + var root = find(path); + + if (isFile(root)) { return; } + for (var e in root) { + if (isFile(root[e])) { + if (compareFiles(o, root[e])) { + root[e] = n; + } + } else { + var nPath = path.slice(); + nPath.push(e); + replaceFile(nPath, o, n); + } + } + }; + // Replace a href by a stronger one everywhere in the drive (except FILES_DATA) + var replaceHref = exp.replace = function (o, n) { + if (!isFile(o) || !isFile(n)) { return; } + var paths = findFile(o); + + // Remove all the occurences in the trash + // Replace all the occurences not in the trash + // If all the occurences are in the trash or no occurence, add the pad to unsorted + var allInTrash = true; + paths.forEach(function (p) { + if (p[0] === TRASH) { + removeFromTrash(p, null, true); // 3rd parameter means skip "checkDeletedFiles" + return; + } else { + allInTrash = false; + var parentPath = p.slice(); + var key = parentPath.pop(); + var parentEl = find(parentPath); + parentEl[key] = n; + } + }); + if (allInTrash) { + add(n); + } + }; + /** * INTEGRITY CHECK */ diff --git a/www/drive/main.js b/www/drive/main.js index f4a8d05a8..1b57b41ae 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -5,7 +5,7 @@ define([ '/bower_components/textpatcher/TextPatcher.amd.js', 'json.sortify', '/common/cryptpad-common.js', - '/common/fileObject.js', + '/common/userObject.js', '/common/toolbar.js', '/customize/application_config.js', '/common/cryptget.js', @@ -264,9 +264,7 @@ define([ var removeInput = function (cancel) { if (!cancel && $iframe.find('.element-row > input').length === 1) { var $input = $iframe.find('.element-row > input'); - filesOp.renameElement($input.data('path'), $input.val(), function () { - APP.refresh(); - }); + filesOp.rename($input.data('path'), $input.val(), APP.refresh); } $iframe.find('.element-row > input').remove(); $iframe.find('.element-row > span:hidden').removeAttr('style'); @@ -332,9 +330,7 @@ define([ $input.on('keyup', function (e) { if (e.which === 13) { removeInput(true); - filesOp.renameElement(path, $input.val(), function () { - refresh(); - }); + filesOp.rename(path, $input.val(), refresh); return; } if (e.which === 27) { @@ -371,6 +367,7 @@ define([ var filterContextMenu = function ($menu, paths) { //var path = $element.data('path'); + if (!paths || paths.length === 0) { console.error('no paths'); } var hide = []; var hasFolder = false; @@ -652,15 +649,11 @@ define([ var getElementName = function (path) { // Trash root - if (filesOp.isInTrashRoot(path)) { - return path[0]; - } + if (filesOp.isInTrashRoot(path)) { return path[0]; } // Root or trash - if (filesOp.isPathInRoot(path) || filesOp.isPathInTrash(path)) { - return path[path.length - 1]; - } + if (filesOp.isPathIn(path, [ROOT, TRASH])) { return path[path.length - 1]; } // Unsorted or template - if (filesOp.isPathInUnsorted(path) || filesOp.isPathInTemplate(path)) { + if (filesOp.isPathIn(path, ['hrefArray'])) { var file = filesOp.find(path); if (filesOp.isFile(file) && filesOp.getTitle(file)) { return filesOp.getTitle(file); @@ -674,10 +667,10 @@ define([ var moveElements = function (paths, newPath, force, cb) { if (!APP.editable) { return; } var andThen = function () { - filesOp.moveElements(paths, newPath, cb); + filesOp.move(paths, newPath, cb); }; // Cancel drag&drop from TRASH to TRASH - if (filesOp.comparePath(newPath, [TRASH]) && paths.length >= 1 && paths[0][0] === TRASH) { + if (filesOp.isPathIn(newPath, [TRASH]) && paths.length && paths[0][0] === TRASH) { return; } // "force" is currently unused but may be configurable by user @@ -764,7 +757,8 @@ define([ moveElements(movedPaths, newPath, null, refresh); } if (importedElements && importedElements.length) { - filesOp.importElements(importedElements, newPath, refresh); + // TODO workgroup + //filesOp.importElements(importedElements, newPath, refresh); } }; @@ -967,7 +961,7 @@ define([ // Create the title block with the "parent folder" button var createTitle = function (path, noStyle) { if (!path || path.length === 0) { return; } - var isTrash = filesOp.isPathInTrash(path); + var isTrash = filesOp.isPathIn(path, [TRASH]); var $title = $('', {'class': 'path unselectable'}); if (APP.mobile()) { return $title; @@ -1119,7 +1113,7 @@ define([ refresh(); }; $block.find('a.newFolder').click(function () { - filesOp.addFolder(currentPath, null, onCreated); // TODO START HERE + filesOp.addFolder(currentPath, null, onCreated); }); $block.find('a.newdoc').click(function (e) { var type = $(this).attr('data-type') || 'pad'; @@ -2046,7 +2040,7 @@ define([ if (path.length === 4) { name = path[1]; } Cryptpad.confirm(Messages._getKey("fm_removePermanentlyDialog", [name]), function(res) { if (!res) { return; } - filesOp.removeFromTrash(path, refresh); // TODO END HERE + filesOp.delete([path], refresh); }); return; } @@ -2055,8 +2049,7 @@ define([ var msg = Messages._getKey("fm_removeSeveralPermanentlyDialog", [paths.length]); Cryptpad.confirm(msg, function(res) { if (!res) { return; } - filesOp.deletePathsPermanently(pathsList); - refresh(); + filesOp.delete(pathsList, refresh); }); } else if ($(this).hasClass("restore")) { @@ -2064,13 +2057,12 @@ define([ if (path.length === 4) { name = path[1]; } Cryptpad.confirm(Messages._getKey("fm_restoreDialog", [name]), function(res) { if (!res) { return; } - filesOp.restoreTrash(path, refresh); + filesOp.restore(path, refresh); }); } else if ($(this).hasClass("properties")) { - if (paths.length !== 1) { return; } - if (path.length !== 4) { return; } - var element = filesOp.getTrashElementData(path); + if (paths.length !== 1 || path.length !== 4) { return; } + var element = filesOp.find(path.slice(0,3)); // element containing the oldpath var sPath = stringifyPath(element.path); Cryptpad.alert('' + Messages.fm_originalPath + ":
" + sPath, undefined, true); } @@ -2094,20 +2086,17 @@ define([ $appContainer.on('keydown', function (e) { // "Del" if (e.which === 46) { - if (filesOp.isPathInFilesData(currentPath)) { return; } // We can't remove elements directly from filesData + if (filesOp.isPathIn(currentPath, [FILES_DATA])) { return; } // We can't remove elements directly from filesData var $selected = $iframe.find('.selected'); if (!$selected.length) { return; } var paths = []; - var isTrash = filesOp.isPathInTrash(currentPath); + var isTrash = filesOp.isPathIn(currentPath, [TRASH]); $selected.each(function (idx, elmt) { if (!$(elmt).data('path')) { return; } paths.push($(elmt).data('path')); }); // If we are in the trash or anon pad or if we are holding the "shift" key, delete permanently, if (isTrash || e.shiftKey) { - //var cb = filesOp.removeFromTrash; // We're in the trash - //if (!isTrash) { cb = filesOp.deletePathPermanently; } // We're in root - var msg = Messages._getKey("fm_removeSeveralPermanentlyDialog", [paths.length]); if (paths.length === 1) { msg = Messages.fm_removePermanentlyDialog; @@ -2116,8 +2105,7 @@ define([ Cryptpad.confirm(msg, function(res) { $(ifrw).focus(); if (!res) { return; } - filesOp.deletePathsPermanently(paths); - refresh(); + filesOp.delete(paths, refresh); }); return; } @@ -2143,10 +2131,8 @@ define([ if (path[0] !== 'drive') { return false; } path = path.slice(1); var cPath = currentPath.slice(); - if ((filesOp.isPathInUnsorted(cPath) && filesOp.isPathInUnsorted(path)) || - (filesOp.isPathInTemplate(cPath) && filesOp.isPathInTemplate(path)) || - (path.length >= cPath.length && filesOp.isSubpath(path, cPath)) || - (filesOp.isPathInTrash(cPath) && filesOp.isPathInTrash(path))) { + if ((filesOp.isPathIn(cPath, ['hrefArray', TRASH]) && cPath[0] === path[0]) || + (path.length >= cPath.length && filesOp.isSubpath(path, cPath))) { // Reload after a few ms to make sure all the change events have been received onRefresh.refresh(); } else if (path.length && path[0] === FILES_DATA) { @@ -2159,10 +2145,8 @@ define([ if (path[0] !== 'drive') { return false; } path = path.slice(1); var cPath = currentPath.slice(); - if ((filesOp.isPathInUnsorted(cPath) && filesOp.isPathInUnsorted(path)) || - (filesOp.isPathInTemplate(cPath) && filesOp.isPathInTemplate(path)) || - (path.length >= cPath.length && filesOp.isSubpath(path, cPath)) || - (filesOp.isPathInTrash(cPath) && filesOp.isPathInTrash(path))) { + if ((filesOp.isPathIn(cPath, ['hrefArray', TRASH]) && cPath[0] === path[0]) || + (path.length >= cPath.length && filesOp.isSubpath(path, cPath))) { // Reload after a few to make sure all the change events have been received onRefresh.to = window.setTimeout(refresh, 500); }