Merge branch 'pad2' of github.com:xwiki-labs/cryptpad into pad2
This commit is contained in:
commit
8a9755611a
@ -56,7 +56,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
iframe {
|
iframe {
|
||||||
height: auto;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -205,6 +205,13 @@ define([
|
|||||||
var randomToken = function () {
|
var randomToken = function () {
|
||||||
return Math.random().toString(16).replace(/0./, '');
|
return Math.random().toString(16).replace(/0./, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
common.isFeedbackAllowed = function () {
|
||||||
|
try {
|
||||||
|
if (!getStore().getProxy().proxy.allowUserFeedback) { return; }
|
||||||
|
return true;
|
||||||
|
} catch (e) { return void console.error(e); }
|
||||||
|
};
|
||||||
var feedback = common.feedback = function (action, force) {
|
var feedback = common.feedback = function (action, force) {
|
||||||
if (force !== true) {
|
if (force !== true) {
|
||||||
if (!action) { return; }
|
if (!action) { return; }
|
||||||
|
|||||||
@ -101,10 +101,29 @@ define([
|
|||||||
ctx.sframeChan.query('Q_GET_FULL_HISTORY', null, cb);
|
ctx.sframeChan.query('Q_GET_FULL_HISTORY', null, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO
|
funcs.feedback = function (action, force) {
|
||||||
|
if (force !== true) {
|
||||||
|
if (!action) { return; }
|
||||||
|
try {
|
||||||
|
if (!ctx.metadataMgr.getPrivateData().feedbackAllowed) { return; }
|
||||||
|
} catch (e) { return void console.error(e); }
|
||||||
|
}
|
||||||
|
var randomToken = Math.random().toString(16).replace(/0./, '');
|
||||||
|
var origin = ctx.metadataMgr.getPrivateData().origin;
|
||||||
|
var href = /*origin +*/ '/common/feedback.html?' + action + '=' + randomToken;
|
||||||
|
$.ajax({
|
||||||
|
type: "HEAD",
|
||||||
|
url: href,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var prepareFeedback = function (key) {
|
||||||
|
if (typeof(key) !== 'string') { return $.noop; }
|
||||||
|
|
||||||
funcs.feedback = function () {};
|
var type = ctx.metadataMgr.getMetadata().type;
|
||||||
var prepareFeedback = function () {};
|
return function () {
|
||||||
|
funcs.feedback((key + (type? '_' + type: '')).toUpperCase());
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// BUTTONS
|
// BUTTONS
|
||||||
var isStrongestStored = function () {
|
var isStrongestStored = function () {
|
||||||
|
|||||||
@ -161,6 +161,7 @@ define([
|
|||||||
var metadataMgr = config.metadataMgr;
|
var metadataMgr = config.metadataMgr;
|
||||||
var userData = metadataMgr.getMetadata().users;
|
var userData = metadataMgr.getMetadata().users;
|
||||||
var viewers = metadataMgr.getViewers();
|
var viewers = metadataMgr.getViewers();
|
||||||
|
var origin = config.metadataMgr.getPrivateData().origin;
|
||||||
|
|
||||||
// If we are using old pads (readonly unavailable), only editing users are in userList.
|
// If we are using old pads (readonly unavailable), only editing users are in userList.
|
||||||
// With new pads, we also have readonly users in userList, so we have to intersect with
|
// With new pads, we also have readonly users in userList, so we have to intersect with
|
||||||
@ -225,7 +226,7 @@ define([
|
|||||||
if (data.profile) {
|
if (data.profile) {
|
||||||
$span.addClass('clickable');
|
$span.addClass('clickable');
|
||||||
$span.click(function () {
|
$span.click(function () {
|
||||||
window.open('/profile/#' + data.profile);
|
window.open(origin+'/profile/#' + data.profile);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (data.avatar && avatars[data.avatar]) {
|
if (data.avatar && avatars[data.avatar]) {
|
||||||
|
|||||||
@ -413,6 +413,15 @@ define([
|
|||||||
});
|
});
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
exp.getRecentPads = function () {
|
||||||
|
var allFiles = files[FILES_DATA];
|
||||||
|
var sorted = Object.keys(allFiles)
|
||||||
|
.sort(function (a,b) {
|
||||||
|
return allFiles[a].atime < allFiles[b].atime;
|
||||||
|
})
|
||||||
|
.map(function (str) { return Number(str); });
|
||||||
|
return sorted;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OPERATIONS
|
* OPERATIONS
|
||||||
|
|||||||
@ -190,7 +190,8 @@ span {
|
|||||||
}
|
}
|
||||||
.docTree {
|
.docTree {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
padding: 0 0 0 20px;
|
//padding: 0 0 0 20px;
|
||||||
|
padding: 0;
|
||||||
cursor: auto;
|
cursor: auto;
|
||||||
&li, li {
|
&li, li {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -304,6 +305,24 @@ span {
|
|||||||
top: -1px;
|
top: -1px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.docTree {
|
||||||
|
.root > .element-row > .expcol {
|
||||||
|
position: relative;
|
||||||
|
top:0;
|
||||||
|
left: -10px;
|
||||||
|
}
|
||||||
|
.root > .element-row > .folder {
|
||||||
|
margin-left: -5px;
|
||||||
|
}
|
||||||
|
.root {
|
||||||
|
&> .element-row {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
&> ul {
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Expand/collapse lines
|
// Expand/collapse lines
|
||||||
.docTree ul {
|
.docTree ul {
|
||||||
@ -478,9 +497,26 @@ span {
|
|||||||
.listElement {
|
.listElement {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.addpad {
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.5;
|
||||||
|
padding: 0;
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
.fa {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 100px;
|
||||||
|
line-height: 140px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
|
.grid-element {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
// Make it act as a table!
|
// Make it act as a table!
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
ul {
|
ul {
|
||||||
|
|||||||
@ -51,6 +51,8 @@ define([
|
|||||||
var TEMPLATE_NAME = Messages.fm_templateName;
|
var TEMPLATE_NAME = Messages.fm_templateName;
|
||||||
var TRASH = "trash";
|
var TRASH = "trash";
|
||||||
var TRASH_NAME = Messages.fm_trashName;
|
var TRASH_NAME = Messages.fm_trashName;
|
||||||
|
var RECENT = "recent";
|
||||||
|
var RECENT_NAME = "Recent pads";
|
||||||
|
|
||||||
var LOCALSTORAGE_LAST = "cryptpad-file-lastOpened";
|
var LOCALSTORAGE_LAST = "cryptpad-file-lastOpened";
|
||||||
var LOCALSTORAGE_OPENED = "cryptpad-file-openedFolders";
|
var LOCALSTORAGE_OPENED = "cryptpad-file-openedFolders";
|
||||||
@ -172,6 +174,7 @@ define([
|
|||||||
var $closeIcon = $('<span>', {"class": "fa fa-window-close"});
|
var $closeIcon = $('<span>', {"class": "fa fa-window-close"});
|
||||||
var $backupIcon = $('<span>', {"class": "fa fa-life-ring"});
|
var $backupIcon = $('<span>', {"class": "fa fa-life-ring"});
|
||||||
var $searchIcon = $('<span>', {"class": "fa fa-search searchIcon"});
|
var $searchIcon = $('<span>', {"class": "fa fa-search searchIcon"});
|
||||||
|
var $addIcon = $('<span>', {"class": "fa fa-plus"});
|
||||||
|
|
||||||
var history = {
|
var history = {
|
||||||
isHistoryMode: false,
|
isHistoryMode: false,
|
||||||
@ -233,9 +236,10 @@ define([
|
|||||||
|
|
||||||
// Categories dislayed in the menu
|
// Categories dislayed in the menu
|
||||||
// _WORKGROUP_ : do not display unsorted
|
// _WORKGROUP_ : do not display unsorted
|
||||||
var displayedCategories = [ROOT, TRASH, SEARCH];
|
var displayedCategories = [ROOT, TRASH, SEARCH, RECENT];
|
||||||
if (AppConfig.enableTemplates) { displayedCategories.push(TEMPLATE); }
|
if (AppConfig.enableTemplates) { displayedCategories.push(TEMPLATE); }
|
||||||
if (isWorkgroup()) { displayedCategories = [ROOT, TRASH, SEARCH]; }
|
if (isWorkgroup()) { displayedCategories = [ROOT, TRASH, SEARCH]; }
|
||||||
|
var virtualCategories = [SEARCH, RECENT];
|
||||||
|
|
||||||
if (!APP.loggedIn) {
|
if (!APP.loggedIn) {
|
||||||
displayedCategories = [FILES_DATA];
|
displayedCategories = [FILES_DATA];
|
||||||
@ -1259,6 +1263,7 @@ define([
|
|||||||
case TEMPLATE: pName = TEMPLATE_NAME; break;
|
case TEMPLATE: pName = TEMPLATE_NAME; break;
|
||||||
case FILES_DATA: pName = FILES_DATA_NAME; break;
|
case FILES_DATA: pName = FILES_DATA_NAME; break;
|
||||||
case SEARCH: pName = SEARCH_NAME; break;
|
case SEARCH: pName = SEARCH_NAME; break;
|
||||||
|
case RECENT: pName = RECENT_NAME; break;
|
||||||
default: pName = name;
|
default: pName = name;
|
||||||
}
|
}
|
||||||
return pName;
|
return pName;
|
||||||
@ -1318,6 +1323,9 @@ define([
|
|||||||
case FILES_DATA:
|
case FILES_DATA:
|
||||||
msg = Messages.fm_info_allFiles;
|
msg = Messages.fm_info_allFiles;
|
||||||
break;
|
break;
|
||||||
|
case RECENT:
|
||||||
|
msg = Messages.fm_info_recent || 'TODO';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
msg = undefined;
|
msg = undefined;
|
||||||
}
|
}
|
||||||
@ -1805,6 +1813,50 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var displayRecent = function ($list) {
|
||||||
|
var filesList = filesOp.getRecentPads();
|
||||||
|
var limit = 20;
|
||||||
|
var i = 0;
|
||||||
|
filesList.forEach(function (id) {
|
||||||
|
if (i >= 20) { return; }
|
||||||
|
// Check path (pad exists and not in trash)
|
||||||
|
var paths = filesOp.findFile(id);
|
||||||
|
if (!paths.length) { return; }
|
||||||
|
var path = paths[0];
|
||||||
|
if (filesOp.isPathIn(path, [TRASH])) { return; }
|
||||||
|
// Display the pad
|
||||||
|
var file = filesOp.getFileData(id);
|
||||||
|
if (!file) {
|
||||||
|
//debug("Unsorted or template returns an element not present in filesData: ", href);
|
||||||
|
file = { title: Messages.fm_noname };
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
var $icon = getFileIcon(id);
|
||||||
|
var ro = filesOp.isReadOnlyFile(id);
|
||||||
|
// ro undefined mens it's an old hash which doesn't support read-only
|
||||||
|
var roClass = typeof(ro) === 'undefined' ? ' noreadonly' : ro ? ' readonly' : '';
|
||||||
|
var $element = $('<li>', {
|
||||||
|
'class': 'file-element element element-row' + roClass,
|
||||||
|
});
|
||||||
|
addFileData(id, $element);
|
||||||
|
$element.prepend($icon).dblclick(function () {
|
||||||
|
openFile(id);
|
||||||
|
});
|
||||||
|
$element.data('path', path);
|
||||||
|
$element.click(function(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
onElementClick(e, $element, path);
|
||||||
|
});
|
||||||
|
$element.contextmenu(openDefaultContextMenu);
|
||||||
|
$element.data('context', $defaultContextMenu);
|
||||||
|
/*if (draggable) {
|
||||||
|
addDragAndDropHandlers($element, path, false, false);
|
||||||
|
}*/
|
||||||
|
$list.append($element);
|
||||||
|
i++;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Display the selected directory into the content part (rightside)
|
// Display the selected directory into the content part (rightside)
|
||||||
// NOTE: Elements in the trash are not using the same storage structure as the others
|
// NOTE: Elements in the trash are not using the same storage structure as the others
|
||||||
// _WORKGROUP_ : do not change the lastOpenedFolder value in localStorage
|
// _WORKGROUP_ : do not change the lastOpenedFolder value in localStorage
|
||||||
@ -1833,9 +1885,11 @@ define([
|
|||||||
var isTemplate = filesOp.comparePath(path, [TEMPLATE]);
|
var isTemplate = filesOp.comparePath(path, [TEMPLATE]);
|
||||||
var isAllFiles = filesOp.comparePath(path, [FILES_DATA]);
|
var isAllFiles = filesOp.comparePath(path, [FILES_DATA]);
|
||||||
var isSearch = path[0] === SEARCH;
|
var isSearch = path[0] === SEARCH;
|
||||||
|
var isRecent = path[0] === RECENT;
|
||||||
|
var isVirtual = virtualCategories.indexOf(path[0]) !== -1;
|
||||||
|
|
||||||
var root = isSearch ? undefined : filesOp.find(path);
|
var root = isVirtual ? undefined : filesOp.find(path);
|
||||||
if (!isSearch && typeof(root) === "undefined") {
|
if (!isVirtual && typeof(root) === "undefined") {
|
||||||
log(Messages.fm_unknownFolderError);
|
log(Messages.fm_unknownFolderError);
|
||||||
debug("Unable to locate the selected directory: ", path);
|
debug("Unable to locate the selected directory: ", path);
|
||||||
var parentPath = path.slice();
|
var parentPath = path.slice();
|
||||||
@ -1921,6 +1975,8 @@ define([
|
|||||||
displayTrashRoot($list, $folderHeader, $fileHeader);
|
displayTrashRoot($list, $folderHeader, $fileHeader);
|
||||||
} else if (isSearch) {
|
} else if (isSearch) {
|
||||||
displaySearch($list, path[1]);
|
displaySearch($list, path[1]);
|
||||||
|
} else if (isRecent) {
|
||||||
|
displayRecent($list);
|
||||||
} else {
|
} else {
|
||||||
$dirContent.contextmenu(openContentContextMenu);
|
$dirContent.contextmenu(openContentContextMenu);
|
||||||
if (filesOp.hasSubfolder(root)) { $list.append($folderHeader); }
|
if (filesOp.hasSubfolder(root)) { $list.append($folderHeader); }
|
||||||
@ -1940,6 +1996,21 @@ define([
|
|||||||
var $element = createElement(path, key, root, false);
|
var $element = createElement(path, key, root, false);
|
||||||
$element.appendTo($list);
|
$element.appendTo($list);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var $element = $('<li>', {
|
||||||
|
'class': 'element-row grid-element addpad'
|
||||||
|
}).prepend($addIcon.clone()).appendTo($list);
|
||||||
|
$element.attr('title', "TODO: Add a pad");
|
||||||
|
$element.click(function () {
|
||||||
|
window.setTimeout(function () {
|
||||||
|
$driveToolbar.find('.leftside .dropdown-bar-content').show();
|
||||||
|
});
|
||||||
|
/*var $content = $driveToolbar.find('.leftside .dropdown-bar-content').html();
|
||||||
|
var $container = $('<div>').append($('<div>', {id:'cryptpad-add-pad'}));
|
||||||
|
Cryptpad.alert($container.html(),null,true);
|
||||||
|
var $c = $('body > .alertify').last().find('#cryptpad-add-pad');
|
||||||
|
$c.append($content);*/
|
||||||
|
});
|
||||||
}
|
}
|
||||||
//$content.append($toolbar).append($title).append($info).append($dirContent);
|
//$content.append($toolbar).append($title).append($info).append($dirContent);
|
||||||
$content.append($info).append($dirContent);
|
$content.append($info).append($dirContent);
|
||||||
@ -2037,7 +2108,10 @@ define([
|
|||||||
var $rootIcon = filesOp.isFolderEmpty(files[ROOT]) ?
|
var $rootIcon = filesOp.isFolderEmpty(files[ROOT]) ?
|
||||||
(isRootOpened ? $folderOpenedEmptyIcon : $folderEmptyIcon) :
|
(isRootOpened ? $folderOpenedEmptyIcon : $folderEmptyIcon) :
|
||||||
(isRootOpened ? $folderOpenedIcon : $folderIcon);
|
(isRootOpened ? $folderOpenedIcon : $folderIcon);
|
||||||
var $rootElement = createTreeElement(ROOT_NAME, $rootIcon.clone(), [ROOT], false, true, false, isRootOpened);
|
var $rootElement = createTreeElement(ROOT_NAME, $rootIcon.clone(), [ROOT], false, true, true, isRootOpened);
|
||||||
|
if (!filesOp.hasSubfolder(root)) {
|
||||||
|
$rootElement.find('.expcol').css('visibility', 'hidden');
|
||||||
|
}
|
||||||
$rootElement.addClass('root');
|
$rootElement.addClass('root');
|
||||||
$rootElement.find('>.element-row').contextmenu(openDirectoryContextMenu);
|
$rootElement.find('>.element-row').contextmenu(openDirectoryContextMenu);
|
||||||
$('<ul>', {'class': 'docTree'}).append($rootElement).appendTo($container);
|
$('<ul>', {'class': 'docTree'}).append($rootElement).appendTo($container);
|
||||||
@ -2093,6 +2167,15 @@ define([
|
|||||||
$container.append($trashList);
|
$container.append($trashList);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var createRecent = function ($container, path) {
|
||||||
|
var $icon = $templateIcon.clone(); //TODO
|
||||||
|
var isOpened = filesOp.comparePath(path, currentPath);
|
||||||
|
var $element = createTreeElement(RECENT_NAME, $icon, [RECENT], false, false, false, isOpened);
|
||||||
|
$element.addClass('root');
|
||||||
|
var $list = $('<ul>', { id: 'recentTree', 'class': 'category' }).append($element);
|
||||||
|
$container.append($list);
|
||||||
|
};
|
||||||
|
|
||||||
var search = APP.Search = {};
|
var search = APP.Search = {};
|
||||||
var createSearch = function ($container) {
|
var createSearch = function ($container) {
|
||||||
var isInSearch = currentPath[0] === SEARCH;
|
var isInSearch = currentPath[0] === SEARCH;
|
||||||
@ -2145,6 +2228,7 @@ define([
|
|||||||
$tree.html('');
|
$tree.html('');
|
||||||
if (displayedCategories.indexOf(SEARCH) !== -1) { createSearch($tree); }
|
if (displayedCategories.indexOf(SEARCH) !== -1) { createSearch($tree); }
|
||||||
var $div = $('<div>', {'class': 'categories-container'}).appendTo($tree);
|
var $div = $('<div>', {'class': 'categories-container'}).appendTo($tree);
|
||||||
|
if (displayedCategories.indexOf(RECENT) !== -1) { createRecent($div, [RECENT]); }
|
||||||
if (displayedCategories.indexOf(ROOT) !== -1) { createTree($div, [ROOT]); }
|
if (displayedCategories.indexOf(ROOT) !== -1) { createTree($div, [ROOT]); }
|
||||||
if (displayedCategories.indexOf(TEMPLATE) !== -1) { createTemplate($div, [TEMPLATE]); }
|
if (displayedCategories.indexOf(TEMPLATE) !== -1) { createTemplate($div, [TEMPLATE]); }
|
||||||
if (displayedCategories.indexOf(FILES_DATA) !== -1) { createAllFiles($div, [FILES_DATA]); }
|
if (displayedCategories.indexOf(FILES_DATA) !== -1) { createAllFiles($div, [FILES_DATA]); }
|
||||||
|
|||||||
@ -528,11 +528,11 @@ define([
|
|||||||
$collapse.removeClass('fa-caret-down').removeClass('fa-caret-up');
|
$collapse.removeClass('fa-caret-down').removeClass('fa-caret-up');
|
||||||
var isCollapsed = !$bar.find('.cke_toolbox_main').is(':visible');
|
var isCollapsed = !$bar.find('.cke_toolbox_main').is(':visible');
|
||||||
if (isCollapsed) {
|
if (isCollapsed) {
|
||||||
if (!initializing) { Cryptpad.feedback('HIDETOOLBAR_PAD'); }
|
if (!initializing) { common.feedback('HIDETOOLBAR_PAD'); }
|
||||||
$collapse.addClass('fa-caret-down');
|
$collapse.addClass('fa-caret-down');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!initializing) { Cryptpad.feedback('SHOWTOOLBAR_PAD'); }
|
if (!initializing) { common.feedback('SHOWTOOLBAR_PAD'); }
|
||||||
$collapse.addClass('fa-caret-up');
|
$collapse.addClass('fa-caret-up');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -721,7 +721,7 @@ define([
|
|||||||
|
|
||||||
var id = classes[0];
|
var id = classes[0];
|
||||||
if (typeof(id) === 'string') {
|
if (typeof(id) === 'string') {
|
||||||
Cryptpad.feedback(id.toUpperCase());
|
common.feedback(id.toUpperCase());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -77,7 +77,8 @@ define([
|
|||||||
pathname: window.location.pathname,
|
pathname: window.location.pathname,
|
||||||
readOnly: readOnly,
|
readOnly: readOnly,
|
||||||
availableHashes: hashes,
|
availableHashes: hashes,
|
||||||
isTemplate: Cryptpad.isTemplate(window.location.href)
|
isTemplate: Cryptpad.isTemplate(window.location.href),
|
||||||
|
feedbackAllowed: Cryptpad.isFeedbackAllowed()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user