diff --git a/customize.dist/fsStore.js b/customize.dist/fsStore.js
index fbf7a5719..7ccde1947 100644
--- a/customize.dist/fsStore.js
+++ b/customize.dist/fsStore.js
@@ -119,6 +119,10 @@ define([
return filesOp.getStructure();
};
+ ret.replaceHref = function (o, n) {
+ return filesOp.replaceHref(o, n);
+ };
+
var changeHandlers = ret.changeHandlers = [];
ret.change = function (f) {};
diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js
index 3bcd145de..e31bd5a9b 100644
--- a/customize.dist/translations/messages.fr.js
+++ b/customize.dist/translations/messages.fr.js
@@ -250,6 +250,7 @@ define(function () {
"Êtes-vous sûr de vouloir continuer ?
" +
"Tapez “I love CryptPad” pour confirmer.";
out.settings_resetDone = "Votre drive est désormais vide!";
+ out.settings_resetError = "Texte de vérification incorrect. Votre CryptDrive n'a pas été modifié.";
out.settings_resetTips = "Astuces et informations dans CryptDrive";
out.settings_resetTipsButton = "Réinitialiser les astuces visibles dans CryptDrive";
out.settings_resetTipsDone = "Toutes les astuces sont de nouveau visibles.";
diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js
index 479cde75f..c32f346eb 100644
--- a/customize.dist/translations/messages.js
+++ b/customize.dist/translations/messages.js
@@ -252,6 +252,7 @@ define(function () {
"Are you sure you want to continue?
" +
"Type “I love CryptPad” to confirm.";
out.settings_resetDone = "Your drive is now empty!";
+ out.settings_resetError = "Incorrect verification text. Your CryptDrive has not been changed.";
out.settings_resetTips = "Tips in CryptDrive";
out.settings_resetTipsButton = "Reset the available tips in CryptDrive";
out.settings_resetTipsDone = "All the tips are now visible again.";
diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js
index c78f938d2..6660cac5b 100644
--- a/www/common/cryptpad-common.js
+++ b/www/common/cryptpad-common.js
@@ -423,6 +423,8 @@ define([
var ret = {};
+ if (!href) { return ret; }
+
if (!/^https*:\/\//.test(href)) {
var idx = href.indexOf('/#');
ret.type = href.slice(1, idx);
@@ -628,6 +630,7 @@ define([
return;
}
+ var updateWeaker = [];
var contains;
var renamed = recent.map(function (pad) {
var p = parsePadUrl(pad.href);
@@ -661,6 +664,14 @@ define([
// set the name
pad.title = name;
+
+ // If we now have a stronger version of a stored href, replace the weaker one by the strong one
+ if (pad && pad.href && href !== pad.href) {
+ updateWeaker.push({
+ o: pad.href,
+ n: href
+ });
+ }
pad.href = href;
}
return pad;
@@ -675,6 +686,11 @@ define([
}
setRecentPads(renamed, function (err, data) {
+ if (updateWeaker.length > 0) {
+ updateWeaker.forEach(function (obj) {
+ getStore().replaceHref(obj.o, obj.n);
+ });
+ }
cb(err, data);
});
});
@@ -1183,7 +1199,7 @@ define([
content: Messages.user_rename
});
}
- if (parsed && parsed.type && parsed.type !== 'settings') {
+ if (parsed && (!parsed.type || parsed.type !== 'settings')) {
options.push({
tag: 'a',
attributes: {'class': 'settings'},
diff --git a/www/common/fileObject.js b/www/common/fileObject.js
index d8f10ced4..158f664ff 100644
--- a/www/common/fileObject.js
+++ b/www/common/fileObject.js
@@ -242,6 +242,86 @@ define([
return ret;
};
+ var _findFileInRoot = function (path, href) {
+ if (path[0] !== ROOT && path[0] !== TRASH) { return []; }
+ var paths = [];
+ var root = exp.findElement(files, path);
+ var addPaths = function (p) {
+ if (paths.indexOf(p) === -1) {
+ paths.push(p);
+ }
+ };
+
+ if (isFile(root)) {
+ if (compareFiles(href, root)) {
+ if (paths.indexOf(path) === -1) {
+ paths.push(path);
+ }
+ }
+ return paths;
+ }
+ for (var e in root) {
+ var nPath = path.slice();
+ nPath.push(e);
+ _findFileInRoot(nPath, href).forEach(addPaths);
+ }
+
+ return paths;
+ };
+ var _findFileInHrefArray = function (rootName, href) {
+ var unsorted = files[rootName].slice();
+ var ret = [];
+ var i = -1;
+ while ((i = unsorted.indexOf(href, i+1)) != -1){
+ ret.push([rootName, i]);
+ }
+ return ret;
+ };
+ var _findFileInTrash = function (path, href) {
+ var root = exp.findElement(files, path);
+ var paths = [];
+ var addPaths = function (p) {
+ if (paths.indexOf(p) === -1) {
+ paths.push(p);
+ }
+ };
+ if (path.length === 1) {
+ Object.keys(root).forEach(function (key) {
+ var arr = root[key];
+ if (!Array.isArray(arr)) { return; }
+ var nPath = path.slice();
+ nPath.push(key);
+ _findFileInTrash(nPath, href).forEach(addPaths);
+ });
+ }
+ if (path.length === 2) {
+ if (!Array.isArray(root)) { return []; }
+ root.forEach(function (el, i) {
+ var nPath = path.slice();
+ nPath.push(i);
+ nPath.push('element');
+ if (isFile(el.element)) {
+ if (compareFiles(href, el.element)) {
+ addPaths(nPath);
+ }
+ return;
+ }
+ _findFileInTrash(nPath, href).forEach(addPaths);
+ });
+ }
+ if (path.length >= 4) {
+ _findFileInRoot(path, href).forEach(addPaths);
+ }
+ return paths;
+ };
+ var findFile = exp.findFile = function (href) {
+ var rootpaths = _findFileInRoot([ROOT], href);
+ var unsortedpaths = _findFileInHrefArray(UNSORTED, href);
+ var templatepaths = _findFileInHrefArray(TEMPLATE, href);
+ var trashpaths = _findFileInTrash([TRASH], href);
+ return rootpaths.concat(unsortedpaths, templatepaths, trashpaths);
+ };
+
// Remove the selected 'href' from the tree located at 'path', and push its locations to the 'paths' array
var removeFileFromRoot = function (path, href) {
var paths = [];
@@ -374,7 +454,6 @@ define([
var parentEl = exp.findElement(files, parentPath);
// Trash root: we have array here, we can't just splice with the path otherwise we might break the path
// of another element in the loop
- console.log(path);
if (path.length === 4) {
trashRoot.push({
name: path[1],
@@ -573,7 +652,6 @@ define([
// Import elements in the file manager
var importElements = exp.importElements = function (elements, path, cb) {
if (!elements || elements.length === 0) { return; }
- console.log(elements);
var newParent = findElement(files, path);
if (!newParent) { debug("Trying to import elements into a non-existing folder"); return; }
elements.forEach(function (e) {
@@ -670,7 +748,7 @@ define([
};
// Delete permanently (remove from the trash root and from filesData)
- var removeFromTrash = exp.removeFromTrash = function (path, cb) {
+ var removeFromTrash = exp.removeFromTrash = function (path, cb, nocheck) {
if (!path || path.length < 4 || path[0] !== TRASH) { return; }
// Remove the last element from the path to get the parent path and the element name
var parentPath = path.slice();
@@ -691,7 +769,9 @@ define([
parentEl[name] = undefined;
delete parentEl[name];
}
- checkDeletedFiles();
+ if (!nocheck) {
+ checkDeletedFiles();
+ }
if(cb) { cb(); }
};
@@ -773,7 +853,7 @@ define([
pushToTrash(key, href, path);
};
- var addUnsortedPad = exp.addPad = function (href, path, name) {
+ var addPad = exp.addPad = function (href, path, name) {
if (workgroup) { return; }
if (!href) { return; }
var unsortedFiles = getUnsortedFiles();
@@ -798,10 +878,54 @@ define([
}
}
if (unsortedFiles.indexOf(href) === -1 && rootFiles.indexOf(href) === -1 && templateFiles.indexOf(href) === -1 && trashFiles.indexOf(href) === -1) {
+ console.log('push', href);
files[UNSORTED].push(href);
}
};
+ var replaceFile = function (path, o, n) {
+ var root = exp.findElement(files, 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.replaceHref = 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 = findElement(files, parentPath);
+ parentEl[key] = n;
+ }
+ });
+ if (allInTrash) {
+ addPad(n);
+ }
+ };
+
// addTemplate is called when we want to add a new pad, never visited, to the templates list
// first, we must add it to FILES_DATA, so the input has to be an fileDAta object
var addTemplate = exp.addTemplate = function (fileData) {
diff --git a/www/drive/file.css b/www/drive/file.css
index 9f41d3839..65e03f713 100644
--- a/www/drive/file.css
+++ b/www/drive/file.css
@@ -113,6 +113,7 @@ span.fa-folder-open {
#tree li > span.element-row {
width: 100%;
display: inline-block;
+ cursor: pointer;
}
#tree li > span.element-row:not(.selected):hover {
background-color: #eee;
diff --git a/www/drive/file.less b/www/drive/file.less
index cf874dad7..cdbba0e56 100644
--- a/www/drive/file.less
+++ b/www/drive/file.less
@@ -147,6 +147,7 @@ span {
& > span.element-row {
width: 100%;
display: inline-block;
+ cursor: pointer;
}
& > span.element-row:not(.selected):hover {
background-color: @drive-hover;
diff --git a/www/drive/main.js b/www/drive/main.js
index 4836fe51c..8ccb0a82c 100644
--- a/www/drive/main.js
+++ b/www/drive/main.js
@@ -1164,7 +1164,7 @@ define([
var e = useData ? element : filesOp.getFileData(element);
if (!e) {
e = {
- href : el,
+ href : element,
title : Messages.fm_noname,
atime : 0,
ctime : 0
diff --git a/www/settings/main.js b/www/settings/main.js
index 70cf938dc..ab3330ccd 100644
--- a/www/settings/main.js
+++ b/www/settings/main.js
@@ -124,7 +124,8 @@ define([
var exportFile = function () {
var sjson = JSON.stringify(obj);
- var suggestion = obj.login_name + '-' + new Date().toDateString();
+ var name = obj.login_name || obj[USERNAME_KEY] || Messages.anonymous;
+ var suggestion = name + '-' + new Date().toDateString();
Cryptpad.prompt(Cryptpad.Messages.exportPrompt,
Cryptpad.fixFileName(suggestion) + '.json', function (filename) {
if (!(typeof(filename) === 'string' && filename)) { return; }
@@ -164,7 +165,10 @@ define([
$button.click(function () {
Cryptpad.prompt(Messages.settings_resetPrompt, "", function (val) {
- if (val !== "I love CryptPad") { return; }
+ if (val !== "I love CryptPad") {
+ Cryptpad.alert(Messages.settings_resetError);
+ return;
+ }
obj.proxy.drive = Cryptpad.getStore().getEmptyObject();
Cryptpad.alert(Messages.settings_resetDone);
});