diff --git a/customize.dist/application_config.js b/customize.dist/application_config.js
index 1ac8a8bab..8f190a9ad 100644
--- a/customize.dist/application_config.js
+++ b/customize.dist/application_config.js
@@ -32,6 +32,7 @@ define(function() {
'#FF00C0', // hot pink
'#800080', // purple
];
+ config.enableTemplates = true;
return config;
});
diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js
index eb6f0c392..78b1b067a 100644
--- a/customize.dist/translations/messages.fr.js
+++ b/customize.dist/translations/messages.fr.js
@@ -75,6 +75,11 @@ define(function () {
out.newButton = 'Nouveau';
out.newButtonTitle = 'Créer un nouveau pad';
+ out.saveTemplateButton = "Sauver en tant que modèle";
+ out.saveTemplatePrompt = "Choisir un titre pour ce modèle";
+ out.templateSaved = "Modèle enregistré !";
+ out.selectTemplate = "Sélectionner un modèle ou appuyer sur Échap";
+
out.presentButtonTitle = "Entrer en mode présentation";
out.presentSuccess = 'Appuyer sur Échap pour quitter le mode présentation';
diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js
index 0f95fbc3e..607a9ff4c 100644
--- a/customize.dist/translations/messages.js
+++ b/customize.dist/translations/messages.js
@@ -77,6 +77,11 @@ define(function () {
out.newButton = 'New';
out.newButtonTitle = 'Create a new pad';
+ out.saveTemplateButton = "Save as template";
+ out.saveTemplatePrompt = "Choose a title for the template";
+ out.templateSaved = "Template saved!";
+ out.selectTemplate = "Select a template or press escape";
+
out.presentButtonTitle = "Enter presentation mode";
out.presentSuccess = 'Hit ESC to exit presentation mode';
diff --git a/www/code/main.js b/www/code/main.js
index 8127cb566..227c1e1fa 100644
--- a/www/code/main.js
+++ b/www/code/main.js
@@ -7,13 +7,14 @@ define([
'json.sortify',
'/bower_components/chainpad-json-validator/json-ot.js',
'/common/cryptpad-common.js',
+ '/common/cryptget.js',
'/common/modes.js',
'/common/themes.js',
'/common/visible.js',
'/common/notify.js',
'/bower_components/file-saver/FileSaver.min.js',
'/bower_components/jquery/dist/jquery.min.js',
-], function (Crypto, Realtime, TextPatcher, Toolbar, JSONSortify, JsonOT, Cryptpad, Modes, Themes, Visible, Notify) {
+], function (Crypto, Realtime, TextPatcher, Toolbar, JSONSortify, JsonOT, Cryptpad, Cryptget, Modes, Themes, Visible, Notify) {
var $ = window.jQuery;
var saveAs = window.saveAs;
var Messages = Cryptpad.Messages;
@@ -401,6 +402,17 @@ define([
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
}
+ /* save as template */
+ if (!Cryptpad.isTemplate(window.location.href)) {
+ var templateObj = {
+ rt: info.realtime,
+ Crypt: Cryptget,
+ getTitle: function () { return document.title; }
+ };
+ var $templateButton = Cryptpad.createButton('template', true, templateObj);
+ $rightside.append($templateButton);
+ }
+
/* add an export button */
var $export = Cryptpad.createButton('export', true, {}, exportText);
$rightside.append($export);
@@ -532,6 +544,8 @@ define([
var userDoc = module.realtime.getUserDoc();
+ var isNew = false;
+ if (userDoc === "" || userDoc === "{}") { isNew = true; }
var newDoc = "";
if(userDoc !== "") {
@@ -599,6 +613,9 @@ define([
onLocal();
module.$userNameButton.click();
}
+ if (isNew) {
+ Cryptpad.selectTemplate('code', info.realtime, Cryptget);
+ }
});
};
diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js
index c904b7678..ee8d06151 100644
--- a/www/common/cryptpad-common.js
+++ b/www/common/cryptpad-common.js
@@ -498,7 +498,7 @@ load pinpad dynamically only after you know that it will be needed */
};
var makePad = function (href, title) {
- var now = ''+new Date();
+ var now = +new Date();
return {
href: href,
atime: now,
@@ -557,6 +557,41 @@ load pinpad dynamically only after you know that it will be needed */
getStore().addTemplate(href);
};
+ var isTemplate = common.isTemplate = function (href) {
+ var rhref = getRelativeHref(href);
+ var templates = listTemplates();
+ return templates.some(function (t) {
+ return t.href === rhref;
+ });
+ };
+ var selectTemplate = common.selectTemplate = function (type, rt, Crypt) {
+ if (!AppConfig.enableTemplates) { return; }
+ var temps = listTemplates(type);
+ if (temps.length === 0) { return; }
+ var $content = $('
');
+ $('
').text(Messages.selectTemplate).appendTo($content);
+ $('', {id:"selectTemplate"}).appendTo($content);
+ Cryptpad.alert($content.html(), null, true);
+ var $p = $('#selectTemplate');
+ temps.forEach(function (t, i) {
+ $('', {href: t.href, title: t.title}).text(t.title).click(function (e) {
+ e.preventDefault();
+ var parsed = parsePadUrl(t.href);
+ if(!parsed) { throw new Error("Cannot get template hash"); }
+ common.addLoadingScreen(null, true);
+ Crypt.get(parsed.hash, function (err, val) {
+ if (err) { throw new Error(err); }
+ var p = parsePadUrl(window.location.href);
+ Crypt.put(p.hash, val, function (e) {
+ common.findOKButton().click();
+ common.removeLoadingScreen();
+ });
+ });
+ }).appendTo($p);
+ if (i !== temps.length) { $('
').appendTo($p); }
+ });
+ common.findOKButton().text(Messages.cancelButton);
+ };
// STORAGE
/* fetch and migrate your pad history from localStorage */
@@ -1080,6 +1115,56 @@ load pinpad dynamically only after you know that it will be needed */
}));
}
break;
+ case 'template':
+ if (!AppConfig.enableTemplates) { return; }
+ button = $('