', {'class': 'cp-dropdown-content'});
if (config.left) { $innerblock.addClass('cp-dropdown-left'); }
config.options.forEach(function (o) {
if (!isValidOption(o)) { return; }
if (isElement(o)) { return $innerblock.append($(o)); }
var $el = $('<' + o.tag + '>', o.attributes || {}).html(o.content || '');
$el.appendTo($innerblock);
if (typeof(o.action) === 'function') {
$el.click(o.action);
}
});
$container.append($button).append($innerblock);
var value = config.initialValue || '';
var setActive = function ($el) {
if ($el.length !== 1) { return; }
$innerblock.find('.cp-dropdown-element-active').removeClass('cp-dropdown-element-active');
$el.addClass('cp-dropdown-element-active');
var scroll = $el.position().top + $innerblock.scrollTop();
if (scroll < $innerblock.scrollTop()) {
$innerblock.scrollTop(scroll);
} else if (scroll > ($innerblock.scrollTop() + 280)) {
$innerblock.scrollTop(scroll-270);
}
};
var hide = function () {
window.setTimeout(function () { $innerblock.hide(); }, 0);
};
var show = function () {
var wh = $(window).height();
var button = $button[0].getBoundingClientRect();
var topPos = button.bottom;
$innerblock.css('bottom', '');
if (config.noscroll) {
var h = $innerblock.outerHeight();
if ((topPos + h) > wh) {
$innerblock.css('bottom', button.height+'px');
}
} else {
$innerblock.css('max-height', Math.floor(wh - topPos - 1)+'px');
}
$innerblock.show();
$innerblock.find('.cp-dropdown-element-active').removeClass('cp-dropdown-element-active');
if (config.isSelect && value) {
var $val = $innerblock.find('[data-value="'+value+'"]');
setActive($val);
try {
$innerblock.scrollTop($val.position().top + $innerblock.scrollTop());
} catch (e) {}
}
if (config.feedback) { Feedback.send(config.feedback); }
};
$container.click(function (e) {
e.stopPropagation();
var state = $innerblock.is(':visible');
$('.cp-dropdown-content').hide();
var $c = $container.closest('.cp-toolbar-drawer-content');
$c.removeClass('cp-dropdown-visible');
if (!state) { $c.addClass('cp-dropdown-visible'); }
try {
$('iframe').each(function (idx, ifrw) {
$(ifrw).contents().find('.cp-dropdown-content').hide();
});
} catch (er) {
// empty try catch in case this iframe is problematic (cross-origin)
}
if (state) {
hide();
return;
}
show();
});
if (config.isSelect) {
var pressed = '';
var to;
$container.on('click', 'a', function () {
value = $(this).data('value');
var $val = $(this);
var textValue = $val.html() || value;
$button.find('.cp-dropdown-button-title').html(textValue);
});
$container.keydown(function (e) {
var $value = $innerblock.find('[data-value].cp-dropdown-element-active:visible');
if (!$value.length) {
$value = $innerblock.find('[data-value]').first();
}
if (e.which === 38) { // Up
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.mouseleave();
var $prev = $value.prev();
$prev.mouseenter();
setActive($prev);
}
}
if (e.which === 40) { // Down
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.mouseleave();
var $next = $value.next();
$next.mouseenter();
setActive($next);
}
}
if (e.which === 13) { //Enter
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.click();
hide();
}
}
if (e.which === 27) { // Esc
e.preventDefault();
e.stopPropagation();
$value.mouseleave();
hide();
}
});
$container.keypress(function (e) {
window.clearTimeout(to);
var c = String.fromCharCode(e.which);
pressed += c;
var $value = $innerblock.find('[data-value^="'+pressed+'"]:first');
if ($value.length) {
setActive($value);
$innerblock.scrollTop($value.position().top + $innerblock.scrollTop());
}
to = window.setTimeout(function () {
pressed = '';
}, 1000);
});
$container.setValue = function (val, name) {
value = val;
var $val = $innerblock.find('[data-value="'+val+'"]');
var textValue = name || $val.html() || val;
setTimeout(function () {
$button.find('.cp-dropdown-button-title').html(textValue);
});
};
$container.getValue = function () {
return value || '';
};
}
return $container;
};
UIElements.displayInfoMenu = function (Common, metadataMgr) {
//var padType = metadataMgr.getMetadata().type;
var priv = metadataMgr.getPrivateData();
var origin = priv.origin;
// TODO link to the most recent changelog/release notes
// https://github.com/xwiki-labs/cryptpad/releases/latest/ ?
var template = function (line, link) {
if (!line || !link) { return; }
var p = $('
').html(line)[0];
var sub = link.cloneNode(true);
/* This is a hack to make relative URLs point to the main domain
instead of the sandbox domain. It will break if the admins have specified
some less common URL formats for their customizable links, such as if they've
used a protocal-relative absolute URL. The URL API isn't quite safe to use
because of IE (thanks, Bill). */
var href = sub.getAttribute('href');
if (/^\//.test(href)) { sub.setAttribute('href', origin + href); }
var a = p.querySelector('a');
if (!a) { return; }
sub.innerText = a.innerText;
p.replaceChild(sub, a);
return p;
};
var legalLine = template(Messages.info_imprintFlavour, Pages.imprintLink);
var privacyLine = template(Messages.info_privacyFlavour, Pages.privacyLink);
// XXX existing key
Messages.help.generic.more = "Learn more about how CryptPad can work for you by reading our Documentation.";
var faqLine = template(Messages.help.generic.more, Pages.docsLink);
var content = h('div.cp-info-menu-container', [
h('div.logo-block', [
h('img', {
src: '/customize/CryptPad_logo.svg?' + urlArgs
}),
h('h6', "CryptPad"),
h('span', Pages.versionString)
]),
h('hr'),
legalLine,
privacyLine,
faqLine,
]);
var buttons = [
{
className: 'primary',
name: Messages.filePicker_close,
onClick: function () {},
keys: [27],
},
];
var modal = UI.dialog.customModal(content, {buttons: buttons });
UI.openCustomModal(modal);
};
UIElements.createUserAdminMenu = function (Common, config) {
var metadataMgr = Common.getMetadataMgr();
var displayNameCls = config.displayNameCls || 'cp-toolbar-user-name';
var $displayedName = $('', {'class': displayNameCls});
var priv = metadataMgr.getPrivateData();
var accountName = priv.accountName;
var origin = priv.origin;
var padType = metadataMgr.getMetadata().type;
var $userName = $('');
var options = [];
if (config.displayNameCls) {
var $userAdminContent = $('');
if (accountName) {
var $userAccount = $('').append(Messages.user_accountName + ': ');
$userAdminContent.append($userAccount).append(Util.fixHTML(accountName));
$userAdminContent.append($('
'));
}
if (config.displayName && !AppConfig.disableProfile) {
// Hide "Display name:" in read only mode
$userName.append(Messages.user_displayName + ': ');
$userName.append($displayedName);
}
$userAdminContent.append($userName);
options.push({
tag: 'p',
attributes: {'class': 'cp-toolbar-account'},
content: $userAdminContent.html()
});
}
if (accountName && !AppConfig.disableProfile) {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-profile fa fa-user-circle'},
content: h('span', Messages.profileButton),
action: function () {
if (padType) {
window.open(origin+'/profile/');
} else {
window.parent.location = origin+'/profile/';
}
},
});
}
if (padType !== 'drive' || (!accountName && priv.newSharedFolder)) {
options.push({
tag: 'a',
attributes: {
'target': '_blank',
'href': origin+'/drive/',
'class': 'fa fa-hdd-o'
},
content: h('span', Messages.type.drive)
});
}
if (padType !== 'teams' && accountName) {
options.push({
tag: 'a',
attributes: {
'target': '_blank',
'href': origin+'/teams/',
'class': 'fa fa-users'
},
content: h('span', Messages.type.teams)
});
}
if (padType !== 'contacts' && accountName) {
options.push({
tag: 'a',
attributes: {
'target': '_blank',
'href': origin+'/contacts/',
'class': 'fa fa-address-book'
},
content: h('span', Messages.type.contacts)
});
}
if (padType !== 'settings') {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-settings fa fa-cog'},
content: h('span', Messages.settingsButton),
action: function () {
if (padType) {
window.open(origin+'/settings/');
} else {
window.parent.location = origin+'/settings/';
}
},
});
}
options.push({ tag: 'hr' });
// Add administration panel link if the user is an admin
if (priv.edPublic && Array.isArray(Config.adminKeys) && Config.adminKeys.indexOf(priv.edPublic) !== -1) {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-admin fa fa-cogs'},
content: h('span', Messages.adminPage || 'Admin'),
action: function () {
if (padType) {
window.open(origin+'/admin/');
} else {
window.parent.location = origin+'/admin/';
}
},
});
}
options.push({
tag: 'a',
attributes: {
'target': '_blank',
'rel': 'noopener',
'href': 'https://docs.cryptpad.fr',
'class': 'fa fa-book'
},
content: h('span', Messages.docs_link) // XXX
});
if (padType !== 'support' && accountName && Config.supportMailbox) {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-support fa fa-life-ring'},
content: h('span', Messages.supportPage || 'Support'),
action: function () {
if (padType) {
window.open(origin+'/support/');
} else {
window.parent.location = origin+'/support/';
}
},
});
}
// XXX Trade the survey for documentation
// if (AppConfig.surveyURL) {
// options.push({
// tag: 'a',
// attributes: {
// 'target': '_blank',
// 'rel': 'noopener',
// 'href': AppConfig.surveyURL,
// 'class': 'cp-toolbar-survey fa fa-graduation-cap'
// },
// content: h('span', Messages.survey),
// action: function () {
// Feedback.send('SURVEY_CLICKED');
// },
// });
// }
options.push({
tag: 'a',
attributes: {
'class': 'cp-toolbar-about fa fa-info',
},
content: h('span', Messages.user_about),
action: function () {
UIElements.displayInfoMenu(Common, metadataMgr);
},
});
options.push({
tag: 'a',
attributes: {
'target': '_blank',
'href': origin+'/index.html',
'class': 'fa fa-home'
},
content: h('span', Messages.homePage)
});
// Add the change display name button if not in read only mode
/*
if (config.changeNameButtonCls && config.displayChangeName && !AppConfig.disableProfile) {
options.push({
tag: 'a',
attributes: {'class': config.changeNameButtonCls + ' fa fa-user'},
content: h('span', Messages.user_rename)
});
}*/
options.push({ tag: 'hr' });
if (Config.allowSubscriptions) {
options.push({
tag: 'a',
attributes: {
'target': '_blank',
'href': priv.plan ? priv.accounts.upgradeURL : origin+'/features.html',
'class': 'fa fa-star-o'
},
content: h('span', priv.plan ? Messages.settings_cat_subscription : Messages.pricing)
});
}
if (!priv.plan && !Config.removeDonateButton) {
options.push({
tag: 'a',
attributes: {
'target': '_blank',
'rel': 'noopener',
'href': priv.accounts.donateURL,
'class': 'fa fa-gift'
},
content: h('span', Messages.crowdfunding_button2)
});
}
options.push({ tag: 'hr' });
// Add login or logout button depending on the current status
if (priv.loggedIn) {
options.push({
tag: 'a',
attributes: {
'class': 'cp-toolbar-menu-logout-everywhere fa fa-plug',
},
content: h('span', Messages.logoutEverywhere),
action: function () {
Common.getSframeChannel().query('Q_LOGOUT_EVERYWHERE', null, function () {
window.parent.location = origin + '/';
});
},
});
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-logout fa fa-sign-out'},
content: h('span', Messages.logoutButton),
action: function () {
Common.logout(function () {
window.parent.location = origin+'/';
});
},
});
} else {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-login fa fa-sign-in'},
content: h('span', Messages.login_login),
action: function () {
Common.setLoginRedirect('login');
},
});
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-register fa fa-user-plus'},
content: h('span', Messages.login_register),
action: function () {
Common.setLoginRedirect('register');
},
});
}
var $icon = $('', {'class': 'fa fa-user-secret'});
//var $userbig = $('', {'class': 'big'}).append($displayedName.clone());
var $userButton = $('').append($icon);//.append($userbig);
if (accountName) {
$userButton = $('
').append(accountName);
}
/*if (account && config.displayNameCls) {
$userbig.append($('
', {'class': 'account-name'}).text('(' + accountName + ')'));
} else if (account) {
// If no display name, do not display the parentheses
$userbig.append($('', {'class': 'account-name'}).text(accountName));
}*/
var dropdownConfigUser = {
text: $userButton.html(), // Button initial text
options: options, // Entries displayed in the menu
left: true, // Open to the left of the button
container: config.$initBlock, // optional
feedback: "USER_ADMIN",
common: Common
};
var $userAdmin = UIElements.createDropdown(dropdownConfigUser);
/*
// Uncomment these lines to have a language selector in the admin menu
// FIXME clicking on the inner menu hides the outer one
var $lang = UIElements.createLanguageSelector(Common);
$userAdmin.find('.cp-dropdown-content').append($lang);
*/
var $displayName = $userAdmin.find('.'+displayNameCls);
var $avatar = $userAdmin.find('> button .cp-dropdown-button-title');
var loadingAvatar;
var to;
var oldUrl = '';
var updateButton = function () {
var myData = metadataMgr.getUserData();
if (!myData) { return; }
if (loadingAvatar) {
// Try again in 200ms
window.clearTimeout(to);
to = window.setTimeout(updateButton, 200);
return;
}
loadingAvatar = true;
var newName = myData.name;
var url = myData.avatar;
$displayName.text(newName || Messages.anonymous);
if (accountName && oldUrl !== url) {
$avatar.html('');
Common.displayAvatar($avatar, url,
newName || Messages.anonymous, function ($img) {
oldUrl = url;
$userAdmin.find('> button').removeClass('cp-avatar');
if ($img) { $userAdmin.find('> button').addClass('cp-avatar'); }
loadingAvatar = false;
});
return;
}
loadingAvatar = false;
};
metadataMgr.onChange(updateButton);
updateButton();
return $userAdmin;
};
// Provide $container if you want to put the generated block in another element
// Provide $initBlock if you already have the menu block and you want the content inserted in it
UIElements.createLanguageSelector = function (common, $container, $initBlock) {
var options = [];
var languages = Messages._languages;
var keys = Object.keys(languages).sort();
keys.forEach(function (l) {
options.push({
tag: 'a',
attributes: {
'class': 'cp-language-value',
'data-value': l,
'href': '#',
},
content: languages[l] // Pretty name of the language value
});
});
var dropdownConfig = {
text: Messages.language, // Button initial text
options: options, // Entries displayed in the menu
//left: true, // Open to the left of the button
container: $initBlock, // optional
isSelect: true,
common: common
};
var $block = UIElements.createDropdown(dropdownConfig);
$block.attr('id', 'cp-language-selector');
if ($container) {
$block.appendTo($container);
}
Language.initSelector($block, common);
return $block;
};
UIElements.createNewPadModal = function (common) {
// if in drive, show new pad modal instead
if ($(".cp-app-drive-element-row.cp-app-drive-new-ghost").length !== 0) {
return void $(".cp-app-drive-element-row.cp-app-drive-new-ghost").click();
}
var modal = UI.createModal({
id: 'cp-app-toolbar-creation-dialog',
$body: $('body')
});
var $modal = modal.$modal;
var $title = $('').text(Messages.fm_newFile);
var $description = $('
').html(Messages.creation_newPadModalDescription);
$modal.find('.cp-modal').append($title);
$modal.find('.cp-modal').append($description);
var $container = $('
');
var i = 0;
var types = AppConfig.availablePadTypes.filter(function (p) {
if (p === 'drive') { return; }
if (p === 'teams') { return; }
if (p === 'contacts') { return; }
if (p === 'todo') { return; }
if (p === 'file') { return; }
if (p === 'accounts') { return; }
if (!common.isLoggedIn() && AppConfig.registeredOnlyTypes &&
AppConfig.registeredOnlyTypes.indexOf(p) !== -1) { return; }
return true;
});
types.forEach(function (p) {
var $element = $('
', {
'class': 'cp-icons-element',
'id': 'cp-newpad-icons-'+ (i++)
}).prepend(UI.getIcon(p)).appendTo($container);
$element.append($('', {'class': 'cp-icons-name'})
.text(Messages.type[p]));
$element.attr('data-type', p);
$element.click(function () {
$modal.hide();
common.openURL('/' + p + '/');
});
});
var selected = -1;
var next = function () {
selected = ++selected % types.length;
$container.find('.cp-icons-element-selected').removeClass('cp-icons-element-selected');
$container.find('#cp-newpad-icons-'+selected).addClass('cp-icons-element-selected');
};
$modal.off('keydown');
$modal.keydown(function (e) {
if (e.which === 9) {
e.preventDefault();
e.stopPropagation();
next();
return;
}
if (e.which === 13) {
if ($container.find('.cp-icons-element-selected').length === 1) {
$container.find('.cp-icons-element-selected').click();
}
return;
}
});
$modal.find('.cp-modal').append($container);
window.setTimeout(function () {
modal.show();
$modal.focus();
});
};
UIElements.openFilePicker = function (common, types, cb) {
var sframeChan = common.getSframeChannel();
sframeChan.query("Q_FILE_PICKER_OPEN", types, function (err, data) {
if (err) { return; }
cb(data);
});
};
UIElements.openTemplatePicker = function (common, force) {
var metadataMgr = common.getMetadataMgr();
var type = metadataMgr.getMetadataLazy().type;
var sframeChan = common.getSframeChannel();
var focus;
var pickerCfgInit = {
types: [type],
where: ['template'],
hidden: true
};
var pickerCfg = {
types: [type],
where: ['template'],
};
var onConfirm = function (yes) {
if (!yes) {
if (focus) { focus.focus(); }
return;
}
delete pickerCfg.hidden;
var first = true; // We can only pick a template once (for a new document)
common.openFilePicker(pickerCfg, function (data) {
if (data.type === type && first) {
UI.addLoadingScreen({hideTips: true});
var chatChan = common.getPadChat();
var cursorChan = common.getCursorChannel();
sframeChan.query('Q_TEMPLATE_USE', {
href: data.href,
chat: chatChan,
cursor: cursorChan
}, function () {
first = false;
UI.removeLoadingScreen();
Feedback.send('TEMPLATE_USED');
});
if (focus) { focus.focus(); }
return;
}
});
};
sframeChan.query("Q_TEMPLATE_EXIST", type, function (err, data) {
if (data) {
common.openFilePicker(pickerCfgInit);
focus = document.activeElement;
if (force) { return void onConfirm(true); }
UI.confirm(Messages.useTemplate, onConfirm, {
ok: Messages.useTemplateOK,
cancel: Messages.useTemplateCancel,
});
} else if (force) {
UI.alert(Messages.template_empty);
}
});
};
/*
UIElements.setExpirationValue = function (val, $expire) {
if (val && typeof (val) === "number") {
$expire.find('#cp-creation-expire').attr('checked', true).trigger('change');
$expire.find('#cp-creation-expire-true').attr('checked', true);
if (val % (3600 * 24 * 30) === 0) {
$expire.find('#cp-creation-expire-unit').val("month");
$expire.find('#cp-creation-expire-val').val(val / (3600 * 24 * 30));
return;
}
if (val % (3600 * 24) === 0) {
$expire.find('#cp-creation-expire-unit').val("day");
$expire.find('#cp-creation-expire-val').val(val / (3600 * 24));
return;
}
if (val % 3600 === 0) {
$expire.find('#cp-creation-expire-unit').val("hour");
$expire.find('#cp-creation-expire-val').val(val / 3600);
return;
}
// if we're here, it means we don't have a valid value so we should check unlimited
$expire.find('#cp-creation-expire-false').attr('checked', true);
}
};
*/
UIElements.getPadCreationScreen = function (common, cfg, appCfg, cb) {
appCfg = appCfg || {};
if (!common.isLoggedIn()) { return void cb(); }
var sframeChan = common.getSframeChannel();
var metadataMgr = common.getMetadataMgr();
var privateData = metadataMgr.getPrivateData();
var type = metadataMgr.getMetadataLazy().type || privateData.app;
var fromFileData = privateData.fromFileData;
var $body = $('body');
var $creationContainer = $('', { id: 'cp-creation-container' }).appendTo($body);
var urlArgs = (Config.requireConf && Config.requireConf.urlArgs) || '';
var logo = h('img', { src: '/customize/CryptPad_logo.svg?' + urlArgs });
var fill1 = h('div.cp-creation-fill.cp-creation-logo', logo);
var fill2 = h('div.cp-creation-fill');
var $creation = $('
', { id: 'cp-creation', tabindex:1 });
$creationContainer.append([fill1, $creation, fill2]);
var createHelper = function (href, text) {
var q = UI.createHelper(href, text);
$(q).addClass('cp-creation-help');
return q;
};
// Title
var colorClass = 'cp-icon-color-'+type;
//$creation.append(h('h2.cp-creation-title', Messages.newButtonTitle));
var newPadH3Title = Messages['button_new' + type];
Messages.creation_helperText = "Learn more..."; // XXX
var title = h('div.cp-creation-title', [
UI.getFileIcon({type: type})[0],
h('div.cp-creation-title-text', [
h('span', newPadH3Title),
createHelper('https://docs.cryptpad.fr/en/user_guide/apps/general.html#new-document', Messages.creation_helperText)
])
]);
$creation.append(title);
//$creation.append(h('h2.cp-creation-title.'+colorClass, Messages.newButtonTitle));
// Deleted pad warning
if (metadataMgr.getPrivateData().isDeleted) {
$creation.append(h('div.cp-creation-deleted-container',
h('div.cp-creation-deleted', Messages.creation_404)
));
}
// Team pad
var team;
var teamExists = privateData.teams && Object.keys(privateData.teams).length;
var teamValue;
// storeInTeam can be
// * a team ID ==> store in the team drive, and the team will be the owner
// * -1 ==> store in the user drive, and the user will be the owner
// * undefined ==> ask
if (teamExists) {
var teams = Object.keys(privateData.teams).map(function (id) {
var data = privateData.teams[id];
var avatar = h('span.cp-creation-team-avatar.cp-avatar');
common.displayAvatar($(avatar), data.avatar, data.name);
return h('div.cp-creation-team', {
'data-id': id,
title: data.name,
},[
avatar,
h('span.cp-creation-team-name', data.name)
]);
});
teams.unshift(h('div.cp-creation-team', {
'data-id': '-1',
title: Messages.settings_cat_drive
}, [
h('span.cp-creation-team-avatar.fa.fa-hdd-o'),
h('span.cp-creation-team-name', Messages.settings_cat_drive)
]));
team = h('div.cp-creation-teams', [
Messages.team_pcsSelectLabel,
h('div.cp-creation-teams-grid', teams),
createHelper('#', Messages.team_pcsSelectHelp)
]);
var $team = $(team);
$team.find('.cp-creation-team').click(function () {
if ($(this).hasClass('cp-selected')) {
teamValue = undefined;
return void $(this).removeClass('cp-selected');
}
$team.find('.cp-creation-team').removeClass('cp-selected');
$(this).addClass('cp-selected');
teamValue = $(this).attr('data-id');
});
if (privateData.storeInTeam) {
$team.find('[data-id="'+privateData.storeInTeam+'"]').addClass('cp-selected');
teamValue = privateData.storeInTeam;
}
}
// Owned pads
// Default is Owned pad
// XXX Remove creation_owned1 and creation_owned2 keys
var owned = h('div.cp-creation-owned', [
UI.createCheckbox('cp-creation-owned', Messages.creation_owned, true),
]);
// Life time
// XXX rewrite "creation_expire2": "An expiring pad has a set lifetime, after which it will be automatically removed from the server and other users' CryptDrives."
Messages.creation_expiration = "Expiration date"; // XXX
Messages.creation_expiresIn = "Expires in"; // XXX
var expire = h('div.cp-creation-expire', [
UI.createCheckbox('cp-creation-expire', Messages.creation_expiration, false, {
labelAlt: Messages.creation_expiresIn
}),
h('span.cp-creation-expire-picker.cp-creation-slider', [
h('input#cp-creation-expire-val', {
type: "number",
min: 1,
max: 100,
value: 3
}),
h('select#cp-creation-expire-unit', [
h('option', { value: 'hour' }, Messages.creation_expireHours),
h('option', { value: 'day' }, Messages.creation_expireDays),
h('option', {
value: 'month',
selected: 'selected'
}, Messages.creation_expireMonths)
])
]),
]);
// Password
Messages.creation_password = "Password"; // XXX
var password = h('div.cp-creation-password', [
UI.createCheckbox('cp-creation-password', Messages.creation_password, false),
h('span.cp-creation-password-picker.cp-creation-slider', [
UI.passwordInput({id: 'cp-creation-password-val'})
/*h('input#cp-creation-password-val', {
type: "text" // TODO type password with click to show
}),*/
]),
//createHelper('#', "TODO: password protection adds another layer of security ........") // TODO
]);
var $w = $(window);
var big = $w.width() > 800;
var right = h('span.fa.fa-chevron-right.cp-creation-template-more');
var left = h('span.fa.fa-chevron-left.cp-creation-template-more');
if (!big) {
$(left).removeClass('fa-chevron-left').addClass('fa-chevron-up');
$(right).removeClass('fa-chevron-right').addClass('fa-chevron-down');
}
var templates = h('div.cp-creation-template', [
left,
h('div.cp-creation-template-container', [
h('span.fa.fa-circle-o-notch.fa-spin.fa-4x.fa-fw')
]),
right
]);
var createDiv = h('div.cp-creation-create');
var $create = $(createDiv);
$(h('div#cp-creation-form', [
h('div.cp-creation-checkboxes', [
team,
owned,
expire,
password,
]),
templates,
createDiv
])).appendTo($creation);
// Display templates
var selected = 0; // Selected template in the list (highlighted)
var TEMPLATES_DISPLAYED = big ? 6 : 3; // Max templates displayed per page
var next = function () {}; // Function called when pressing tab to highlight the next template
var i = 0; // Index of the first template displayed in the current page
sframeChan.query("Q_CREATE_TEMPLATES", type, function (err, res) {
if (!res.data || !Array.isArray(res.data)) {
return void console.error("Error: get the templates list");
}
var allData = res.data.slice().sort(function (a, b) {
if (a.used === b.used) {
// Sort by name
if (a.name === b.name) { return 0; }
return a.name < b.name ? -1 : 1;
}
return b.used - a.used;
});
if (!appCfg.noTemplates) {
allData.unshift({
name: Messages.creation_newTemplate,
id: -1,
//icon: h('span.fa.fa-bookmark')
icon: h('span.cptools.cptools-new-template')
});
}
if (!privateData.newTemplate) {
allData.unshift({
name: Messages.creation_noTemplate,
id: 0,
//icon: h('span.fa.fa-file')
icon: UI.getFileIcon({type: type})
});
}
var redraw = function (index) {
if (index < 0) { i = 0; }
else if (index > allData.length - 1) { return; }
else { i = index; }
var data = allData.slice(i, i + TEMPLATES_DISPLAYED);
var $container = $(templates).find('.cp-creation-template-container').html('');
data.forEach(function (obj, idx) {
var name = obj.name;
var $span = $('', {
'class': 'cp-creation-template-element',
'title': name,
}).appendTo($container);
$span.data('id', obj.id);
if (idx === selected) { $span.addClass('cp-creation-template-selected'); }
if (!obj.thumbnail) {
$span.append(obj.icon || h('span.cptools.cptools-template'));
}
$('', {'class': 'cp-creation-template-element-name'}).text(name)
.appendTo($span);
$span.click(function () {
$container.find('.cp-creation-template-selected')
.removeClass('cp-creation-template-selected');
$span.addClass('cp-creation-template-selected');
selected = idx;
});
// Add thumbnail if it exists
if (obj.thumbnail) {
common.addThumbnail(obj.thumbnail, $span, function () {});
}
});
$(right).off('click').removeClass('hidden').click(function () {
selected = 0;
redraw(i + TEMPLATES_DISPLAYED);
});
if (i >= allData.length - TEMPLATES_DISPLAYED ) { $(right).addClass('hidden'); }
$(left).off('click').removeClass('hidden').click(function () {
selected = TEMPLATES_DISPLAYED - 1;
redraw(i - TEMPLATES_DISPLAYED);
});
if (i < TEMPLATES_DISPLAYED) { $(left).addClass('hidden'); }
};
if (fromFileData) {
var todo = function (thumbnail) {
allData = [{
name: fromFileData.title,
id: 0,
thumbnail: thumbnail,
icon: h('span.cptools.cptools-file'),
}];
redraw(0);
};
todo();
sframeChan.query("Q_GET_FILE_THUMBNAIL", null, function (err, res) {
if (err || (res && res.error)) { return; }
todo(res.data);
});
}
else {
redraw(0);
}
// Change template selection when Tab is pressed
next = function (revert) {
var max = $creation.find('.cp-creation-template-element').length;
if (selected + 1 === max && !revert) {
selected = i + TEMPLATES_DISPLAYED < allData.length ? 0 : max;
return void redraw(i + TEMPLATES_DISPLAYED);
}
if (selected === 0 && revert) {
selected = i - TEMPLATES_DISPLAYED >= 0 ? TEMPLATES_DISPLAYED - 1 : 0;
return void redraw(i - TEMPLATES_DISPLAYED);
}
selected = revert ?
(--selected < 0 ? 0 : selected) :
++selected >= max ? max-1 : selected;
$creation.find('.cp-creation-template-element')
.removeClass('cp-creation-template-selected');
$($creation.find('.cp-creation-template-element').get(selected))
.addClass('cp-creation-template-selected');
};
$w.on('resize', function () {
var _big = $w.width() > 800;
if (big === _big) { return; }
big = _big;
if (!big) {
$(left).removeClass('fa-chevron-left').addClass('fa-chevron-up');
$(right).removeClass('fa-chevron-right').addClass('fa-chevron-down');
} else {
$(left).removeClass('fa-chevron-up').addClass('fa-chevron-left');
$(right).removeClass('fa-chevron-down').addClass('fa-chevron-right');
}
TEMPLATES_DISPLAYED = big ? 6 : 3;
redraw(0);
});
});
// Display expiration form when checkbox checked
$creation.find('#cp-creation-expire').on('change', function () {
if ($(this).is(':checked')) {
$creation.find('.cp-creation-expire-picker:not(.active)').addClass('active');
$creation.find('.cp-creation-expire:not(.active)').addClass('active');
$creation.find('#cp-creation-expire-val').focus();
return;
}
$creation.find('.cp-creation-expire-picker').removeClass('active');
$creation.find('.cp-creation-expire').removeClass('active');
$creation.focus();
});
// Display password form when checkbox checked
$creation.find('#cp-creation-password').on('change', function () {
if ($(this).is(':checked')) {
$creation.find('.cp-creation-password-picker:not(.active)').addClass('active');
$creation.find('.cp-creation-password:not(.active)').addClass('active');
$creation.find('#cp-creation-password-val').focus();
return;
}
$creation.find('.cp-creation-password-picker').removeClass('active');
$creation.find('.cp-creation-password').removeClass('active');
$creation.focus();
});
// Keyboard shortcuts
$creation.find('#cp-creation-expire-val').keydown(function (e) {
if (e.which === 9) {
e.stopPropagation();
}
});
$creation.find('#cp-creation-expire-unit').keydown(function (e) {
if (e.which === 9 && e.shiftKey) {
e.stopPropagation();
}
});
// Initial values
/*
if (!cfg.owned && typeof cfg.owned !== "undefined") {
$creation.find('#cp-creation-owned').prop('checked', false);
}
UIElements.setExpirationValue(cfg.expire, $creation);
*/
// Create the pad
var getFormValues = function () {
// Type of pad
var ownedVal = $('#cp-creation-owned').is(':checked') ? 1 : 0;
// Life time
var expireVal = 0;
if($('#cp-creation-expire').is(':checked')) {
var unit = 0;
switch ($('#cp-creation-expire-unit').val()) {
case "hour" : unit = 3600; break;
case "day" : unit = 3600 * 24; break;
case "month": unit = 3600 * 24 * 30; break;
default: unit = 0;
}
expireVal = ($('#cp-creation-expire-val').val() || 0) * unit;
}
// Password
var passwordVal = $('#cp-creation-password').is(':checked') ?
$('#cp-creation-password-val').val() : undefined;
var $template = $creation.find('.cp-creation-template-selected');
var templateId = $template.data('id') || undefined;
// Team
var team;
if (teamValue) {
team = privateData.teams[teamValue] || {};
team.id = Number(teamValue);
}
return {
owned: ownedVal,
password: passwordVal,
expire: expireVal,
templateId: templateId,
team: team
};
};
var create = function () {
var val = getFormValues();
common.setAttribute(['general', 'creation', 'owned'], val.owned, function (e) {
if (e) { return void console.error(e); }
});
common.setAttribute(['general', 'creation', 'expire'], val.expire, function (e) {
if (e) { return void console.error(e); }
});
if (val.expire) {
Feedback.send('EXPIRING_PAD-'+val.expire);
}
$creationContainer.remove();
common.createPad(val, function () {
cb();
});
};
var $button = $('