Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging

pull/1/head
yflory 5 years ago
commit 3dba20776f

@ -461,6 +461,102 @@ define([
cb(id); cb(id);
}); });
}; };
// convert a folder to a Shared Folder
var _convertFolderToSharedFolder = function (Env, data, cb) {
var path = data.path;
var folderElement = Env.user.userObject.find(path);
// don't try to convert top-level elements (trash, root, etc) to shared-folders
// TODO also validate that you're in root (not templates, etc)
if (data.path.length <= 1) {
return void cb({
error: 'E_INVAL_PATH',
});
}
if (_isInSharedFolder(Env, path)) {
return void cb({
error: 'E_INVAL_NESTING',
});
}
if (Env.user.userObject.hasSubSharedFolder(folderElement)) {
return void cb({
error: 'E_INVAL_NESTING',
});
}
var parentPath = path.slice(0, -1);
var parentFolder = Env.user.userObject.find(parentPath);
var folderName = path[path.length - 1];
var SFId;
nThen(function (waitFor) {
// create shared folder
_addSharedFolder(Env, {
path: parentPath,
name: folderName,
owned: true, // XXX FIXME hardcoded preference
password: '', // XXX FIXME hardcoded preference
}, waitFor(function (id) {
// _addSharedFolder can be an id or an error
if (typeof(id) === 'object' && id && id.error) {
waitFor.abort();
return void cb(id);
} else {
SFId = id;
}
}));
}).nThen(function (waitFor) {
// move everything from folder to SF
if (!SFId) {
waitFor.abort();
return void cb({
error: 'E_NO_ID'
});
}
var paths = [];
for (var el in folderElement) {
if (Env.user.userObject.isFolder(folderElement[el]) || Env.user.userObject.isFile(folderElement[el])) {
paths.push(path.concat(el));
}
}
var SFKey;
// this is basically Array.find, except it works in IE
Object.keys(parentFolder).some(function (el) {
if (parentFolder[el] === SFId) {
SFKey = el;
return true;
}
});
if (!SFKey) {
waitFor.abort();
return void cb({
error: 'E_NO_KEY'
});
}
var newPath = parentPath.concat(SFKey).concat(UserObject.ROOT);
_move(Env, {
paths: paths,
newPath: newPath,
copy: false,
}, waitFor());
}).nThen(function () {
// migrate metadata
var sharedFolderElement = Env.user.proxy[UserObject.SHARED_FOLDERS][SFId];
var metadata = Env.user.userObject.getFolderData(folderElement);
for (var key in metadata) {
// it shouldn't be possible to have nested metadata
// but this is a reasonable sanity check
if (key === "metadata") { continue; }
// copy the metadata from the original folder to the new shared folder
sharedFolderElement[key] = metadata[key];
}
// remove folder
Env.user.userObject.delete([path], function () {
cb();
});
});
};
// Delete permanently some pads or folders // Delete permanently some pads or folders
var _delete = function (Env, data, cb) { var _delete = function (Env, data, cb) {
data = data || {}; data = data || {};
@ -598,6 +694,8 @@ define([
_addFolder(Env, data, cb); break; _addFolder(Env, data, cb); break;
case 'addSharedFolder': case 'addSharedFolder':
_addSharedFolder(Env, data, cb); break; _addSharedFolder(Env, data, cb); break;
case 'convertFolderToSharedFolder':
_convertFolderToSharedFolder(Env, data, cb); break;
case 'delete': case 'delete':
_delete(Env, data, cb); break; _delete(Env, data, cb); break;
case 'emptyTrash': case 'emptyTrash':
@ -914,6 +1012,14 @@ define([
} }
}, cb); }, cb);
}; };
var convertFolderToSharedFolderInner = function (Env, path, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "convertFolderToSharedFolder",
data: {
path: path
}
}, cb);
};
var deleteInner = function (Env, paths, cb) { var deleteInner = function (Env, paths, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", { return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "delete", cmd: "delete",
@ -1074,6 +1180,9 @@ define([
} }
return Env.user.userObject.hasSubfolder(el, trashRoot); return Env.user.userObject.hasSubfolder(el, trashRoot);
}; };
var hasSubSharedFolder = function (Env, el) {
return Env.user.userObject.hasSubSharedFolder(el);
};
var hasFile = function (Env, el, trashRoot) { var hasFile = function (Env, el, trashRoot) {
if (Env.folders[el]) { if (Env.folders[el]) {
var uo = Env.folders[el].userObject; var uo = Env.folders[el].userObject;
@ -1113,6 +1222,7 @@ define([
emptyTrash: callWithEnv(emptyTrashInner), emptyTrash: callWithEnv(emptyTrashInner),
addFolder: callWithEnv(addFolderInner), addFolder: callWithEnv(addFolderInner),
addSharedFolder: callWithEnv(addSharedFolderInner), addSharedFolder: callWithEnv(addSharedFolderInner),
convertFolderToSharedFolder: callWithEnv(convertFolderToSharedFolderInner),
delete: callWithEnv(deleteInner), delete: callWithEnv(deleteInner),
restore: callWithEnv(restoreInner), restore: callWithEnv(restoreInner),
setFolderData: callWithEnv(setFolderDataInner), setFolderData: callWithEnv(setFolderDataInner),
@ -1144,6 +1254,7 @@ define([
isInTrashRoot: callWithEnv(isInTrashRoot), isInTrashRoot: callWithEnv(isInTrashRoot),
comparePath: callWithEnv(comparePath), comparePath: callWithEnv(comparePath),
hasSubfolder: callWithEnv(hasSubfolder), hasSubfolder: callWithEnv(hasSubfolder),
hasSubSharedFolder: callWithEnv(hasSubSharedFolder),
hasFile: callWithEnv(hasFile), hasFile: callWithEnv(hasFile),
// Data // Data
user: Env.user, user: Env.user,

@ -123,7 +123,11 @@ define([
}; };
exp.isFolderEmpty = function (element) { exp.isFolderEmpty = function (element) {
if (!isFolder(element)) { return false; } if (!isFolder(element)) { return false; }
return Object.keys(element).length === 0; // if the folder contains nothing, it's empty
if (Object.keys(element).length === 0) { return true; }
// or if it contains one thing and that thing is metadata
if (Object.keys(element).length === 1 && isFolderData(element[Object.keys(element)[0]])) { return true; }
return false;
}; };
exp.hasSubfolder = function (element, trashRoot) { exp.hasSubfolder = function (element, trashRoot) {
@ -170,6 +174,20 @@ define([
} }
}; };
var hasSubSharedFolder = exp.hasSubSharedFolder = function (folder) {
for (var el in folder) {
if (isSharedFolder(folder[el])) {
return true;
}
else if (isFolder(folder[el])) {
if (hasSubSharedFolder(folder[el])) {
return true;
}
}
}
return false;
};
// Get data from AllFiles (Cryptpad_RECENTPADS) // Get data from AllFiles (Cryptpad_RECENTPADS)
var getFileData = exp.getFileData = function (file) { var getFileData = exp.getFileData = function (file) {
if (!file) { return; } if (!file) { return; }

@ -1101,9 +1101,10 @@ define([
hide.push('collapseall'); hide.push('collapseall');
} }
if (path.length === 1) { if (path.length === 1) {
// Can't rename or delete root elements // Can't rename, share, delete, or change the color of root elements
hide.push('delete'); hide.push('delete');
hide.push('rename'); hide.push('rename');
hide.push('share');
hide.push('color'); hide.push('color');
} }
if (!$element.is('.cp-app-drive-element-owned')) { if (!$element.is('.cp-app-drive-element-owned')) {
@ -1158,7 +1159,6 @@ define([
hide.push('openro'); hide.push('openro');
hide.push('openincode'); hide.push('openincode');
hide.push('properties'); hide.push('properties');
hide.push('share');
hide.push('hashtag'); hide.push('hashtag');
} }
// If we're in the trash, hide restore and properties for non-root elements // If we're in the trash, hide restore and properties for non-root elements
@ -3922,7 +3922,27 @@ define([
editHash: parsed.hash editHash: parsed.hash
} }
}); });
} else { return void UI.openCustomModal(modal, {
wide: Object.keys(friends).length !== 0
});
} else if (manager.isFolder(el)) { // Folder
// if folder is inside SF
if (manager.isInSharedFolder(paths[0].path)) {
return void UI.alert(Messages.convertFolderToSF_SFParent);
}
// if folder already contains SF
else if (manager.hasSubSharedFolder(el)) {
return void UI.alert(Messages.convertFolderToSF_SFChildren);
}
// if folder does not contains SF
else {
return void UI.confirm(Messages.convertFolderToSF_confirm, function(res) {
if (!res) { return; }
if (paths[0].path.length <= 1) { return; } // if root
manager.convertFolderToSharedFolder(paths[0].path, refresh);
});
}
} else { // File
data = manager.getFileData(el); data = manager.getFileData(el);
parsed = Hash.parsePadUrl(data.href); parsed = Hash.parsePadUrl(data.href);
var roParsed = Hash.parsePadUrl(data.roHref); var roParsed = Hash.parsePadUrl(data.roHref);
@ -3948,11 +3968,11 @@ define([
modal = padType === 'file' ? UIElements.createFileShareModal(padData) modal = padType === 'file' ? UIElements.createFileShareModal(padData)
: UIElements.createShareModal(padData); : UIElements.createShareModal(padData);
modal = UI.dialog.tabs(modal); modal = UI.dialog.tabs(modal);
}
UI.openCustomModal(modal, { UI.openCustomModal(modal, {
wide: Object.keys(friends).length !== 0 wide: Object.keys(friends).length !== 0
}); });
} }
}
else if ($this.hasClass('cp-app-drive-context-newfolder')) { else if ($this.hasClass('cp-app-drive-context-newfolder')) {
if (paths.length !== 1) { return; } if (paths.length !== 1) { return; }
var onFolderCreated = function (err, info) { var onFolderCreated = function (err, info) {

Loading…
Cancel
Save