Merge branch 'soon' into staging

This commit is contained in:
ansuz 2018-09-20 11:44:56 -04:00
commit ad4e36015b
10 changed files with 2056 additions and 67 deletions

View File

@ -18,6 +18,7 @@ www/pad/mediatag-plugin-dialog.js
www/pad/disable-base64.js
www/kanban/jkanban.js
www/kanban/jscolor.js
www/common/media-tag-nacl.min.js

View File

@ -1,3 +1,30 @@
# Ibis release (v2.8.0)
## Goals
We've been making use of some hidden features for a while, to make sure that they were safe to deploy.
This release, we worked on making _contextual chat_ and _shared folders_ available to everyone.
## Update notes
* run `bower update` to download an updated version of _marked.js_
### Features
* Our kanban application now features a much more consistent and flexible colorpicker, thanks to @MTRNord (https://github.com/MTRNord)
* File upload dialogs now allow you to upload multiple files at once
* Updated German translations thanks to [b3yond](https://github.com/b3yond/)
* An explicit pad storage policy to better suit different privacy constraints
* _import local pads_ at login time is no longer default
* An embedded chat room in every pad, so you can work alongside your fellow editors more easily
* Promotion of our [crowdfunding campaign](https://opencollective.com/cryptpad), including a button on the home page, and a one-time dialog for users
### Bug fixes
* Updating our markdown library resolved an issue which incorrectly rendered links containing parentheses.
* We discovered an issue logging in with _very old_ credentials which were initialized without a public key. We now regenerate your keyring if you do not have public keys stored in association with your account.
* We found another bug in our login process; under certain conditions the terminating function could be called more than once.
# Hedgehog release (v2.7.0)
## Goals

View File

@ -615,17 +615,21 @@ define([
}
]);
var _link = h('a', {
href: "https://opencollective.com/cryptpad/contribute",
target: '_blank',
rel: 'noopener',
});
var crowdFunding = AppConfig.disableCrowdfundingMessages ? undefined : h('button', [
Msg.crowdfunding_home1,
h('br'),
Msg.crowdfunding_home2
Msg.crowdfunding_home2,
_link
]);
$(crowdFunding).click(function () {
var a = document.createElement("a");
a.href = "https://opencollective.com/cryptpad/contribute";
a.target = "_blank";
a.rel = "noopener";
a.click();
_link.click();
});
return [

View File

@ -567,6 +567,14 @@ define(function () {
out.settings_importConfirm = "Bist Du sicher, dass Du die kürzlich besuchte Dokumente in Deinem Konto importieren möchtest??";
out.settings_importDone = "Import erledigt";
out.settings_autostoreTitle = "Automatisches Speichern im CryptDrive";
out.settings_autostoreHint = "<b>Automatisch:</b> Alle Pads werden in deinem CryptDrive gespeichert.<br>" +
"<b>Manuell (immer nachfragen):</b> Wenn du ein Pad noch nicht gespeichert hast, wirst du gefragt, ob du es im CryptDrive speichern willst.<br>" +
"<b>Manuell (nie nachfragen):</b> Pads werden nicht automatisch im CryptDrive gespeichert. Die Option, sie trotzdem zu speichern, ist versteckt.<br>";
out.settings_autostoreYes = "Automatisch";
out.settings_autostoreNo = "Manuell (nie nachfragen)";
out.settings_autostoreMaybe = "Manual (immer nachfragen)";
out.settings_userFeedbackTitle = "Rückmeldung";
out.settings_userFeedbackHint1 = "CryptPad gibt grundlegende Rückmeldungen zum Server, um die Benutzer-Erfahrung zu verbessern können.";
out.settings_userFeedbackHint2 = "Der Inhalt deiner Dokumente wird nie mit dem Server geteilt.";
@ -1107,7 +1115,7 @@ define(function () {
out.readme_cat2_l2 = "Der Titel eines Dokuments kann mit einem Klick auf den Stift geändert werden.";
out.readme_cat3 = "Entdecke CryptPad Apps";
out.readme_cat3_l1 = "Mit dem CryptPad Codeeditor kannst du Code wie JavaScript, Markdown, oder HTML bearbeiten";
out.readme_cat3_l2 = "Mit dem CryptPad Präsentationseditor kannst du schnell Vorträge mit Hilfe von Markdwon gestalten";
out.readme_cat3_l2 = "Mit dem CryptPad Präsentationseditor kannst du schnell Vorträge mit Hilfe von Markdown gestalten";
out.readme_cat3_l3 = "Mit der CryptPad Umfrage kannst du schnell Abstimmungen durchführen, insbesondere, um Meetings zu planen, die in den Kalender von allen passen.";
// Tips
@ -1200,6 +1208,27 @@ define(function () {
out.loading_drive_2 = "Aktualisiere Datenformat";
out.loading_drive_3 = "Verifiziere Datenintegrität";
// Shared folders
out.sharedFolders_forget = "Dieses pad wird nur in einem geteilten Ordner gespeichert, du kannst es nicht in den Papierkorb verschieben. Du kannst es in deinem CryptDrive löschen.";
out.sharedFolders_duplicate = "Einige der pads, die du versucht hast zu verschieben, waren schon im Zielordner geteilt.";
out.sharedFolders_create = "Erstelle einen geteilten Ordner";
out.sharedFolders_create_name = "Neuer Ordner";
out.sharedFolders_create_owned = "Eigener Ordner";
out.sharedFolders_create_password = "Ordnerpasswort";
out.sharedFolders_share = "Teile diese URL mit anderen registrierten Benutzern, um ihnen Zugriff auf den geteilten Ordner zu geben. Sobald sie diese URL öffnen, wird der geteilte Ordner zu ihrem CryptDrive hinzugefügt.";
out.chrome68 = "Anscheinend benutzt du Chrome oder Chromium version 68. Darin ist ein bug, der dafür sorgt, dass nach ein paar Sekunden die Seite komplett weiß ist oder nicht mehr auf Klicks reagiert. Um das Problem zu beheben, wechsle den Tab und komme wieder, oder versuche zu scrollen. Dieser Bug sollte in der nächsten Version deines Browsers gefixt sein.";
// Manual pad storage popup
out.autostore_notstored = "Dieses Pad ist noch nicht in deinem CryptDrive. Willst du es jetzt speichern?";
out.autostore_settings = "Du kannst automatisches Speichern im CryptDrive in deinen <a href=\"/settings/\">Einstellungen</a> aktivieren!";
out.autostore_store = "Speichern";
out.autostore_hide = "Nicht speichern";
out.autostore_error = "Unerwarteter Fehler: wir konnten das Pad nicht speichern, bitte versuche es nochmal.";
out.autostore_saved = "Das Pad wurde erfolgreich in deinem CryptDrive gespeichert!";
out.autostore_forceSave = "Speicher die Datei in deinem CryptDrive"; // File upload modal
out.autostore_notAvailable = "Du musst dieses Pad in deinem CryptDrive speichern, bevor du dieses Feature benutzen kannst."; // Properties/tags/move to trash
return out;
});

View File

@ -583,9 +583,9 @@ define(function () {
out.settings_importDone = "Import completed";
out.settings_autostoreTitle = "Pad storage in CryptDrive";
out.settings_autostoreHint = "<b>Automatic</b> pad storage results in all the pads you visit being stored in your CryptDrive.<br>" +
"<b>Manual (always ask)</b> results in the pads not being stored but a reminder will appear to ask you if you want to store them in CryptDrive.<br>" +
"<b>Manual (never ask)</b> results in the pads not being stored and option to store them will be available but in a hidden way.";
out.settings_autostoreHint = "<b>Automatic</b> All the pads you visit are stored in your CryptDrive.<br>" +
"<b>Manual (always ask)</b> If you have not stored a pad yet, you will be asked if you want to store them in your CryptDrive.<br>" +
"<b>Manual (never ask)</b> Pads are not stored automatically in your Cryptpad. The option to store them will be hidden.";
out.settings_autostoreYes = "Automatic";
out.settings_autostoreNo = "Manual (never ask)";
out.settings_autostoreMaybe = "Manual (always ask)";

View File

@ -130,7 +130,7 @@ define(function() {
// spontaneously, resulting in the deletion of the entire folder's content.
// We highly recommend to keep them disabled until they are stable enough to be enabled
// by default by the CryptPad developers.
config.disableSharedFolders = true;
config.disableSharedFolders = false;
return config;
});

View File

@ -117,39 +117,39 @@
}
.kanban-header-yellow {
background: #FC3;
background: #FC3 !important;
}
.kanban-header-orange {
background: #F91;
background: #F91 !important;
}
.kanban-header-blue {
background: #0AC;
background: #0AC !important;
}
.kanban-header-red {
background: #E43;
background: #E43 !important;
}
.kanban-header-green {
background: #8C4;
background: #8C4 !important;
}
.kanban-header-purple {
background: #c851ff;
background: #c851ff !important;
}
.kanban-header-cyan {
background: #00ffff;
background: #00ffff !important;
}
.kanban-header-lightgreen {
background: #c3ff5b;
background: #c3ff5b !important;
}
.kanban-header-lightblue {
background: #adeeff;
background: #adeeff !important;
}
@media (max-width: @browser_media-medium-screen) {

View File

@ -10,6 +10,7 @@ define([
'/common/modes.js',
'/customize/messages.js',
'/kanban/jkanban.js',
'/kanban/jscolor.js',
'css!/kanban/jkanban.css',
'less!/kanban/app-kanban.less'
@ -107,7 +108,7 @@ define([
var kanban = new window.jKanban({
element: '#cp-app-kanban-content',
gutter: '15px',
gutter: '5px',
widthBoard: '300px',
buttonContent: '❌',
colors: COLORS,
@ -138,7 +139,7 @@ define([
// Remove the input
$(el).text(name);
// Save the value for the correct board
var board = $(el.parentNode.parentNode).attr("data-id");
var board = $(el.parentNode.parentNode.parentNode).attr("data-id");
var pos = kanban.findElementPosition(el);
kanban.getBoardJSON(board).item[pos].title = name;
kanban.onChange();
@ -206,24 +207,53 @@ define([
}
});
},
colorClick: function (el) {
colorClick: function (el, type) {
if (framework.isReadOnly() || framework.isLocked()) { return; }
verbose("in color click");
var board = $(el.parentNode).attr("data-id");
var boardJSON = kanban.getBoardJSON(board);
verbose("on color click");
var boardJSON;
var board;
if (type === "board") {
verbose("board color click");
board = $(el.parentNode).attr("data-id");
boardJSON = kanban.getBoardJSON(board);
} else {
verbose("item color click");
board = $(el.parentNode.parentNode).attr("data-id");
var pos = kanban.findElementPosition(el);
boardJSON = kanban.getBoardJSON(board).item[pos];
}
var onchange = function (colorL) {
var elL = el;
var typeL = type;
var boardJSONL;
var boardL;
if (typeL === "board") {
verbose("board color change");
boardL = $(elL.parentNode).attr("data-id");
boardJSONL = kanban.getBoardJSON(boardL);
} else {
verbose("item color change");
boardL = $(elL.parentNode.parentNode).attr("data-id");
var pos = kanban.findElementPosition(elL);
boardJSONL = kanban.getBoardJSON(boardL).item[pos];
}
var currentColor = boardJSONL.color;
verbose("Current color " + currentColor);
if (currentColor !== colorL.toString()) {
$(elL).removeClass("kanban-header-" + currentColor);
boardJSONL.color = colorL.toString();
kanban.onChange();
}
};
var jscolorL;
el._jscLinkedInstance = undefined;
jscolorL = new window.jscolor(el,{onFineChange: onchange, valueElement:undefined});
jscolorL.show();
var currentColor = boardJSON.color;
verbose("Current color " + currentColor);
var index = kanban.options.colors.findIndex(function (element) {
return (element === currentColor);
}) + 1;
verbose("Next index " + index);
if (index >= kanban.options.colors.length) { index = 0; }
var nextColor = kanban.options.colors[index];
verbose("Next color " + nextColor);
boardJSON.color = nextColor;
$(el).removeClass("kanban-header-" + currentColor);
$(el).addClass("kanban-header-" + nextColor);
kanban.onChange();
if (currentColor === undefined) {
currentColor = '';
}
jscolorL.fromString(currentColor);
},
buttonClick: function (el, boardId, e) {
e.stopPropagation();

View File

@ -52,6 +52,7 @@
widthBoard: '250px',
responsive: '700',
colors: ["yellow", "green", "blue", "red", "orange"],
responsivePercentage: false,
boards: [],
dragBoards: true,
addItemButton: false,
@ -67,7 +68,7 @@
click: function (el) {},
boardTitleclick: function (el, boardId) {},
buttonClick: function (el, boardId) {},
colorClick: function (el, boardId) {},
colorClick: function (el, type) {},
addItemClick: function (el, boardId) {},
onChange: function () {}
};
@ -85,12 +86,12 @@
//Init Drag Board
self.drakeBoard = self.dragula([self.container], {
moves: function (el, source, handle, sibling) {
if (self.options.readOnly) { return false; }
if (self.options.readOnly) { return false; }
if (!self.options.dragBoards) return false;
return (handle.classList.contains('kanban-board-header') || handle.classList.contains('kanban-title-board'));
},
accepts: function (el, target, source, sibling) {
if (self.options.readOnly) { return false; }
if (self.options.readOnly) { return false; }
return target.classList.contains('kanban-container');
},
revertOnSpill: true,
@ -144,15 +145,18 @@
//Init Drag Item
self.drake = self.dragula(self.boardContainer, {
moves: function (el, source, handle, sibling) {
if (self.options.readOnly) { return false; }
return handle.classList.contains('kanban-item');
},
accepts: function (el, target, source, sibling) {
if (self.options.readOnly) { return false; }
return true;
},
revertOnSpill: true
moves: function (el, source, handle, sibling) {
if (self.options.readOnly) { return false; }
return handle.classList.contains('kanban-item');
},
accepts: function (el, target, source, sibling) {
if (self.options.readOnly) { return false; }
return true;
},
revertOnSpill: true
})
.on('cancel', function(el, container, source) {
self.enableAllBoards();
})
.on('drag', function (el, source) {
// we need to calculate the position before starting to drag
@ -184,7 +188,9 @@
var boardId = source.parentNode.dataset.id;
self.options.dragcancelEl(el, boardId);
})
.on('drop', function (el, target, source, sibling) {
.on('drop', function(el, target, source, sibling) {
self.enableAllBoards();
console.log("In drop");
// TODO: update board object board order
@ -229,7 +235,7 @@
// if (board1==board2 && pos2<pos1)
// pos2 = pos2;
// moving element to target array
// moving element to target array
board1.item.splice(pos1, 1);
board2.item.splice(pos2 - 1, 0, item);
@ -240,9 +246,18 @@
}
};
this.enableAllBoards = function() {
var allB = document.querySelectorAll('.kanban-board');
if (allB.length > 0 && allB !== undefined) {
for (var i = 0; i < allB.length; i++) {
allB[i].classList.remove('disabled-board');
}
}
};
this.addElement = function (boardID, element) {
// add Element to JSON
// add Element to JSON
var boardJSON = __findBoardJSON(boardID);
boardJSON.item.push({
title: element.title
@ -260,6 +275,7 @@
nodeItem.dragendfn = element.dragend;
nodeItem.dropfn = element.drop;
__onclickHandler(nodeItem);
__onColorClickHandler(nodeItem, "item");
board.appendChild(nodeItem);
// send event that board has changed
self.onChange();
@ -272,8 +288,19 @@
return self;
};
this.addBoards = function (boards) {
var boardWidth = self.options.widthBoard;
this.addBoards = function(boards) {
if (self.options.responsivePercentage) {
self.container.style.width = '100%';
self.options.gutter = '1%';
if (window.innerWidth > self.options.responsive) {
var boardWidth = (100 - boards.length * 2) / boards.length;
} else {
var boardWidth = 100 - (boards.length * 2);
}
} else {
var boardWidth = self.options.widthBoard;
}
var addButton = self.options.addItemButton;
var buttonContent = self.options.buttonContent;
@ -290,7 +317,11 @@
boardNode.dataset.id = board.id;
boardNode.classList.add('kanban-board');
//set style
boardNode.style.width = boardWidth;
if (self.options.responsivePercentage) {
boardNode.style.width = boardWidth + '%';
} else {
boardNode.style.width = boardWidth;
}
boardNode.style.marginLeft = self.options.gutter;
boardNode.style.marginRight = self.options.gutter;
// header board
@ -303,6 +334,10 @@
headerBoard.classList.add(value);
});
if (board.color !== '' && board.color !== undefined) {
headerBoard._jscLinkedInstance = undefined;
jscolorL = new jscolor(headerBoard,{valueElement:undefined});
jscolorL.fromString(board.color);
headerBoard._jscLinkedInstance = undefined;
headerBoard.classList.add("kanban-header-" + board.color);
}
titleBoard = document.createElement('div');
@ -311,7 +346,7 @@
titleBoard.clickfn = board.boardTitleClick;
__onboardTitleClickHandler(titleBoard);
headerBoard.appendChild(titleBoard);
__onColorClickHandler(headerBoard);
__onColorClickHandler(headerBoard, "board");
// if add button is true, add button to the board
if (addButton) {
@ -332,14 +367,24 @@
var nodeItem = document.createElement('div');
nodeItem.classList.add('kanban-item');
nodeItem.dataset.eid = itemKanban.id;
nodeItem.innerHTML = itemKanban.title;
var nodeItemText = document.createElement('div');
nodeItemText.classList.add('kanban-item-text');
nodeItemText.dataset.eid = itemKanban.id;
nodeItemText.innerHTML = itemKanban.title;
nodeItem.appendChild(nodeItemText);
//add function
nodeItem.clickfn = itemKanban.click;
nodeItem.dragfn = itemKanban.drag;
nodeItem.dragendfn = itemKanban.dragend;
nodeItem.dropfn = itemKanban.drop;
nodeItemText.clickfn = itemKanban.click;
nodeItemText.dragfn = itemKanban.drag;
nodeItemText.dragendfn = itemKanban.dragend;
nodeItemText.dropfn = itemKanban.drop;
//add click handler of item
__onclickHandler(nodeItem);
__onclickHandler(nodeItemText);
if (itemKanban.color !== '' && itemKanban.color !== undefined) {
jscolorL = new jscolor(nodeItem,{valueElement:undefined});
jscolorL.fromString(itemKanban.color);
}
__onColorClickHandler(nodeItem, "item");
contentBoard.appendChild(nodeItem);
}
//footer board
@ -487,12 +532,10 @@
});
}
function __onColorClickHandler(nodeItem, clickfn) {
function __onColorClickHandler(nodeItem, type) {
nodeItem.addEventListener('click', function (e) {
e.preventDefault;
self.options.colorClick(this);
if (typeof (this.clickfn) === 'function')
this.clickfn(this);
self.options.colorClick(this, type);
});
}

1855
www/kanban/jscolor.js Normal file

File diff suppressed because it is too large Load Diff