Merge branch 'staging' into dark

pull/1/head
yflory 4 years ago
commit 42dfa9a941

@ -1179,7 +1179,18 @@ define([
// getPinnedUsage updates common.account.usage, and other values // getPinnedUsage updates common.account.usage, and other values
// so we can just use those and only check for errors // so we can just use those and only check for errors
var $container = $('<span>', {'class':'cp-limit-container'}); var $container = $('<span>', {'class':'cp-limit-container'});
var to;
var todo = function (err, data) { var todo = function (err, data) {
if (to) {
clearTimeout(to);
to = undefined;
}
if (err === 'RPC_NOT_READY') {
to = setTimeout(function () {
common.getPinUsage(teamId, todo);
}, 1000);
return;
}
if (err || !data) { return void console.error(err || 'No data'); } if (err || !data) { return void console.error(err || 'No data'); }
var usage = data.usage; var usage = data.usage;
@ -1849,6 +1860,13 @@ define([
var oldUrl = ''; var oldUrl = '';
var updateButton = function () { var updateButton = function () {
var myData = metadataMgr.getUserData(); var myData = metadataMgr.getUserData();
var privateData = metadataMgr.getPrivateData();
if (!priv.plan && privateData.plan) {
config.$initBlock.empty();
metadataMgr.off('change', updateButton);
UIElements.createUserAdminMenu(Common, config);
return;
}
if (!myData) { return; } if (!myData) { return; }
if (loadingAvatar) { if (loadingAvatar) {
// Try again in 200ms // Try again in 200ms
@ -2087,6 +2105,16 @@ define([
var sframeChan = common.getSframeChannel(); var sframeChan = common.getSframeChannel();
var metadataMgr = common.getMetadataMgr(); var metadataMgr = common.getMetadataMgr();
var privateData = metadataMgr.getPrivateData(); var privateData = metadataMgr.getPrivateData();
if (privateData.offline) {
metadataMgr.onChange(function () {
var privateData = metadataMgr.getPrivateData();
if (privateData.offline) { return; }
UIElements.getPadCreationScreen(common, cfg, appCfg, cb);
});
return;
}
var type = metadataMgr.getMetadataLazy().type || privateData.app; var type = metadataMgr.getMetadataLazy().type || privateData.app;
var fromFileData = privateData.fromFileData; var fromFileData = privateData.fromFileData;

@ -3259,6 +3259,7 @@ define([
var $spinnerContainer = $(h('div.cp-app-drive-search-spinner')); var $spinnerContainer = $(h('div.cp-app-drive-search-spinner'));
var spinner = UI.makeSpinner($spinnerContainer); var spinner = UI.makeSpinner($spinnerContainer);
var searching = true;
var $input = APP.Search.$input = $('<input>', { var $input = APP.Search.$input = $('<input>', {
id: 'cp-app-drive-search-input', id: 'cp-app-drive-search-input',
placeholder: Messages.fm_searchName, placeholder: Messages.fm_searchName,
@ -3266,21 +3267,19 @@ define([
draggable: false, draggable: false,
tabindex: 1, tabindex: 1,
}).keyup(function (e) { }).keyup(function (e) {
var lastValue = search.value; if (searching) {
search.value = $input.val().trim(); e.preventDefault();
if (lastValue === search.value) { return; } e.stopPropagation();
if (search.to) { window.clearTimeout(search.to); }
if (search.value === "") {
search.cursor = 0;
APP.displayDirectory([SEARCH]);
return; return;
} }
spinner.spin(); var currentValue = $input.val().trim();
if (search.to) { window.clearTimeout(search.to); }
if (e.which === 13) { if (e.which === 13) {
spinner.spin();
var newLocation = [SEARCH, $input.val()]; var newLocation = [SEARCH, $input.val()];
search.cursor = $input[0].selectionStart; search.cursor = $input[0].selectionStart;
if (!manager.comparePath(newLocation, currentPath.slice())) { if (!manager.comparePath(newLocation, currentPath.slice())) {
searching = true;
APP.displayDirectory(newLocation); APP.displayDirectory(newLocation);
} }
return; return;
@ -3288,27 +3287,30 @@ define([
if (e.which === 27) { if (e.which === 27) {
$input.val(''); $input.val('');
search.cursor = 0; search.cursor = 0;
searching = true;
APP.displayDirectory([SEARCH]); APP.displayDirectory([SEARCH]);
return; return;
} }
if ($input.val()) {
if (!$input.hasClass('cp-app-drive-search-active')) { if (currentValue === "") {
$input.addClass('cp-app-drive-search-active'); search.cursor = 0;
} APP.displayDirectory([SEARCH]);
} else { return;
$input.removeClass('cp-app-drive-search-active');
} }
if (currentValue.length < 2) { return; } // Don't autosearch 1 character
search.to = window.setTimeout(function () { search.to = window.setTimeout(function () {
var newLocation = [SEARCH, $input.val()]; var newLocation = [SEARCH, $input.val()];
search.cursor = $input[0].selectionStart; search.cursor = $input[0].selectionStart;
if (currentValue === search.value) { return; }
if (!manager.comparePath(newLocation, currentPath.slice())) { if (!manager.comparePath(newLocation, currentPath.slice())) {
searching = true;
APP.displayDirectory(newLocation); APP.displayDirectory(newLocation);
} }
}, 500); }, 500);
}).on('click mousedown mouseup', function (e) { }).on('click mousedown mouseup', function (e) {
e.stopPropagation(); e.stopPropagation();
}).val(value || '').appendTo($div); }).val(value || '').appendTo($div);
if (value) { $input.addClass('cp-app-drive-search-active'); }
$input[0].selectionStart = search.cursor || 0; $input[0].selectionStart = search.cursor || 0;
$input[0].selectionEnd = search.cursor || 0; $input[0].selectionEnd = search.cursor || 0;
@ -3329,6 +3331,7 @@ define([
if (typeof(value) === "string" && value.trim()) { if (typeof(value) === "string" && value.trim()) {
spinner.spin(); spinner.spin();
} else { } else {
searching = false;
return; return;
} }
@ -3338,6 +3341,7 @@ define([
if (!filesList.length) { if (!filesList.length) {
$list.append(h('div.cp-app-drive-search-noresult', Messages.fm_noResult)); $list.append(h('div.cp-app-drive-search-noresult', Messages.fm_noResult));
spinner.hide(); spinner.hide();
searching = false;
return; return;
} }
var sortable = {}; var sortable = {};
@ -3402,6 +3406,7 @@ define([
}); });
setTimeout(collapseDrivePath); setTimeout(collapseDrivePath);
spinner.hide(); spinner.hide();
searching = false;
}); });
}; };

@ -992,8 +992,10 @@ define([
// Also stop for shared folders // Also stop for shared folders
if (parsed.hashData.type !== 'pad' || parsed.type === 'drive') { return h('div', content); } if (parsed.hashData.type !== 'pad' || parsed.type === 'drive') { return h('div', content); }
var owned = Modal.isOwned(Env, data);
// Request edit access // Request edit access
if (common.isLoggedIn() && ((data.roHref && !data.href) || data.fakeHref)) { if (common.isLoggedIn() && ((data.roHref && !data.href) || data.fakeHref) && !owned) {
var requestButton = h('button.btn.btn-secondary.no-margin.cp-access-margin-right', var requestButton = h('button.btn.btn-secondary.no-margin.cp-access-margin-right',
Messages.requestEdit_button); Messages.requestEdit_button);
var requestBlock = h('p', requestButton); var requestBlock = h('p', requestButton);
@ -1028,7 +1030,6 @@ define([
// Mute access requests // Mute access requests
var edPublic = priv.edPublic; var edPublic = priv.edPublic;
var owned = Modal.isOwned(Env, data);
var canMute = data.mailbox && owned === true && ( var canMute = data.mailbox && owned === true && (
(typeof (data.mailbox) === "string" && data.owners[0] === edPublic) || (typeof (data.mailbox) === "string" && data.owners[0] === edPublic) ||
data.mailbox[edPublic]); data.mailbox[edPublic]);

@ -1229,6 +1229,7 @@ define([
var data = obj.data; var data = obj.data;
if (channels.indexOf(data.channel) !== -1) { return; } if (channels.indexOf(data.channel) !== -1) { return; }
var id = obj.id; var id = obj.id;
if (data.channel) { channels.push(data.channel); }
var parsed = Hash.parsePadUrl(data.href || data.roHref); var parsed = Hash.parsePadUrl(data.href || data.roHref);
if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1) && if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1) &&
!isFiltered(parsed.type, data)) { !isFiltered(parsed.type, data)) {

@ -141,6 +141,9 @@
border: 0; border: 0;
background: transparent; background: transparent;
align-self: flex-start; align-self: flex-start;
@media (hover: none) {
margin-right: 20px;
}
} }
.cp-kanban-cursors { .cp-kanban-cursors {
@ -166,7 +169,10 @@
flex-wrap: wrap; flex-wrap: wrap;
touch-action: none; touch-action: none;
background: @cp_kanban-item-bg; background: @cp_kanban-item-bg;
.tools_unselectable();
touch-action: none;
cursor: move; cursor: move;
cursor: grab;
margin-bottom: 10px; margin-bottom: 10px;
&:last-child { &:last-child {
@ -259,12 +265,14 @@
.kanban-board { .kanban-board {
position: relative; position: relative;
transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1); transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
margin: 10px;
vertical-align: top; vertical-align: top;
display: flex; display: flex;
flex-flow: column; flex-flow: column;
width: 300px; width: 300px;
margin: 10px 5px; margin: 10px 5px;
@media (hover: none) {
margin-bottom: 30px;
}
&.is-moving.gu-mirror { &.is-moving.gu-mirror {
transform: rotate(3deg); transform: rotate(3deg);
@ -282,12 +290,17 @@
overflow-y: auto; overflow-y: auto;
justify-content: space-around; justify-content: space-around;
min-height: 38px; // Size of one card min-height: 38px; // Size of one card
@media (hover: none) {
padding-right: 30px;
}
} }
header { header {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
padding: 5px 10px; padding: 5px 10px;
cursor: move;
cursor: grab;
.kanban-title-board { .kanban-title-board {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
@ -305,9 +318,6 @@
#kanban-edit { #kanban-edit {
font-weight: bold; font-weight: bold;
} }
&:hover {
cursor: move;
}
} }
footer { footer {
margin: 10px; margin: 10px;

@ -134,6 +134,24 @@ define([
}; };
var addEditItemButton = function () {}; var addEditItemButton = function () {};
var now = function () { return +new Date(); };
var _lastUpdate = 0;
var _updateBoards = function (framework, kanban, boards) {
_lastUpdate = now();
kanban.setBoards(Util.clone(boards));
kanban.inEditMode = false;
addEditItemButton(framework, kanban);
};
var _updateBoardsThrottle = Util.throttle(_updateBoards, 1000);
var updateBoards = function (framework, kanban, boards) {
if ((now() - _lastUpdate) > 5000 || framework.isLocked()) {
_updateBoards(framework, kanban, boards);
return;
}
_updateBoardsThrottle(framework, kanban, boards);
};
var onRemoteChange = Util.mkEvent(); var onRemoteChange = Util.mkEvent();
var editModal; var editModal;
var PROPERTIES = ['title', 'body', 'tags', 'color']; var PROPERTIES = ['title', 'body', 'tags', 'color'];
@ -146,10 +164,9 @@ define([
var isBoard, id; var isBoard, id;
var offline = false; var offline = false;
var update = Util.throttle(function () { var update = function () {
kanban.setBoards(kanban.options.boards); updateBoards(framework, kanban, kanban.options.boards);
addEditItemButton(framework, kanban); };
}, 400);
var commit = function () { var commit = function () {
framework.localChange(); framework.localChange();
@ -400,7 +417,9 @@ define([
framework.onEditableChange(function (unlocked) { framework.onEditableChange(function (unlocked) {
editor.setOption('readOnly', !unlocked); editor.setOption('readOnly', !unlocked);
$title.prop('disabled', unlocked ? '' : 'disabled'); $title.prop('disabled', unlocked ? '' : 'disabled');
$(_field.element).tokenfield(unlocked ? 'enable' : 'disable'); if (_field) {
$(_field.element).tokenfield(unlocked ? 'enable' : 'disable');
}
$modal.find('nav button.danger').prop('disabled', unlocked ? '' : 'disabled'); $modal.find('nav button.danger').prop('disabled', unlocked ? '' : 'disabled');
offline = !unlocked; offline = !unlocked;
@ -831,7 +850,8 @@ define([
openLink: openLink, openLink: openLink,
getTags: getExistingTags, getTags: getExistingTags,
cursors: remoteCursors, cursors: remoteCursors,
boards: boards boards: boards,
_boards: Util.clone(boards),
}); });
framework._.cpNfInner.metadataMgr.onChange(function () { framework._.cpNfInner.metadataMgr.onChange(function () {
@ -842,7 +862,7 @@ define([
// If the rendering has changed, update the value and redraw // If the rendering has changed, update the value and redraw
kanban.options.tagsAnd = tagsAnd; kanban.options.tagsAnd = tagsAnd;
_tagsAnd = tagsAnd; _tagsAnd = tagsAnd;
kanban.setBoards(kanban.options.boards); updateBoards(framework, kanban, kanban.options.boards);
}); });
if (migrated) { framework.localChange(); } if (migrated) { framework.localChange(); }
@ -1167,9 +1187,8 @@ define([
if (Sortify(currentContent) !== Sortify(remoteContent)) { if (Sortify(currentContent) !== Sortify(remoteContent)) {
var cursor = getCursor(); var cursor = getCursor();
verbose("Content is different.. Applying content"); verbose("Content is different.. Applying content");
kanban.setBoards(remoteContent); kanban.options.boards = remoteContent;
kanban.inEditMode = false; updateBoards(framework, kanban, remoteContent);
addEditItemButton(framework, kanban);
restoreCursor(cursor); restoreCursor(cursor);
onRemoteChange.fire(); onRemoteChange.fire();
} }
@ -1191,8 +1210,17 @@ define([
var items = boards.items || {}; var items = boards.items || {};
var data = boards.data || {}; var data = boards.data || {};
var list = boards.list || []; var list = boards.list || [];
// Remove duplicate boards
list = boards.list = Util.deduplicateString(list);
Object.keys(data).forEach(function (id) { Object.keys(data).forEach(function (id) {
if (list.indexOf(Number(id)) === -1) { delete data[id]; } if (list.indexOf(Number(id)) === -1) {
list.push(Number(id));
}
// Remove duplicate items
var b = data[id];
b.item = Util.deduplicateString(b.item || []);
}); });
Object.keys(items).forEach(function (eid) { Object.keys(items).forEach(function (eid) {
var exists = Object.keys(data).some(function (id) { var exists = Object.keys(data).some(function (id) {

@ -26,13 +26,14 @@ define([
element: '', element: '',
gutter: '15px', gutter: '15px',
widthBoard: '250px', widthBoard: '250px',
responsive: '700', responsive: 0, //'700',
responsivePercentage: false, responsivePercentage: false,
boards: { boards: {
data: {}, data: {},
items: {}, items: {},
list: [] list: []
}, }, // The realtime kanban
_boards: {}, // The displayed kanban. We need to remember the old columns when we redraw
getAvatar: function () {}, getAvatar: function () {},
openLink: function () {}, openLink: function () {},
getTags: function () {}, getTags: function () {},
@ -298,7 +299,9 @@ define([
// Move to trash? // Move to trash?
if (target.classList.contains('kanban-trash')) { if (target.classList.contains('kanban-trash')) {
list.splice(index1, 1); list.splice(index1, 1);
delete self.options.boards.data[id]; if (list.indexOf(id) === -1) {
delete self.options.boards.data[id];
}
self.onChange(); self.onChange();
return; return;
} }
@ -393,10 +396,11 @@ define([
console.log("In drop"); console.log("In drop");
var id1 = Number($(el).attr('data-eid')); var id1 = Number($(el).attr('data-eid'));
var boardId = Number($(source).closest('.kanban-board').data('id'));
// Move to trash? // Move to trash?
if (target.classList.contains('kanban-trash')) { if (target.classList.contains('kanban-trash')) {
self.moveItem(id1); self.moveItem(boardId, id1);
self.onChange(); self.onChange();
return; return;
} }
@ -416,7 +420,7 @@ define([
} }
// Move the item // Move the item
self.moveItem(id1, board2, pos2); self.moveItem(boardId, id1, board2, pos2);
// send event that board has changed // send event that board has changed
self.onChange(); self.onChange();
@ -443,21 +447,44 @@ define([
}); });
return res; return res;
}; };
this.moveItem = function (eid, board, pos) { this.checkItem = function (eid) {
var boards = self.options.boards; var boards = self.options.boards;
var same = -1; var data = boards.data || {};
var from = findItem(eid); var exists = Object.keys(data).some(function (id) {
// Remove the item from its board return (data[id].item || []).indexOf(Number(eid)) !== -1;
from.forEach(function (obj) {
obj.board.item.splice(obj.pos, 1);
if (obj.board === board) { same = obj.pos; }
}); });
// If it's a deletion, remove the item data return exists;
};
this.moveItem = function (source, eid, board, pos) {
var boards = self.options.boards;
var same = -1;
console.error(source, eid, board, pos);
if (source && boards.data[source]) {
// Remove from this board only
var l = boards.data[source].item;
var idx = l.indexOf(eid);
if (idx !== -1) { l.splice(idx, 1); }
if (source === board) { same = idx; }
} else {
// Remove the item from all its board
var from = findItem(eid);
from.forEach(function (obj) {
obj.board.item.splice(obj.pos, 1);
if (obj.board === board) { same = obj.pos; }
});
}
// If it's a deletion and not a duplicate, remove the item data
if (!board) { if (!board) {
delete boards.items[eid]; if (!self.checkItem(eid)) {
delete self.cache[eid]; delete boards.items[eid];
removeUnusedTags(boards); delete self.cache[eid];
self.options.refresh(); removeUnusedTags(boards);
self.options.refresh();
}
return;
}
// If the item already exists in the target board, abort (duplicate)
if (board.item.indexOf(eid) !== -1) {
return; return;
} }
// If it's moved to the same board at a bigger index, decrement the index by one // If it's moved to the same board at a bigger index, decrement the index by one
@ -707,21 +734,29 @@ define([
}; };
this.addBoard = function (board) { this.addBoard = function (board) {
if (!board || !board.id) { return; } if (!board || !board.id) { return; }
// We need to store all the columns in _boards too because it's used to
// remember what columns were already displayed when we redraw (in order to
// preserve their scroll value)
var boards = self.options.boards; var boards = self.options.boards;
boards.data = boards.data || {}; boards.data = boards.data || {};
boards.list = boards.list || []; boards.list = boards.list || [];
var _boards = self.options._boards;
_boards.data = _boards.data || {};
_boards.list = _boards.list || [];
// If it already there, abort // If it already there, abort
boards.data[board.id] = board; boards.data[board.id] = board;
_boards.data[board.id] = board;
if (boards.list.indexOf(board.id) !== -1) { return; } if (boards.list.indexOf(board.id) !== -1) { return; }
boards.list.push(board.id); boards.list.push(board.id);
_boards.list.push(board.id);
var boardNode = getBoardNode(board); var boardNode = getBoardNode(board);
self.container.appendChild(boardNode); self.container.appendChild(boardNode);
}; };
this.addBoards = function() { this.addBoards = function() {
//for on all the boards //for on all the boards
var boards = self.options.boards; var boards = self.options._boards;
boards.list = boards.list || []; boards.list = boards.list || [];
boards.data = boards.data || {}; boards.data = boards.data || {};
var toRemove = []; var toRemove = [];
@ -759,10 +794,10 @@ define([
var $el = $(self.element); var $el = $(self.element);
var scrollLeft = $el.scrollLeft(); var scrollLeft = $el.scrollLeft();
// Get existing boards list // Get existing boards list
var list = Util.clone(this.options.boards.list); var list = Util.clone(this.options._boards.list);
// Update memory // Update memory
this.options.boards = boards; this.options._boards = Util.clone(boards);
// If the tab is not focused but a handler already exists: abort // If the tab is not focused but a handler already exists: abort
if (!Visible.currently() && onVisibleHandler) { return; } if (!Visible.currently() && onVisibleHandler) { return; }
@ -779,7 +814,7 @@ define([
self.addBoards(); self.addBoards();
self.options.refresh(); self.options.refresh();
// Preserve scroll // Preserve scroll
self.options.boards.list.forEach(function (id) { self.options._boards.list.forEach(function (id) {
if (!scroll[id]) { return; } if (!scroll[id]) { return; }
$('.kanban-board[data-id="'+id+'"] .kanban-drag').scrollTop(scroll[id]); $('.kanban-board[data-id="'+id+'"] .kanban-drag').scrollTop(scroll[id]);
}); });

@ -0,0 +1 @@
fabric.Canvas.prototype.initialize=function(t){return function(...i){return t.call(this,...i),this._historyInit(),this}}(fabric.Canvas.prototype.initialize),fabric.Canvas.prototype.dispose=function(t){return function(...i){return t.call(this,...i),this._historyDispose(),this}}(fabric.Canvas.prototype.dispose),fabric.Canvas.prototype._historyNext=function(){return JSON.stringify(this.toDatalessJSON(this.extraProps))},fabric.Canvas.prototype._historyEvents=function(){return{"object:added":this._historySaveAction,"object:removed":this._historySaveAction,"object:modified":this._historySaveAction,"object:skewing":this._historySaveAction}},fabric.Canvas.prototype._historyInit=function(){this.historyUndo=[],this.historyRedo=[],this.extraProps=["selectable"],this.historyNextState=this._historyNext(),this.on(this._historyEvents())},fabric.Canvas.prototype._historyDispose=function(){this.off(this._historyEvents())},fabric.Canvas.prototype._historySaveAction=function(){if(this.historyProcessing)return;const t=this.historyNextState;this.historyUndo.push(t),this.historyNextState=this._historyNext(),this.fire("history:append",{json:t})},fabric.Canvas.prototype.undo=function(t){this.historyProcessing=!0;const i=this.historyUndo.pop();i?(this.historyRedo.push(this._historyNext()),this.historyNextState=i,this._loadHistory(i,"history:undo",t)):this.historyProcessing=!1},fabric.Canvas.prototype.redo=function(t){this.historyProcessing=!0;const i=this.historyRedo.pop();i?(this.historyUndo.push(this._historyNext()),this.historyNextState=i,this._loadHistory(i,"history:redo",t)):this.historyProcessing=!1},fabric.Canvas.prototype._loadHistory=function(t,i,s){var o=this;this.loadFromJSON(t,function(){o.renderAll(),o.fire(i),o.historyProcessing=!1,s&&"function"==typeof s&&s()})},fabric.Canvas.prototype.clearHistory=function(){this.historyUndo=[],this.historyRedo=[],this.fire("history:clear")},fabric.Canvas.prototype.offHistory=function(){this.historyProcessing=!0},fabric.Canvas.prototype.onHistory=function(){this.historyProcessing=!1,this._historySaveAction()};

@ -88,7 +88,7 @@
#cp-app-whiteboard-delete { #cp-app-whiteboard-delete {
min-width: 40px; min-width: 40px;
} }
.cp-whiteboard-type { .cp-whiteboard-type, .cp-whiteboard-history {
button { button {
min-width: 40px; min-width: 40px;
text-align: center; text-align: center;

@ -53,12 +53,15 @@ define([
var $type = $('.cp-whiteboard-type'); var $type = $('.cp-whiteboard-type');
var $brush = $('.cp-whiteboard-type .brush'); var $brush = $('.cp-whiteboard-type .brush');
var $move = $('.cp-whiteboard-type .move'); var $move = $('.cp-whiteboard-type .move');
var $undo = $('.cp-whiteboard-history .undo');
var $redo = $('.cp-whiteboard-history .redo');
var $text = $('.cp-whiteboard-text button');
var $deleteButton = $('#cp-app-whiteboard-delete'); var $deleteButton = $('#cp-app-whiteboard-delete');
var metadataMgr = framework._.cpNfInner.metadataMgr; var metadataMgr = framework._.cpNfInner.metadataMgr;
var brush = { var brush = {
color: '#000000', color: window.CryptPad_theme === "dark" ? '#FFFFFF' : '#000000',
opacity: 1 opacity: 1
}; };
@ -137,6 +140,35 @@ define([
$deleteButton.prop('disabled', ''); $deleteButton.prop('disabled', '');
}); });
$text.click(function () {
$move.click();
canvas.add(new Fabric.Textbox('My Text', {
fill: brush.color,
top: 5,
left: 5
}));
});
$undo.click(function () {
if (typeof(APP.canvas.undo) !== "function") { return; }
APP.canvas.undo();
APP.onLocal();
});
$redo.click(function () {
if (typeof(APP.canvas.undo) !== "function") { return; }
APP.canvas.redo();
APP.onLocal();
});
$('body').on('keydown', function (e) {
if (e.which === 90 && e.ctrlKey) {
$undo.click();
return;
}
if (e.which === 89 && e.ctrlKey) {
$redo.click();
return;
}
});
var deleteSelection = function () { var deleteSelection = function () {
if (APP.draw) { return; } if (APP.draw) { return; }
if (canvas.getActiveObject()) { if (canvas.getActiveObject()) {
@ -175,6 +207,16 @@ define([
c = Colors.rgb2hex(c); c = Colors.rgb2hex(c);
brush.color = c; brush.color = c;
canvas.freeDrawingBrush.color = Colors.hex2rgba(brush.color, brush.opacity); canvas.freeDrawingBrush.color = Colors.hex2rgba(brush.color, brush.opacity);
if (!APP.draw) {
var active = canvas.getActiveObject();
if (active) {
var col = Colors.hex2rgba(brush.color, brush.opacity);
if (active.text) { active.set('fill', col); }
else { active.set('stroke', col); }
canvas.renderAll();
APP.onLocal();
}
}
createCursor(); createCursor();
}; };
@ -436,7 +478,15 @@ define([
}; };
}); });
var cleanHistory = function () {
if (Array.isArray(canvas.historyUndo)) {
canvas.historyUndo = canvas.historyUndo.slice(-100);
canvas.historyRedo = canvas.historyRedo.slice(-100);
}
};
framework.onContentUpdate(function (newContent, waitFor) { framework.onContentUpdate(function (newContent, waitFor) {
cleanHistory();
var content = newContent.content; var content = newContent.content;
canvas.loadFromJSON(content, waitFor(function () { canvas.loadFromJSON(content, waitFor(function () {
canvas.renderAll(); canvas.renderAll();
@ -445,6 +495,7 @@ define([
}); });
framework.setContentGetter(function () { framework.setContentGetter(function () {
cleanHistory();
var content = canvas.toDatalessJSON(); var content = canvas.toDatalessJSON();
return { return {
content: content content: content
@ -475,6 +526,8 @@ define([
}; };
Messages.undo = "Undo"; // XXX
Messages.redo = "Redo"; // XXX
var initialContent = function () { var initialContent = function () {
return [ return [
h('div#cp-toolbar.cp-toolbar-container'), h('div#cp-toolbar.cp-toolbar-container'),
@ -494,6 +547,13 @@ define([
h('button.btn.brush.fa.fa-paint-brush.btn-primary', {title: Messages.canvas_brush}), h('button.btn.brush.fa.fa-paint-brush.btn-primary', {title: Messages.canvas_brush}),
h('button.btn.move.fa.fa-arrows', {title: Messages.canvas_select}), h('button.btn.move.fa.fa-arrows', {title: Messages.canvas_select}),
]), ]),
h('div.cp-whiteboard-history', [
h('button.btn.undo.fa.fa-undo', {title: Messages.undo}),
h('button.btn.redo.fa.fa-repeat', {title: Messages.redo}),
]),
h('div.cp-whiteboard-text', [
h('button.btn.fa.fa-font')
]),
h('button.btn.fa.fa-trash#cp-app-whiteboard-delete', { h('button.btn.fa.fa-trash#cp-app-whiteboard-delete', {
disabled: 'disabled', disabled: 'disabled',
title: Messages.canvas_delete title: Messages.canvas_delete
@ -560,6 +620,7 @@ define([
$('body').append($div.html()); $('body').append($div.html());
})); }));
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
require(['/lib/fabric-history.min.js'], waitFor());
// Framework initialization // Framework initialization
Framework.create({ Framework.create({

Loading…
Cancel
Save