', {
'class': 'cp-app-whiteboard-palette-color',
})
@@ -271,7 +191,7 @@ define([
})
.on('dblclick', function (e) {
e.preventDefault();
- if (!APP.editable) { return; }
+ if (framework.isLocked()) { return; }
pickColor(Colors.rgb2hex($color.css('background-color')), function (c) {
$color.css({
'background-color': c,
@@ -287,7 +207,7 @@ define([
var first = true;
var updatePalette = function (newPalette) {
- if (first || stringify(palette) !== stringify(newPalette)) {
+ if (first || Sortify(palette) !== Sortify(newPalette)) {
palette = newPalette;
$colors.html('
');
palette.forEach(addColorToPalette);
@@ -299,7 +219,7 @@ define([
var metadata = JSON.parse(JSON.stringify(metadataMgr.getMetadata()));
metadata.palette = newPalette;
metadataMgr.updateMetadata(metadata);
- config.onLocal();
+ framework.localChange();
};
var makeColorButton = function ($container) {
@@ -312,7 +232,7 @@ define([
return;
}
- var $color = APP.$color = common.createButton(null, true, {
+ var $color = APP.$color = framework._.sfCommon.createButton(null, true, {
icon: 'fa-square',
title: Messages.canvas_chooseColor,
name: 'color',
@@ -331,33 +251,73 @@ define([
return $color;
};
- var stringifyInner = function (textValue) {
- var obj = {
- content: textValue,
- metadata: metadataMgr.getMetadataLazy()
- };
- // stringify the json and send it into chainpad
- return stringify(obj);
+ updateLocalPalette(palette);
+
+ metadataMgr.onChange(function () {
+ var md = metadataMgr.getMetadata();
+ if (md.palette) {
+ updateLocalPalette(md.palette);
+ }
+ });
+
+ return {
+ palette: palette,
+ makeColorButton: makeColorButton,
+ updateLocalPalette: updateLocalPalette,
};
+ };
+
+ var mkHelpMenu = function (framework) {
+ var $appContainer = $('#cp-app-whiteboard-container');
+ var helpMenu = framework._.sfCommon.createHelpMenu(['whiteboard']);
+ $appContainer.prepend(helpMenu.menu);
+ framework._.toolbar.$drawer.append(helpMenu.button);
+ };
+
+ // Start of the main loop
+ var andThen2 = function (framework) {
+ var canvas = APP.canvas = new Fabric.Canvas('cp-app-whiteboard-canvas', {
+ containerClass: 'cp-app-whiteboard-canvas-container'
+ });
+ var $canvas = $('canvas');
+ var $canvasContainer = $('canvas').parents('.cp-app-whiteboard-canvas-container');
+ var $controls = $('#cp-app-whiteboard-controls');
+ var metadataMgr = framework._.cpNfInner.metadataMgr;
- var onLocal = config.onLocal = function () {
- if (initializing) { return; }
- if (readOnly) { return; }
-
- var content = stringifyInner(canvas.toDatalessJSON());
-
- try {
- APP.realtime.contentUpdate(content);
- } catch (e) {
- APP.unrecoverable = true;
- setEditable(false);
- APP.toolbar.errorState(true, e.message);
- var msg = Messages.chainpadError;
- UI.errorLoadingScreen(msg, true, true);
- console.error(e);
+ var setEditable = function (bool) {
+ if (bool) { $controls.css('display', 'flex'); }
+ else { $controls.hide(); }
+
+ canvas.isDrawingMode = bool ? APP.draw : false;
+ if (!bool) {
+ canvas.deactivateAll();
+ canvas.renderAll();
}
+ canvas.forEachObject(function (object) {
+ object.selectable = bool;
+ });
+ $canvasContainer.find('canvas').css('border-color', bool? 'black': 'red');
};
+ mkHelpMenu(framework);
+
+ var controls = mkControls(framework, canvas);
+
+ // ---------------------------------------------
+ // Whiteboard custom buttons
+ // ---------------------------------------------
+
+ var $rightside = framework._.toolbar.$rightside;
+
+ APP.FM = framework._.sfCommon.createFileManager({});
+ APP.upload = function (title) {
+ var canvas = $canvas[0];
+ APP.canvas.deactivateAll().renderAll();
+ canvas.toBlob(function (blob) {
+ blob.name = title;
+ APP.FM.handleFile(blob);
+ });
+ };
var addImageToCanvas = function (img) {
var w = img.width;
var h = img.height;
@@ -370,313 +330,159 @@ define([
}
var cImg = new Fabric.Image(img, { left:0, top:0, angle:0, });
APP.canvas.add(cImg);
- onLocal();
+ framework.localChange();
};
- var initThumbnails = function () {
- var oldThumbnailState;
- var privateDat = metadataMgr.getPrivateData();
- if (!privateDat.thumbnails) { return; }
- var hash = privateDat.availableHashes.editHash ||
- privateDat.availableHashes.viewHash;
- var href = privateDat.pathname + '#' + hash;
- var mkThumbnail = function () {
- if (!hash) { return; }
- if (initializing) { return; }
- if (!APP.realtime) { return; }
- var content = APP.realtime.getUserDoc();
- if (content === oldThumbnailState) { return; }
- var D = Thumb.getResizedDimensions($canvas[0], 'pad');
- Thumb.fromCanvas($canvas[0], D, function (err, b64) {
- oldThumbnailState = content;
- Thumb.setPadThumbnail(common, href, privateDat.channel, b64);
- });
+ // Export to drive as PNG
+ framework._.sfCommon.createButton('savetodrive', true, {}).click(function () {
+ var defaultName = framework._.title.getTitle();
+ UI.prompt(Messages.exportPrompt, defaultName + '.png', function (name) {
+ if (name === null || !name.trim()) { return; }
+ APP.upload(name);
+ });
+ }).appendTo($rightside);
+
+ // Embed image
+ var onUpload = function (e) {
+ var file = e.target.files[0];
+ var reader = new FileReader();
+ reader.onload = function () {
+ var img = new Image();
+ img.onload = function () {
+ addImageToCanvas(img);
+ };
+ img.src = reader.result;
};
- window.setInterval(mkThumbnail, Thumb.UPDATE_INTERVAL);
- window.setTimeout(mkThumbnail, Thumb.UPDATE_FIRST);
+ reader.readAsDataURL(file);
};
-
- config.onInit = function (info) {
- updateLocalPalette(palette);
- readOnly = metadataMgr.getPrivateData().readOnly;
-
- Title = common.createTitle({});
-
- var configTb = {
- displayed: [
- 'userlist',
- 'title',
- 'useradmin',
- 'spinner',
- 'newpad',
- 'share',
- 'limit',
- 'unpinnedWarning'
- ],
- title: Title.getTitleConfig(),
- metadataMgr: metadataMgr,
- readOnly: readOnly,
- realtime: info.realtime,
- sfCommon: common,
- $container: $bar,
- $contentContainer: $('#cp-app-whiteboard-canvas-area')
+ framework._.sfCommon.createButton('', true, {
+ title: Messages.canvas_imageEmbed,
+ icon: 'fa-file-image-o',
+ name: 'embedImage'
+ }).click(function () {
+ $('', {type:'file'}).on('change', onUpload).click();
+ }).appendTo($rightside);
+
+ if (framework._.sfCommon.isLoggedIn()) {
+ var fileDialogCfg = {
+ onSelect: function (data) {
+ if (data.type === 'file') {
+ var mt = '';
+ framework._.sfCommon.displayMediatagImage($(mt), function (err, $image) {
+ Util.blobURLToImage($image.attr('src'), function (imgSrc) {
+ var img = new Image();
+ img.onload = function () { addImageToCanvas(img); };
+ img.src = imgSrc;
+ });
+ });
+ return;
+ }
+ }
};
- toolbar = APP.toolbar = Toolbar.create(configTb);
- Title.setToolbar(toolbar);
-
- var $rightside = toolbar.$rightside;
- var $drawer = toolbar.$drawer;
-
- /* save as template */
- if (!metadataMgr.getPrivateData().isTemplate) {
- var templateObj = {
- rt: info.realtime,
- getTitle: function () { return metadataMgr.getMetadata().title; }
+ framework._.sfCommon.initFilePicker(fileDialogCfg);
+ framework._.sfCommon.createButton('mediatag', true).click(function () {
+ var pickerCfg = {
+ types: ['file'],
+ where: ['root'],
+ filter: {
+ fileType: ['image/']
+ }
};
- var $templateButton = common.createButton('template', true, templateObj);
- $rightside.append($templateButton);
- }
-
- /* add an export button */
- var $export = common.createButton('export', true, {}, saveImage);
- $drawer.append($export);
-
- if (common.isLoggedIn()) {
- common.createButton('savetodrive', true, {}, function () {})
- .click(function () {
- UI.prompt(Messages.exportPrompt, document.title + '.png',
- function (name) {
- if (name === null || !name.trim()) { return; }
- APP.upload(name);
- });
- }).appendTo($rightside);
-
- common.createButton('hashtag', true).appendTo($rightside);
- }
-
- var $forget = common.createButton('forget', true, {}, function (err) {
- if (err) { return; }
- setEditable(false);
- });
- $rightside.append($forget);
-
- var $properties = common.createButton('properties', true);
- toolbar.$drawer.append($properties);
-
- var $appContainer = $('#cp-app-whiteboard-container');
- var helpMenu = common.createHelpMenu(['whiteboard']);
- $appContainer.prepend(helpMenu.menu);
- toolbar.$drawer.append(helpMenu.button);
-
- if (!readOnly) {
- makeColorButton($rightside);
-
- // Embed image
- var onUpload = function (e) {
- var file = e.target.files[0];
- var reader = new FileReader();
- reader.onload = function () {
- var img = new Image();
- img.onload = function () {
- addImageToCanvas(img);
- };
- img.src = reader.result;
- };
- reader.readAsDataURL(file);
- };
- common.createButton('', true, {
- title: Messages.canvas_imageEmbed,
- icon: 'fa-file-image-o',
- name: 'embedImage'
- }).click(function () {
- $('', {type:'file'}).on('change', onUpload).click();
- }).appendTo($rightside);
-
- if (common.isLoggedIn()) {
- var fileDialogCfg = {
- onSelect: function (data) {
- if (data.type === 'file') {
- var mt = '';
- common.displayMediatagImage($(mt), function (err, $image) {
- Util.blobURLToImage($image.attr('src'), function (imgSrc) {
- var img = new Image();
- img.onload = function () { addImageToCanvas(img); };
- img.src = imgSrc;
- });
- });
- return;
- }
- }
- };
- common.initFilePicker(fileDialogCfg);
- APP.$mediaTagButton = common.createButton('mediatag', true).click(function () {
- var pickerCfg = {
- types: ['file'],
- where: ['root'],
- filter: {
- fileType: ['image/']
- }
- };
- common.openFilePicker(pickerCfg);
- }).appendTo($rightside);
- }
- } else {
- $colors.hide();
- $controls.hide();
- }
-
- metadataMgr.onChange(function () {
- var md = metadataMgr.getMetadata();
- if (md.palette) {
- updateLocalPalette(md.palette);
- }
- });
- };
-
- config.onReady = function (info) {
- if (APP.realtime !== info.realtime) {
- APP.realtime = info.realtime;
- }
-
- var userDoc = APP.realtime.getUserDoc();
- var isNew = false;
- var newDoc = '';
- if (userDoc === "" || userDoc === "{}") { isNew = true; }
+ framework._.sfCommon.openFilePicker(pickerCfg);
+ }).appendTo($rightside);
+ }
- if (userDoc !== "") {
- var hjson = JSON.parse(userDoc);
-
- if (hjson && hjson.metadata) {
- metadataMgr.updateMetadata(hjson.metadata);
- }
- if (typeof (hjson) !== 'object' || Array.isArray(hjson) ||
- (hjson.metadata && typeof(hjson.metadata.type) !== 'undefined' &&
- hjson.metadata.type !== 'whiteboard')) {
- var errorText = Messages.typeError;
- UI.errorLoadingScreen(errorText);
- throw new Error(errorText);
- }
- newDoc = hjson.content;
- } else {
- Title.updateTitle(Title.defaultTitle);
- }
+ if (framework.isReadOnly()) {
+ setEditable(false);
+ } else {
+ controls.makeColorButton($rightside);
+ }
- nThen(function (waitFor) {
- if (newDoc) {
- canvas.loadFromJSON(newDoc, waitFor(function () {
- console.log('loaded');
- canvas.renderAll();
- }));
- }
- }).nThen(function () {
- setEditable(!readOnly);
- initializing = false;
- config.onLocal();
- UI.removeLoadingScreen();
+ $('#cp-app-whiteboard-clear').on('click', function () {
+ canvas.clear();
+ framework.localChange();
+ });
- initThumbnails();
+ // ---------------------------------------------
+ // End custom
+ // ---------------------------------------------
- if (readOnly) { return; }
+ framework.onEditableChange(function () {
+ var locked = framework.isLocked() || framework.isReadOnly();
+ setEditable(!locked);
+ });
- var privateDat = metadataMgr.getPrivateData();
- var skipTemp = Util.find(privateDat,
- ['settings', 'general', 'creation', 'noTemplate']);
- var skipCreation = Util.find(privateDat, ['settings', 'general', 'creation', 'skip']);
- if (isNew && (!AppConfig.displayCreationScreen || (!skipTemp && skipCreation))) {
- common.openTemplatePicker();
- }
+ framework.setFileExporter('png', function (cb) {
+ $canvas[0].toBlob(function (blob) {
+ cb(blob);
});
+ });
- };
-
- config.onRemote = function () {
- if (initializing) { return; }
- var userDoc = APP.realtime.getUserDoc();
-
- var json = JSON.parse(userDoc);
- var remoteDoc = json.content;
+ framework.setNormalizer(function (c) {
+ return {
+ content: c.content
+ };
+ });
- canvas.loadFromJSON(remoteDoc, function () {
+ framework.onContentUpdate(function (newContent, waitFor) {
+ var content = newContent.content;
+ canvas.loadFromJSON(content, waitFor(function () {
canvas.renderAll();
- if (json.metadata) {
- metadataMgr.updateMetadata(json.metadata);
- }
- });
-
- var content = canvas.toDatalessJSON();
- if (content !== remoteDoc) { common.notify(); }
- if (readOnly) { setEditable(false); }
- };
-
- config.onAbort = function () {
- if (APP.unrecoverable) { return; }
- // inform of network disconnect
- setEditable(false);
- toolbar.failed();
- UI.alert(Messages.common_connectionLost, undefined, true);
- };
-
- config.onConnectionChange = function (info) {
- if (APP.unrecoverable) { return; }
- setEditable(info.state);
- if (info.state) {
- initializing = true;
- //UI.findOKButton().click();
- } else {
- //UI.alert(Messages.common_connectionLost, undefined, true);
- }
- };
-
- config.onError = function (err) {
- common.onServerError(err, toolbar, function () {
- APP.unrecoverable = true;
- setEditable(false);
- });
- };
-
- cpNfInner = common.startRealtime(config);
- metadataMgr = cpNfInner.metadataMgr;
-
- cpNfInner.onInfiniteSpinner(function () {
- if (APP.unrecoverable) { return; }
- setEditable(false);
- UI.confirm(Messages.realtime_unrecoverableError, function (yes) {
- if (!yes) { return; }
- common.gotoURL();
- });
+ }));
});
- canvas.on('mouse:up', onLocal);
-
- $('#cp-app-whiteboard-clear').on('click', function () {
- canvas.clear();
- onLocal();
+ framework.setContentGetter(function () {
+ var content = canvas.toDatalessJSON();
+ return {
+ content: content
+ };
});
- $('#save').on('click', function () {
- saveImage();
+ framework.onReady(function () {
+ var oldThumbnailState;
+ var privateDat = metadataMgr.getPrivateData();
+ if (!privateDat.thumbnails) { return; }
+ var hash = privateDat.availableHashes.editHash ||
+ privateDat.availableHashes.viewHash;
+ var href = privateDat.pathname + '#' + hash;
+ var mkThumbnail = function () {
+ if (!hash) { return; }
+ if (framework.getState() !== 'READY') { return; }
+ if (!framework._.cpNfInner.chainpad) { return; }
+ var content = framework._.cpNfInner.chainpad.getUserDoc();
+ if (content === oldThumbnailState) { return; }
+ var D = Thumb.getResizedDimensions($canvas[0], 'pad');
+ Thumb.fromCanvas($canvas[0], D, function (err, b64) {
+ oldThumbnailState = content;
+ Thumb.setPadThumbnail(framework._.sfCommon, href, privateDat.channel, b64);
+ });
+ };
+ window.setInterval(mkThumbnail, Thumb.UPDATE_INTERVAL);
+ window.setTimeout(mkThumbnail, Thumb.UPDATE_FIRST);
});
- common.onLogout(function () { setEditable(false); });
+ canvas.on('mouse:up', framework.localChange);
+ framework.start();
};
var main = function () {
- var common;
-
+ // var framework;
nThen(function (waitFor) {
$(waitFor(function () {
- UI.addLoadingScreen();
var $div = $('').append(Pages['/whiteboard/']());
$('body').append($div.html());
}));
- SFCommon.create(waitFor(function (c) { APP.common = common = c; }));
}).nThen(function (waitFor) {
- common.getSframeChannel().onReady(waitFor());
- }).nThen(function (waitFor) {
- common.handleNewFile(waitFor);
- }).nThen(function (/*waitFor*/) {
- andThen(common);
+
+ // Framework initialization
+ Framework.create({
+ patchTransformer: ChainPad.NaiveJSONTransformer,
+ toolbarContainer: '#cp-toolbar',
+ contentContainer: '#cp-app-whiteboard-canvas-area',
+ }, waitFor(function (framework) {
+ andThen2(framework);
+ }));
});
};
main();