Use framework in the whiteboard app

pull/1/head
yflory 7 years ago
parent d37aa0646e
commit 60db53a993

@ -176,9 +176,12 @@ define([
} }
}; };
var contentUpdate = function (newContent) { var oldContent;
var contentUpdate = function (newContent, waitFor) {
if (JSONSortify(newContent) === JSONSortify(oldContent)) { return; }
try { try {
evContentUpdate.fire(newContent); evContentUpdate.fire(newContent, waitFor);
setTimeout(function () { oldContent = newContent; });
} catch (e) { } catch (e) {
console.log(e.stack); console.log(e.stack);
UI.errorLoadingScreen(e.message); UI.errorLoadingScreen(e.message);
@ -197,8 +200,9 @@ define([
cpNfInner.metadataMgr.updateMetadata(meta); cpNfInner.metadataMgr.updateMetadata(meta);
newContent = normalize(newContent); newContent = normalize(newContent);
contentUpdate(newContent); nThen(function (waitFor) {
contentUpdate(newContent, waitFor);
}).nThen(function () {
if (!readOnly) { if (!readOnly) {
var newContent2NoMeta = normalize(contentGetter()); var newContent2NoMeta = normalize(contentGetter());
var newContent2StrNoMeta = JSONSortify(newContent2NoMeta); var newContent2StrNoMeta = JSONSortify(newContent2NoMeta);
@ -237,6 +241,7 @@ define([
if (JSONSortify(newContent) !== JSONSortify(oldContent)) { if (JSONSortify(newContent) !== JSONSortify(oldContent)) {
common.notify(); common.notify();
} }
});
}; };
var setHistoryMode = function (bool, update) { var setHistoryMode = function (bool, update) {
@ -289,11 +294,13 @@ define([
var newPad = false; var newPad = false;
if (newContentStr === '') { newPad = true; } if (newContentStr === '') { newPad = true; }
// contentUpdate may be async so we need an nthen here
nThen(function (waitFor) {
if (!newPad) { if (!newPad) {
var newContent = JSON.parse(newContentStr); var newContent = JSON.parse(newContentStr);
cpNfInner.metadataMgr.updateMetadata(extractMetadata(newContent)); cpNfInner.metadataMgr.updateMetadata(extractMetadata(newContent));
newContent = normalize(newContent); newContent = normalize(newContent);
contentUpdate(newContent); contentUpdate(newContent, waitFor);
} else { } else {
if (!cpNfInner.metadataMgr.getPrivateData().isNewFile) { if (!cpNfInner.metadataMgr.getPrivateData().isNewFile) {
// We're getting 'new pad' but there is an existing file // We're getting 'new pad' but there is an existing file
@ -310,6 +317,7 @@ define([
title.updateTitle(title.defaultTitle); title.updateTitle(title.defaultTitle);
evOnDefaultContentNeeded.fire(); evOnDefaultContentNeeded.fire();
} }
}).nThen(function () {
stateChange(STATE.READY); stateChange(STATE.READY);
firstConnection = false; firstConnection = false;
if (!readOnly) { onLocal(); } if (!readOnly) { onLocal(); }
@ -341,6 +349,7 @@ define([
if (newPad && (!AppConfig.displayCreationScreen || (!skipTemp && skipCreation))) { if (newPad && (!AppConfig.displayCreationScreen || (!skipTemp && skipCreation))) {
common.openTemplatePicker(); common.openTemplatePicker();
} }
});
}; };
var onConnectionChange = function (info) { var onConnectionChange = function (info) {
if (state === STATE.DELETED) { return; } if (state === STATE.DELETED) { return; }
@ -385,13 +394,19 @@ define([
common.createButton('import', true, options, function (c, f) { common.createButton('import', true, options, function (c, f) {
if (async) { if (async) {
fi(c, f, function (content) { fi(c, f, function (content) {
contentUpdate(content); nThen(function (waitFor) {
contentUpdate(content, waitFor);
}).nThen(function () {
onLocal(); onLocal();
}); });
});
return; return;
} }
contentUpdate(fi(c, f)); nThen(function (waitFor) {
contentUpdate(fi(c, f), waitFor);
}).nThen(function () {
onLocal(); onLocal();
});
}) })
); );
}; };

@ -1,81 +1,59 @@
define([ define([
'jquery', 'jquery',
'/bower_components/chainpad-crypto/crypto.js',
'/common/toolbar3.js',
'json.sortify', 'json.sortify',
'/common/common-util.js',
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
'/common/sframe-common.js', '/common/sframe-common.js',
'/common/sframe-app-framework.js',
'/common/common-util.js',
'/common/common-hash.js',
'/common/common-interface.js', '/common/common-interface.js',
'/api/config', '/common/common-thumbnail.js',
'/common/common-realtime.js',
'/customize/pages.js', '/customize/pages.js',
'/customize/messages.js', '/customize/messages.js',
'/customize/application_config.js',
'/common/common-thumbnail.js',
'/whiteboard/colors.js', '/whiteboard/colors.js',
'/customize/application_config.js',
'/bower_components/chainpad/chainpad.dist.js', '/bower_components/chainpad/chainpad.dist.js',
'/bower_components/secure-fabric.js/dist/fabric.min.js', '/bower_components/secure-fabric.js/dist/fabric.min.js',
'/bower_components/file-saver/FileSaver.min.js',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/customize/src/less2/main.less',
], function ( ], function (
$, $,
Crypto, Sortify,
Toolbar,
JSONSortify,
Util,
nThen, nThen,
SFCommon, SFCommon,
Framework,
Util,
Hash,
UI, UI,
ApiConfig, Thumb,
CommonRealtime,
Pages, Pages,
Messages, Messages,
AppConfig,
Thumb,
Colors, Colors,
AppConfig,
ChainPad) ChainPad)
{ {
var saveAs = window.saveAs;
var APP = window.APP = { var APP = window.APP = {
$: $ $: $
}; };
var Fabric = APP.Fabric = window.fabric; var Fabric = APP.Fabric = window.fabric;
var stringify = function (obj) { var verbose = function (x) { console.log(x); };
return JSONSortify(obj); verbose = function () {}; // comment out to enable verbose logging
};
var toolbar;
var andThen = function (common) { var mkControls = function (framework, canvas) {
var config = {};
/* Initialize Fabric */
var canvas = APP.canvas = new Fabric.Canvas('cp-app-whiteboard-canvas', {
containerClass: 'cp-app-whiteboard-canvas-container'
});
var $canvas = $('canvas');
var $controls = $('#cp-app-whiteboard-controls');
var $canvasContainer = $('canvas').parents('.cp-app-whiteboard-canvas-container');
var $pickers = $('#cp-app-whiteboard-pickers'); var $pickers = $('#cp-app-whiteboard-pickers');
var $colors = $('#cp-app-whiteboard-colors'); var $colors = $('#cp-app-whiteboard-colors');
var $cursors = $('#cp-app-whiteboard-cursors'); var $cursors = $('#cp-app-whiteboard-cursors');
var $deleteButton = $('#cp-app-whiteboard-delete'); var $controls = $('#cp-app-whiteboard-controls');
var $toggle = $('#cp-app-whiteboard-toggledraw');
var $width = $('#cp-app-whiteboard-width'); var $width = $('#cp-app-whiteboard-width');
var $widthLabel = $('label[for="cp-app-whiteboard-width"]'); var $widthLabel = $('label[for="cp-app-whiteboard-width"]');
var $opacity = $('#cp-app-whiteboard-opacity'); var $opacity = $('#cp-app-whiteboard-opacity');
var $opacityLabel = $('label[for="cp-app-whiteboard-opacity"]'); var $opacityLabel = $('label[for="cp-app-whiteboard-opacity"]');
var $toggle = $('#cp-app-whiteboard-toggledraw');
var $deleteButton = $('#cp-app-whiteboard-delete');
var metadataMgr = framework._.cpNfInner.metadataMgr;
// Brush
var readOnly = false;
var brush = { var brush = {
color: '#000000', color: '#000000',
opacity: 1 opacity: 1
@ -136,39 +114,6 @@ define([
updateBrushOpacity(); updateBrushOpacity();
$opacity.on('change', updateBrushOpacity); $opacity.on('change', updateBrushOpacity);
var pickColor = function (current, cb) {
var $picker = $('<input>', {
type: 'color',
value: '#FFFFFF',
})
.on('change', function () {
var color = this.value;
cb(color);
}).appendTo($pickers);
setTimeout(function () {
$picker.val(current);
$picker.click();
});
};
var setColor = function (c) {
c = Colors.rgb2hex(c);
brush.color = c;
canvas.freeDrawingBrush.color = Colors.hex2rgba(brush.color, brush.opacity);
APP.$color.css({
'color': c,
});
createCursor();
};
var palette = AppConfig.whiteboardPalette || [
'red', 'blue', 'green', 'white', 'black', 'purple',
'gray', 'beige', 'brown', 'cyan', 'darkcyan', 'gold', 'yellow', 'pink'
];
$('.cp-app-whiteboard-palette-color').on('click', function () {
var color = $(this).css('background-color');
setColor(color);
});
APP.draw = true; APP.draw = true;
var toggleDrawMode = function () { var toggleDrawMode = function () {
canvas.deactivateAll().renderAll(); canvas.deactivateAll().renderAll();
@ -191,74 +136,49 @@ define([
canvas.discardActiveGroup(); canvas.discardActiveGroup();
} }
canvas.renderAll(); canvas.renderAll();
config.onLocal(); framework.localChange();
}; };
$deleteButton.click(deleteSelection); $deleteButton.click(deleteSelection);
$(window).on('keyup', function (e) { $(window).on('keyup', function (e) {
if (e.which === 46) { deleteSelection (); } if (e.which === 46) { deleteSelection (); }
}); });
var setEditable = function (bool) {
APP.editable = bool;
if (readOnly && bool) { return; }
if (bool) { $controls.css('display', 'flex'); }
else { $controls.hide(); }
canvas.isDrawingMode = bool ? APP.draw : false; var pickColor = function (current, cb) {
if (!bool) { var $picker = $('<input>', {
canvas.deactivateAll(); type: 'color',
canvas.renderAll(); value: '#FFFFFF',
} })
canvas.forEachObject(function (object) { .on('change', function () {
object.selectable = bool; var color = this.value;
cb(color);
}).appendTo($pickers);
setTimeout(function () {
$picker.val(current);
$picker.click();
}); });
$canvasContainer.find('canvas').css('border-color', bool? 'black': 'red');
}; };
var setColor = function (c) {
var saveImage = APP.saveImage = function () { c = Colors.rgb2hex(c);
var defaultName = "pretty-picture.png"; brush.color = c;
UI.prompt(Messages.exportPrompt, defaultName, function (filename) { canvas.freeDrawingBrush.color = Colors.hex2rgba(brush.color, brush.opacity);
if (!(typeof(filename) === 'string' && filename)) { return; } APP.$color.css({
$canvas[0].toBlob(function (blob) { 'color': c,
saveAs(blob, filename);
});
}); });
createCursor();
}; };
APP.FM = common.createFileManager({}); var palette = AppConfig.whiteboardPalette || [
APP.upload = function (title) { 'red', 'blue', 'green', 'white', 'black', 'purple',
var canvas = $canvas[0]; 'gray', 'beige', 'brown', 'cyan', 'darkcyan', 'gold', 'yellow', 'pink'
APP.canvas.deactivateAll().renderAll(); ];
canvas.toBlob(function (blob) { $('.cp-app-whiteboard-palette-color').on('click', function () {
blob.name = title; var color = $(this).css('background-color');
APP.FM.handleFile(blob); setColor(color);
}); });
};
var initializing = true;
var $bar = $('#cp-toolbar');
var Title;
var cpNfInner;
var metadataMgr;
config = {
readOnly: readOnly,
patchTransformer: ChainPad.NaiveJSONTransformer,
// cryptpad debug logging (default is 1)
// logLevel: 0,
validateContent: function (content) {
try {
JSON.parse(content);
return true;
} catch (e) {
console.log("Failed to parse, rejecting patch");
return false;
}
}
};
var addColorToPalette = function (color, i) { var addColorToPalette = function (color, i) {
if (readOnly) { return; } if (framework.isReadOnly()) { return; }
var $color = $('<span>', { var $color = $('<span>', {
'class': 'cp-app-whiteboard-palette-color', 'class': 'cp-app-whiteboard-palette-color',
}) })
@ -271,7 +191,7 @@ define([
}) })
.on('dblclick', function (e) { .on('dblclick', function (e) {
e.preventDefault(); e.preventDefault();
if (!APP.editable) { return; } if (framework.isLocked()) { return; }
pickColor(Colors.rgb2hex($color.css('background-color')), function (c) { pickColor(Colors.rgb2hex($color.css('background-color')), function (c) {
$color.css({ $color.css({
'background-color': c, 'background-color': c,
@ -287,7 +207,7 @@ define([
var first = true; var first = true;
var updatePalette = function (newPalette) { var updatePalette = function (newPalette) {
if (first || stringify(palette) !== stringify(newPalette)) { if (first || Sortify(palette) !== Sortify(newPalette)) {
palette = newPalette; palette = newPalette;
$colors.html('<div class="hidden">&nbsp;</div>'); $colors.html('<div class="hidden">&nbsp;</div>');
palette.forEach(addColorToPalette); palette.forEach(addColorToPalette);
@ -299,7 +219,7 @@ define([
var metadata = JSON.parse(JSON.stringify(metadataMgr.getMetadata())); var metadata = JSON.parse(JSON.stringify(metadataMgr.getMetadata()));
metadata.palette = newPalette; metadata.palette = newPalette;
metadataMgr.updateMetadata(metadata); metadataMgr.updateMetadata(metadata);
config.onLocal(); framework.localChange();
}; };
var makeColorButton = function ($container) { var makeColorButton = function ($container) {
@ -312,7 +232,7 @@ define([
return; return;
} }
var $color = APP.$color = common.createButton(null, true, { var $color = APP.$color = framework._.sfCommon.createButton(null, true, {
icon: 'fa-square', icon: 'fa-square',
title: Messages.canvas_chooseColor, title: Messages.canvas_chooseColor,
name: 'color', name: 'color',
@ -331,33 +251,73 @@ define([
return $color; return $color;
}; };
var stringifyInner = function (textValue) { updateLocalPalette(palette);
var obj = {
content: textValue, metadataMgr.onChange(function () {
metadata: metadataMgr.getMetadataLazy() var md = metadataMgr.getMetadata();
if (md.palette) {
updateLocalPalette(md.palette);
}
});
return {
palette: palette,
makeColorButton: makeColorButton,
updateLocalPalette: updateLocalPalette,
}; };
// stringify the json and send it into chainpad
return stringify(obj);
}; };
var onLocal = config.onLocal = function () { var mkHelpMenu = function (framework) {
if (initializing) { return; } var $appContainer = $('#cp-app-whiteboard-container');
if (readOnly) { return; } var helpMenu = framework._.sfCommon.createHelpMenu(['whiteboard']);
$appContainer.prepend(helpMenu.menu);
framework._.toolbar.$drawer.append(helpMenu.button);
};
var content = stringifyInner(canvas.toDatalessJSON()); // 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;
try { var setEditable = function (bool) {
APP.realtime.contentUpdate(content); if (bool) { $controls.css('display', 'flex'); }
} catch (e) { else { $controls.hide(); }
APP.unrecoverable = true;
setEditable(false); canvas.isDrawingMode = bool ? APP.draw : false;
APP.toolbar.errorState(true, e.message); if (!bool) {
var msg = Messages.chainpadError; canvas.deactivateAll();
UI.errorLoadingScreen(msg, true, true); canvas.renderAll();
console.error(e);
} }
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 addImageToCanvas = function (img) {
var w = img.width; var w = img.width;
var h = img.height; var h = img.height;
@ -370,107 +330,18 @@ define([
} }
var cImg = new Fabric.Image(img, { left:0, top:0, angle:0, }); var cImg = new Fabric.Image(img, { left:0, top:0, angle:0, });
APP.canvas.add(cImg); APP.canvas.add(cImg);
onLocal(); framework.localChange();
}; };
var initThumbnails = function () { // Export to drive as PNG
var oldThumbnailState; framework._.sfCommon.createButton('savetodrive', true, {}).click(function () {
var privateDat = metadataMgr.getPrivateData(); var defaultName = framework._.title.getTitle();
if (!privateDat.thumbnails) { return; } UI.prompt(Messages.exportPrompt, defaultName + '.png', function (name) {
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);
});
};
window.setInterval(mkThumbnail, Thumb.UPDATE_INTERVAL);
window.setTimeout(mkThumbnail, Thumb.UPDATE_FIRST);
};
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')
};
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; }
};
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; } if (name === null || !name.trim()) { return; }
APP.upload(name); APP.upload(name);
}); });
}).appendTo($rightside); }).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 // Embed image
var onUpload = function (e) { var onUpload = function (e) {
var file = e.target.files[0]; var file = e.target.files[0];
@ -484,7 +355,7 @@ define([
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
}; };
common.createButton('', true, { framework._.sfCommon.createButton('', true, {
title: Messages.canvas_imageEmbed, title: Messages.canvas_imageEmbed,
icon: 'fa-file-image-o', icon: 'fa-file-image-o',
name: 'embedImage' name: 'embedImage'
@ -492,12 +363,12 @@ define([
$('<input>', {type:'file'}).on('change', onUpload).click(); $('<input>', {type:'file'}).on('change', onUpload).click();
}).appendTo($rightside); }).appendTo($rightside);
if (common.isLoggedIn()) { if (framework._.sfCommon.isLoggedIn()) {
var fileDialogCfg = { var fileDialogCfg = {
onSelect: function (data) { onSelect: function (data) {
if (data.type === 'file') { if (data.type === 'file') {
var mt = '<media-tag src="' + data.src + '" data-crypto-key="cryptpad:' + data.key + '"></media-tag>'; var mt = '<media-tag src="' + data.src + '" data-crypto-key="cryptpad:' + data.key + '"></media-tag>';
common.displayMediatagImage($(mt), function (err, $image) { framework._.sfCommon.displayMediatagImage($(mt), function (err, $image) {
Util.blobURLToImage($image.attr('src'), function (imgSrc) { Util.blobURLToImage($image.attr('src'), function (imgSrc) {
var img = new Image(); var img = new Image();
img.onload = function () { addImageToCanvas(img); }; img.onload = function () { addImageToCanvas(img); };
@ -508,8 +379,8 @@ define([
} }
} }
}; };
common.initFilePicker(fileDialogCfg); framework._.sfCommon.initFilePicker(fileDialogCfg);
APP.$mediaTagButton = common.createButton('mediatag', true).click(function () { framework._.sfCommon.createButton('mediatag', true).click(function () {
var pickerCfg = { var pickerCfg = {
types: ['file'], types: ['file'],
where: ['root'], where: ['root'],
@ -517,166 +388,101 @@ define([
fileType: ['image/'] fileType: ['image/']
} }
}; };
common.openFilePicker(pickerCfg); framework._.sfCommon.openFilePicker(pickerCfg);
}).appendTo($rightside); }).appendTo($rightside);
} }
} else {
$colors.hide();
$controls.hide();
}
metadataMgr.onChange(function () { if (framework.isReadOnly()) {
var md = metadataMgr.getMetadata(); setEditable(false);
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; }
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 { } else {
Title.updateTitle(Title.defaultTitle); controls.makeColorButton($rightside);
} }
nThen(function (waitFor) { $('#cp-app-whiteboard-clear').on('click', function () {
if (newDoc) { canvas.clear();
canvas.loadFromJSON(newDoc, waitFor(function () { framework.localChange();
console.log('loaded'); });
canvas.renderAll();
}));
}
}).nThen(function () {
setEditable(!readOnly);
initializing = false;
config.onLocal();
UI.removeLoadingScreen();
initThumbnails(); // ---------------------------------------------
// End custom
// ---------------------------------------------
if (readOnly) { return; } framework.onEditableChange(function () {
var locked = framework.isLocked() || framework.isReadOnly();
setEditable(!locked);
});
var privateDat = metadataMgr.getPrivateData(); framework.setFileExporter('png', function (cb) {
var skipTemp = Util.find(privateDat, $canvas[0].toBlob(function (blob) {
['settings', 'general', 'creation', 'noTemplate']); cb(blob);
var skipCreation = Util.find(privateDat, ['settings', 'general', 'creation', 'skip']); });
if (isNew && (!AppConfig.displayCreationScreen || (!skipTemp && skipCreation))) {
common.openTemplatePicker();
}
}); });
framework.setNormalizer(function (c) {
return {
content: c.content
}; };
});
config.onRemote = function () { framework.onContentUpdate(function (newContent, waitFor) {
if (initializing) { return; } var content = newContent.content;
var userDoc = APP.realtime.getUserDoc(); canvas.loadFromJSON(content, waitFor(function () {
var json = JSON.parse(userDoc);
var remoteDoc = json.content;
canvas.loadFromJSON(remoteDoc, function () {
canvas.renderAll(); canvas.renderAll();
if (json.metadata) { }));
metadataMgr.updateMetadata(json.metadata);
}
}); });
framework.setContentGetter(function () {
var content = canvas.toDatalessJSON(); var content = canvas.toDatalessJSON();
if (content !== remoteDoc) { common.notify(); } return {
if (readOnly) { setEditable(false); } content: content
};
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); framework.onReady(function () {
var oldThumbnailState;
$('#cp-app-whiteboard-clear').on('click', function () { var privateDat = metadataMgr.getPrivateData();
canvas.clear(); if (!privateDat.thumbnails) { return; }
onLocal(); 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);
}); });
};
$('#save').on('click', function () { window.setInterval(mkThumbnail, Thumb.UPDATE_INTERVAL);
saveImage(); window.setTimeout(mkThumbnail, Thumb.UPDATE_FIRST);
}); });
common.onLogout(function () { setEditable(false); }); canvas.on('mouse:up', framework.localChange);
framework.start();
}; };
var main = function () { var main = function () {
var common; // var framework;
nThen(function (waitFor) { nThen(function (waitFor) {
$(waitFor(function () { $(waitFor(function () {
UI.addLoadingScreen();
var $div = $('<div>').append(Pages['/whiteboard/']()); var $div = $('<div>').append(Pages['/whiteboard/']());
$('body').append($div.html()); $('body').append($div.html());
})); }));
SFCommon.create(waitFor(function (c) { APP.common = common = c; }));
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
common.getSframeChannel().onReady(waitFor());
}).nThen(function (waitFor) { // Framework initialization
common.handleNewFile(waitFor); Framework.create({
}).nThen(function (/*waitFor*/) { patchTransformer: ChainPad.NaiveJSONTransformer,
andThen(common); toolbarContainer: '#cp-toolbar',
contentContainer: '#cp-app-whiteboard-canvas-area',
}, waitFor(function (framework) {
andThen2(framework);
}));
}); });
}; };
main(); main();

Loading…
Cancel
Save