Separate UI elements from cryptpad-common

This commit is contained in:
yflory 2017-11-13 10:23:18 +01:00
parent 354c63bd64
commit dc207393fd
30 changed files with 424 additions and 1840 deletions

View File

@ -2,7 +2,8 @@ define([
'jquery',
'/customize/application_config.js',
'/common/cryptpad-common.js',
], function ($, Config, Cryptpad) {
'/common/common-interface.js',
], function ($, Config, Cryptpad, UI) {
window.APP = {
Cryptpad: Cryptpad,
@ -57,34 +58,6 @@ define([
$('#name').focus();
}
var displayCreateButtons = function () {
var $parent = $('#buttons');
var options = [];
var $container = $('<div>', {'class': 'cp-dropdown-container'}).appendTo($parent);
Config.availablePadTypes.forEach(function (el) {
if (el === 'drive') { return; }
if (!Cryptpad.isLoggedIn() && Config.registeredOnlyTypes &&
Config.registeredOnlyTypes.indexOf(el) !== -1) { return; }
options.push({
tag: 'a',
attributes: {
'class': 'newdoc',
'href': '/' + el + '/',
'target': '_blank'
},
content: Messages['button_new' + el] // Pretty name of the language value
});
});
var dropdownConfig = {
text: Messages.login_makeAPad, // Button initial text
options: options, // Entries displayed in the menu
container: $container
};
var $block = Cryptpad.createDropdown(dropdownConfig);
$block.find('button').addClass('btn').addClass('btn-primary');
$block.appendTo($parent);
};
/* Log in UI */
var Login;
// deferred execution to avoid unnecessary asset loading
@ -144,17 +117,17 @@ define([
switch (err) {
case 'NO_SUCH_USER':
Cryptpad.removeLoadingScreen(function () {
Cryptpad.alert(Messages.login_noSuchUser);
UI.alert(Messages.login_noSuchUser);
});
break;
case 'INVAL_USER':
Cryptpad.removeLoadingScreen(function () {
Cryptpad.alert(Messages.login_invalUser);
UI.alert(Messages.login_invalUser);
});
break;
case 'INVAL_PASS':
Cryptpad.removeLoadingScreen(function () {
Cryptpad.alert(Messages.login_invalPass);
UI.alert(Messages.login_invalPass);
});
break;
default: // UNHANDLED ERROR
@ -166,27 +139,6 @@ define([
}, 100);
});
/* End Log in UI */
var addButtonHandlers = function () {
$('button.register').click(function () {
var username = $('#name').val();
var passwd = $('#password').val();
sessionStorage.login_user = username;
sessionStorage.login_pass = passwd;
document.location.href = '/register/';
});
$('button.gotodrive').click(function () {
document.location.href = '/drive/';
});
$('button#loggedInLogout').click(function () {
$('#user-menu .logout').click();
});
};
displayCreateButtons();
addButtonHandlers();
console.log("ready");
});
});

View File

@ -30,7 +30,6 @@ if (language && map[language]) { req.push('/customize/translations/messages.' +
define(req, function($, Default, Language) {
map.en = 'English';
var defaultLanguage = 'en';
console.log(messages);
if (!Language || language === defaultLanguage || !map[language]) {
messages = $.extend(true, messages, Default);
@ -39,7 +38,6 @@ console.log(messages);
// Add the translated keys to the returned object
messages = $.extend(true, messages, Default, Language);
}
console.log(messages);
messages._languages = map;
messages._languageUsed = language;

View File

@ -488,12 +488,12 @@ define(function () {
out.settings_resetTipsButton = "Réinitialiser les astuces visibles dans CryptDrive";
out.settings_resetTipsDone = "Toutes les astuces sont de nouveau visibles.";
out.settings_thumbnails = "Vignettes";
out.settings_disableThumbnailsAction = "Désactiver la création de vignettes dans CryptDrive";
out.settings_disableThumbnailsDescription = "Des vignettes de vos pads sont automatiquement créées et stockées dans votre navigateur. Vous pouvez désactiver cette fonctionnalité.";
out.settings_thumbnails = "Miniatures";
out.settings_disableThumbnailsAction = "Désactiver la création de miniatures dans CryptDrive";
out.settings_disableThumbnailsDescription = "Des miniatures de vos pads sont automatiquement créées et stockées dans votre navigateur. Vous pouvez désactiver cette fonctionnalité.";
out.settings_resetThumbnailsAction = "Nettoyer";
out.settings_resetThumbnailsDescription = "Nettoyer toutes les vignettes stockées dans votre navigateur.";
out.settings_resetThumbnailsDone = "Toutes les vignettes ont été effacées.";
out.settings_resetThumbnailsDescription = "Nettoyer toutes les miniatures stockées dans votre navigateur.";
out.settings_resetThumbnailsDone = "Toutes les miniatures ont été effacées.";
out.settings_importTitle = "Importer les pads récents de ce navigateur dans votre CryptDrive";
out.settings_import = "Importer";

View File

@ -3,10 +3,12 @@ define([
'/bower_components/chainpad-crypto/crypto.js',
'/common/curve.js',
'/common/common-hash.js',
'/common/common-util.js',
'/customize/messages.js',
'/bower_components/marked/marked.min.js',
'/common/common-realtime.js',
], function ($, Crypto, Curve, Hash, Marked, Realtime) {
], function ($, Crypto, Curve, Hash, Util, Messages, Marked, Realtime) {
var Msg = {
inputs: [],
};
@ -98,7 +100,7 @@ define([
var msg;
if (sender === network.historyKeeper) { return; }
try {
var parsed = common.parsePadUrl(window.location.href);
var parsed = Hash.parsePadUrl(window.location.href);
if (!parsed.hashData) { return; }
var chan = parsed.hashData.channel;
// Decrypt
@ -132,11 +134,11 @@ define([
todo(true);
return;
}
var confirmMsg = common.Messages._getKey('contacts_request', [
common.fixHTML(msgData.displayName)
var confirmMsg = Messages._getKey('contacts_request', [
Util.fixHTML(msgData.displayName)
]);
common.onFriendRequest(confirmMsg, todo);
//common.confirm(confirmMsg, todo, null, true);
//UI.confirm(confirmMsg, todo, null, true);
return;
}
if (msg[0] === "FRIEND_REQ_OK") {
@ -147,12 +149,12 @@ define([
addToFriendList(common, msgData, function (err) {
if (err) {
return void common.onFriendComplete({
logText: common.Messages.contacts_addError,
logText: Messages.contacts_addError,
netfluxId: sender
});
}
common.onFriendComplete({
logText: common.Messages.contacts_added,
logText: Messages.contacts_added,
netfluxId: sender
});
var msg = ["FRIEND_REQ_ACK", chan];
@ -165,7 +167,7 @@ define([
var i = pendingRequests.indexOf(sender);
if (i !== -1) { pendingRequests.splice(i, 1); }
common.onFriendComplete({
logText: common.Messages.contacts_rejected,
logText: Messages.contacts_rejected,
netfluxId: sender
});
common.changeDisplayName(proxy[common.displayNameKey]);
@ -177,12 +179,12 @@ define([
addToFriendList(common, data, function (err) {
if (err) {
return void common.onFriendComplete({
logText: common.Messages.contacts_addError,
logText: Messages.contacts_addError,
netfluxId: sender
});
}
common.onFriendComplete({
logText: common.Messages.contacts_added,
logText: Messages.contacts_added,
netfluxId: sender
});
});
@ -201,7 +203,7 @@ define([
Msg.inviteFromUserlist = function (common, netfluxId) {
var network = common.getNetwork();
var parsed = common.parsePadUrl(window.location.href);
var parsed = Hash.parsePadUrl(window.location.href);
if (!parsed.hashData) { return; }
// Message
var chan = parsed.hashData.channel;

View File

@ -1,7 +1,8 @@
define([
'/customize/application_config.js',
'/customize/messages.js',
], function (AppConfig, Messages) {
'/common/common-interface.js',
], function (AppConfig, Messages, UI) {
var common = {};
common.infiniteSpinnerDetected = false;
@ -44,7 +45,7 @@ define([
infiniteSpinnerHandlers.forEach(function (ish) { ish(); });
// inform the user their session is in a bad state
Cryptpad.confirm(Messages.realtime_unrecoverableError, function (yes) {
UI.confirm(Messages.realtime_unrecoverableError, function (yes) {
if (!yes) { return; }
window.parent.location.reload();
});

View File

@ -4,13 +4,14 @@ define([
'/common/cryptpad-common.js',
'/common/common-util.js',
'/common/common-language.js',
'/common/common-interface.js',
'/common/media-tag.js',
'/common/tippy.min.js',
'/customize/application_config.js',
'css!/common/tippy.css',
], function ($, Config, Cryptpad, Util, Language, MediaTag, Tippy, AppConfig) {
var UI = {};
], function ($, Config, Cryptpad, Util, UI, Language, MediaTag, Tippy, AppConfig) {
var UIElements = {};
var Messages = Cryptpad.Messages;
/**
@ -24,17 +25,14 @@ define([
* - base64ToHex
* - getBlobPathFromHex
* - bytesToMegabytes
* createUserAdminMenu
* - fixHTML
* - createDropdown
*/
UI.updateTags = function (common, href) {
UIElements.updateTags = function (common, href) {
var sframeChan = common.getSframeChannel();
sframeChan.query('Q_TAGS_GET', href || null, function (err, res) {
if (err || res.error) {
if (res.error === 'NO_ENTRY') {
Cryptpad.alert(Messages.tags_noentry);
UI.alert(Messages.tags_noentry);
}
return void console.error(err || res.error);
}
@ -48,7 +46,7 @@ define([
});
};
UI.createButton = function (common, type, rightside, data, callback) {
UIElements.createButton = function (common, type, rightside, data, callback) {
var AppConfig = common.getAppConfig();
var button;
var size = "17px";
@ -93,7 +91,7 @@ define([
target: data.target
};
if (data.filter && !data.filter(file)) {
Cryptpad.log('Invalid avatar (type or size)');
UI.log('Invalid avatar (type or size)');
return;
}
data.FM.handleFile(file, ev);
@ -142,11 +140,11 @@ define([
title: title,
toSave: toSave
}, function () {
Cryptpad.alert(Messages.templateSaved);
UI.alert(Messages.templateSaved);
common.feedback('TEMPLATE_CREATED');
});
};
Cryptpad.prompt(Messages.saveTemplatePrompt, title, todo);
UI.prompt(Messages.saveTemplatePrompt, title, todo);
});
}
break;
@ -162,12 +160,12 @@ define([
.click(common.prepareFeedback(type))
.click(function() {
var msg = common.isLoggedIn() ? Messages.forgetPrompt : Messages.fm_removePermanentlyDialog;
Cryptpad.confirm(msg, function (yes) {
UI.confirm(msg, function (yes) {
if (!yes) { return; }
sframeChan.query('Q_MOVE_TO_TRASH', null, function (err) {
if (err) { return void callback(err); }
var cMsg = common.isLoggedIn() ? Messages.movedToTrash : Messages.deleted;
Cryptpad.alert(cMsg, undefined, true);
UI.alert(cMsg, undefined, true);
callback();
return;
});
@ -220,7 +218,7 @@ define([
title: Messages.tags_title,
})
.click(common.prepareFeedback(type))
.click(function () { UI.updateTags(common, null); });
.click(function () { UIElements.updateTags(common, null); });
break;
default:
button = $('<button>', {
@ -236,7 +234,7 @@ define([
};
// Avatars
UI.displayMediatagImage = function (Common, $tag, cb) {
UIElements.displayMediatagImage = function (Common, $tag, cb) {
if (!$tag.length || !$tag.is('media-tag')) { return void cb('NOT_MEDIATAG'); }
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
@ -267,9 +265,30 @@ define([
});
MediaTag($tag[0]);
};
UI.displayAvatar = function (Common, $container, href, name, cb) {
var emoji_patt = /([\uD800-\uDBFF][\uDC00-\uDFFF])/;
var isEmoji = function (str) {
return emoji_patt.test(str);
};
var emojiStringToArray = function (str) {
var split = str.split(emoji_patt);
var arr = [];
for (var i=0; i<split.length; i++) {
var char = split[i];
if (char !== "") {
arr.push(char);
}
}
return arr;
};
var getFirstEmojiOrCharacter = function (str) {
if (!str || !str.trim()) { return '?'; }
var emojis = emojiStringToArray(str);
return isEmoji(emojis[0])? emojis[0]: str[0];
};
UIElements.displayAvatar = function (Common, $container, href, name, cb) {
var displayDefault = function () {
var text = Cryptpad.getFirstEmojiOrCharacter(name);
var text = getFirstEmojiOrCharacter(name);
var $avatar = $('<span>', {'class': 'cp-avatar-default'}).text(text);
$container.append($avatar);
if (cb) { cb(); }
@ -291,7 +310,7 @@ define([
var $img = $('<media-tag>').appendTo($container);
$img.attr('src', src);
$img.attr('data-crypto-key', 'cryptpad:' + cryptKey);
UI.displayMediatagImage(Common, $img, function (err, $image, img) {
UIElements.displayMediatagImage(Common, $img, function (err, $image, img) {
if (err) { return void console.error(err); }
var w = img.width;
var h = img.height;
@ -317,7 +336,7 @@ define([
update.
*/
var LIMIT_REFRESH_RATE = 30000; // milliseconds
UI.createUsageBar = function (common, cb) {
UIElements.createUsageBar = function (common, cb) {
if (!common.isLoggedIn()) { return cb("NOT_LOGGED_IN"); }
// getPinnedUsage updates common.account.usage, and other values
// so we can just use those and only check for errors
@ -404,7 +423,158 @@ define([
cb(null, $container);
};
UI.createUserAdminMenu = function (Common, config) {
// Create a button with a dropdown menu
// input is a config object with parameters:
// - container (optional): the dropdown container (span)
// - text (optional): the button text value
// - options: array of {tag: "", attributes: {}, content: "string"}
//
// allowed options tags: ['a', 'hr', 'p']
UIElements.createDropdown = function (config) {
if (typeof config !== "object" || !Array.isArray(config.options)) { return; }
var allowedTags = ['a', 'p', 'hr'];
var isValidOption = function (o) {
if (typeof o !== "object") { return false; }
if (!o.tag || allowedTags.indexOf(o.tag) === -1) { return false; }
return true;
};
// Container
var $container = $(config.container);
var containerConfig = {
'class': 'cp-dropdown-container'
};
if (config.buttonTitle) {
containerConfig.title = config.buttonTitle;
}
if (!config.container) {
$container = $('<span>', containerConfig);
}
// Button
var $button = $('<button>', {
'class': ''
}).append($('<span>', {'class': 'cp-dropdown-button-title'}).html(config.text || ""));
/*$('<span>', {
'class': 'fa fa-caret-down',
}).appendTo($button);*/
// Menu
var $innerblock = $('<div>', {'class': 'cp-dropdown-content'});
if (config.left) { $innerblock.addClass('cp-dropdown-left'); }
config.options.forEach(function (o) {
if (!isValidOption(o)) { return; }
$('<' + o.tag + '>', o.attributes || {}).html(o.content || '').appendTo($innerblock);
});
$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 () {
$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);
$innerblock.scrollTop($val.position().top + $innerblock.scrollTop());
}
if (config.feedback) { Cryptpad.feedback(config.feedback); }
};
$container.click(function (e) {
e.stopPropagation();
var state = $innerblock.is(':visible');
$('.cp-dropdown-content').hide();
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.keydown(function (e) {
var $value = $innerblock.find('[data-value].cp-dropdown-element-active');
if (e.which === 38) { // Up
if ($value.length) {
var $prev = $value.prev();
setActive($prev);
}
}
if (e.which === 40) { // Down
if ($value.length) {
var $next = $value.next();
setActive($next);
}
}
if (e.which === 13) { //Enter
if ($value.length) {
$value.click();
hide();
}
}
if (e.which === 27) { // Esc
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;
$button.find('.cp-dropdown-button-title').html(textValue);
};
$container.getValue = function () {
return value || '';
};
}
return $container;
};
UIElements.createUserAdminMenu = function (Common, config) {
var metadataMgr = Common.getMetadataMgr();
var displayNameCls = config.displayNameCls || 'displayName';
@ -419,7 +589,7 @@ define([
if (config.displayNameCls) {
var $userAdminContent = $('<p>');
if (accountName) {
var $userAccount = $('<span>', {'class': 'userAccount'}).append(Messages.user_accountName + ': ' + Cryptpad.fixHTML(accountName));
var $userAccount = $('<span>', {'class': 'userAccount'}).append(Messages.user_accountName + ': ' + Util.fixHTML(accountName));
$userAdminContent.append($userAccount);
$userAdminContent.append($('<br>'));
}
@ -505,7 +675,7 @@ define([
container: config.$initBlock, // optional
feedback: "USER_ADMIN",
};
var $userAdmin = Cryptpad.createDropdown(dropdownConfigUser);
var $userAdmin = UIElements.createDropdown(dropdownConfigUser);
var $displayName = $userAdmin.find('.'+displayNameCls);
@ -528,7 +698,7 @@ define([
$displayName.text(newName || Messages.anonymous);
if (accountName && oldUrl !== url) {
$avatar.html('');
UI.displayAvatar(Common, $avatar, url, newName || Messages.anonymous, function ($img) {
UIElements.displayAvatar(Common, $avatar, url, newName || Messages.anonymous, function ($img) {
oldUrl = url;
if ($img) {
$userAdmin.find('button').addClass('cp-avatar');
@ -577,7 +747,7 @@ define([
// 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
UI.createLanguageSelector = function (common, $container, $initBlock) {
UIElements.createLanguageSelector = function (common, $container, $initBlock) {
var options = [];
var languages = Messages._languages;
var keys = Object.keys(languages).sort();
@ -599,7 +769,7 @@ define([
container: $initBlock, // optional
isSelect: true
};
var $block = Cryptpad.createDropdown(dropdownConfig);
var $block = UIElements.createDropdown(dropdownConfig);
$block.attr('id', 'cp-language-selector');
if ($container) {
@ -612,19 +782,19 @@ define([
};
UI.initFilePicker = function (common, cfg) {
UIElements.initFilePicker = function (common, cfg) {
var onSelect = cfg.onSelect || $.noop;
var sframeChan = common.getSframeChannel();
sframeChan.on("EV_FILE_PICKED", function (data) {
onSelect(data);
});
};
UI.openFilePicker = function (common, types) {
UIElements.openFilePicker = function (common, types) {
var sframeChan = common.getSframeChannel();
sframeChan.event("EV_FILE_PICKER_OPEN", types);
};
UI.openTemplatePicker = function (common) {
UIElements.openTemplatePicker = function (common) {
var metadataMgr = common.getMetadataMgr();
var type = metadataMgr.getMetadataLazy().type;
var sframeChan = common.getSframeChannel();
@ -664,7 +834,7 @@ define([
if (data) {
common.openFilePicker(pickerCfg);
focus = document.activeElement;
Cryptpad.confirm(Messages.useTemplate, onConfirm, {
UI.confirm(Messages.useTemplate, onConfirm, {
ok: Messages.useTemplateOK,
cancel: Messages.useTemplateCancel,
});
@ -672,7 +842,7 @@ define([
});
};
UI.addTooltips = function () {
UIElements.addTooltips = function () {
var MutationObserver = window.MutationObserver;
var delay = typeof(AppConfig.tooltipDelay) === "number" ? AppConfig.tooltipDelay : 500;
var addTippy = function (i, el) {
@ -725,5 +895,5 @@ define([
});
};
return UI;
return UIElements;
});

View File

@ -59,14 +59,14 @@ define([
var anon_rpc;
// import UI elements
common.findCancelButton = UI.findCancelButton;
common.findOKButton = UI.findOKButton;
common.listenForKeys = UI.listenForKeys;
common.stopListening = UI.stopListening;
common.prompt = UI.prompt;
common.confirm = UI.confirm;
common.alert = UI.alert;
common.log = UI.log;
//common.findCancelButton = UI.findCancelButton; REFACTOR
//common.findOKButton = UI.findOKButton;
//common.listenForKeys = UI.listenForKeys;
//common.stopListening = UI.stopListening;
//common.prompt = UI.prompt;
//common.confirm = UI.confirm;
//common.alert = UI.alert;
//common.log = UI.log;
common.warn = UI.warn;
common.spinner = UI.spinner;
common.addLoadingScreen = UI.addLoadingScreen;
@ -83,7 +83,6 @@ define([
// import common utilities for export
common.find = Util.find;
var fixHTML = common.fixHTML = Util.fixHTML;
common.hexToBase64 = Util.hexToBase64;
common.base64ToHex = Util.base64ToHex;
var deduplicateString = common.deduplicateString = Util.deduplicateString;
@ -168,14 +167,6 @@ define([
common.setLanguage = function (l, cb) {
Language.setLanguage(l, null, cb);
};
common.getUserlist = function () {
if (store) {
if (store.getProxy() && store.getProxy().info) {
return store.getProxy().info.userList;
}
}
return;
};
common.getProfileUrl = function () {
if (store && store.getProfile()) {
return store.getProfile().view;
@ -642,7 +633,7 @@ define([
var $content = $('<div>');
$('<b>').text(Messages.selectTemplate).appendTo($content);
$('<p>', {id:"selectTemplate"}).appendTo($content);
common.alert($content.html(), null, true);
UI.alert($content.html(), null, true);
var $p = $('#selectTemplate');
temps.forEach(function (t, i) {
$('<a>', {href: t.href, title: t.title}).text(t.title).click(function (e) {
@ -654,7 +645,7 @@ define([
if (err) { throw new Error(err); }
var p = parsePadUrl(window.location.href);
Crypt.put(p.hash, val, function () {
common.findOKButton().click();
UI.findOKButton().click();
common.removeLoadingScreen();
common.feedback('TEMPLATE_USED');
});
@ -662,7 +653,7 @@ define([
}).appendTo($p);
if (i !== temps.length) { $('<br>').appendTo($p); }
});
common.findOKButton().text(Messages.cancelButton);
UI.findOKButton().text(Messages.cancelButton);
};
// Secure iframes
common.useTemplate = function (href, Crypt, cb) {
@ -791,7 +782,7 @@ define([
getStore().pushData(data, function (e, id) {
if (e) {
if (e === 'E_OVER_LIMIT') {
common.alert(Messages.pinLimitNotPinned, null, true);
UI.alert(Messages.pinLimitNotPinned, null, true);
}
return void cb(e);
}
@ -1239,26 +1230,6 @@ define([
});
};
var emoji_patt = /([\uD800-\uDBFF][\uDC00-\uDFFF])/;
var isEmoji = function (str) {
return emoji_patt.test(str);
};
var emojiStringToArray = function (str) {
var split = str.split(emoji_patt);
var arr = [];
for (var i=0; i<split.length; i++) {
var char = split[i];
if (char !== "") {
arr.push(char);
}
}
return arr;
};
var getFirstEmojiOrCharacter = common.getFirstEmojiOrCharacter = function (str) {
if (!str || !str.trim()) { return '?'; }
var emojis = emojiStringToArray(str);
return isEmoji(emojis[0])? emojis[0]: str[0];
};
common.getMediatagScript = function () {
var origin = window.location.origin;
@ -1311,7 +1282,7 @@ define([
.html(function () {
var text = Messages.download_mt_button + '<br>';
if (title) {
text += '<b>' + common.fixHTML(title) + '</b><br>';
text += '<b>' + Util.fixHTML(title) + '</b><br>';
}
if (size) {
text += '<em>' + Messages._getKey('formattedMB', [sizeMb]) + '</em>';
@ -1427,157 +1398,6 @@ define([
// Create a button with a dropdown menu
// input is a config object with parameters:
// - container (optional): the dropdown container (span)
// - text (optional): the button text value
// - options: array of {tag: "", attributes: {}, content: "string"}
//
// allowed options tags: ['a', 'hr', 'p']
var createDropdown = common.createDropdown = function (config) {
if (typeof config !== "object" || !Array.isArray(config.options)) { return; }
var allowedTags = ['a', 'p', 'hr'];
var isValidOption = function (o) {
if (typeof o !== "object") { return false; }
if (!o.tag || allowedTags.indexOf(o.tag) === -1) { return false; }
return true;
};
// Container
var $container = $(config.container);
var containerConfig = {
'class': 'cp-dropdown-container'
};
if (config.buttonTitle) {
containerConfig.title = config.buttonTitle;
}
if (!config.container) {
$container = $('<span>', containerConfig);
}
// Button
var $button = $('<button>', {
'class': ''
}).append($('<span>', {'class': 'cp-dropdown-button-title'}).html(config.text || ""));
/*$('<span>', {
'class': 'fa fa-caret-down',
}).appendTo($button);*/
// Menu
var $innerblock = $('<div>', {'class': 'cp-dropdown-content'});
if (config.left) { $innerblock.addClass('cp-dropdown-left'); }
config.options.forEach(function (o) {
if (!isValidOption(o)) { return; }
$('<' + o.tag + '>', o.attributes || {}).html(o.content || '').appendTo($innerblock);
});
$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 () {
$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);
$innerblock.scrollTop($val.position().top + $innerblock.scrollTop());
}
if (config.feedback && store) { common.feedback(config.feedback); }
};
$container.click(function (e) {
e.stopPropagation();
var state = $innerblock.is(':visible');
$('.cp-dropdown-content').hide();
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.keydown(function (e) {
var $value = $innerblock.find('[data-value].cp-dropdown-element-active');
if (e.which === 38) { // Up
if ($value.length) {
var $prev = $value.prev();
setActive($prev);
}
}
if (e.which === 40) { // Down
if ($value.length) {
var $next = $value.next();
setActive($next);
}
}
if (e.which === 13) { //Enter
if ($value.length) {
$value.click();
hide();
}
}
if (e.which === 27) { // Esc
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;
$button.find('.cp-dropdown-button-title').html(textValue);
};
$container.getValue = function () {
return value || '';
};
}
return $container;
};
common.getShareHashes = function (secret, cb) {
if (!window.location.hash) {
var hashes = common.getHashes(secret.channel, secret);
@ -1623,7 +1443,7 @@ define([
(parseInt(verArr[0]) === parseInt(storedArr[0]) &&
parseInt(verArr[1]) > parseInt(storedArr[1]));
if (!shouldUpdate) { return; }
//common.alert(Messages._getKey('newVersion', [verArr.join('.')]), null, true);
//UI.alert(Messages._getKey('newVersion', [verArr.join('.')]), null, true);
localStorage[CRYPTPAD_VERSION] = ver;
};
@ -1645,10 +1465,10 @@ define([
delete sessionStorage[newPadPathKey];
}
common.onFriendRequest = function (confirmText, cb) {
common.confirm(confirmText, cb, null, true);
UI.confirm(confirmText, cb, null, true);
};
common.onFriendComplete = function (data) {
common.log(data.logText);
UI.log(data.logText);
};
var proxy;

View File

@ -4,8 +4,9 @@ define([
'/bower_components/chainpad-crypto/crypto.js?v=0.1.5',
'/bower_components/textpatcher/TextPatcher.amd.js',
'/common/userObject.js',
'/common/common-interface.js',
'/common/migrate-user-object.js',
], function ($, Listmap, Crypto, TextPatcher, FO, Migrate) {
], function ($, Listmap, Crypto, TextPatcher, FO, UI, Migrate) {
/*
This module uses localStorage, which is synchronous, but exposes an
asyncronous API. This is so that we can substitute other storage
@ -361,7 +362,7 @@ define([
if (path[0] === 'drive' && path[1] === "migrate" && value === 1) {
rt.network.disconnect();
rt.realtime.abort();
Cryptpad.alert(Cryptpad.Messages.fs_migration, null, true);
UI.alert(Cryptpad.Messages.fs_migration, null, true);
}
});
};

View File

@ -10,6 +10,7 @@ define([
'/common/sframe-common.js',
'/customize/messages.js',
'/common/common-util.js',
'/common/common-interface.js',
'/common/common-thumbnail.js',
'/customize/application_config.js',
@ -28,6 +29,7 @@ define([
SFCommon,
Messages,
Util,
UI,
Thumb,
AppConfig)
{
@ -287,9 +289,9 @@ define([
var onConnectionChange = function (info) {
stateChange(info.state ? STATE.INITIALIZING : STATE.DISCONNECTED);
if (info.state) {
Cryptpad.findOKButton().click();
UI.findOKButton().click();
} else {
Cryptpad.alert(Messages.common_connectionLost, undefined, true);
UI.alert(Messages.common_connectionLost, undefined, true);
}
};
@ -297,7 +299,7 @@ define([
var $export = common.createButton('export', true, {}, function () {
var ext = (typeof(extension) === 'function') ? extension() : extension;
var suggestion = title.suggestTitle('cryptpad-document');
Cryptpad.prompt(Messages.exportPrompt,
UI.prompt(Messages.exportPrompt,
Cryptpad.fixFileName(suggestion) + '.' + ext, function (filename)
{
if (!(typeof(filename) === 'string' && filename)) { return; }
@ -426,13 +428,13 @@ define([
if (infiniteSpinnerModal) { return; }
infiniteSpinnerModal = true;
stateChange(STATE.INFINITE_SPINNER);
Cryptpad.confirm(Messages.realtime_unrecoverableError, function (yes) {
UI.confirm(Messages.realtime_unrecoverableError, function (yes) {
if (!yes) { return; }
common.gotoURL();
});
cpNfInner.chainpad.onSettle(function () {
infiniteSpinnerModal = false;
Cryptpad.findCancelButton().click();
UI.findCancelButton().click();
stateChange(STATE.READY);
onRemote();
});

View File

@ -2,9 +2,12 @@ define([
'jquery',
'/common/modes.js',
'/common/themes.js',
'/common/cryptpad-common.js',
'/customize/messages.js',
'/common/common-ui-elements.js',
'/common/common-hash.js',
'/common/common-util.js',
'/bower_components/textpatcher/TextPatcher.js',
], function ($, Modes, Themes, Cryptpad, TextPatcher) {
], function ($, Modes, Themes, Messages, UIElements, Hash, Util, TextPatcher) {
var module = {};
var cursorToPos = function(cursor, oldText) {
@ -101,7 +104,6 @@ define([
module.create = function (Common, defaultMode, CMeditor) {
var exp = {};
var Messages = Cryptpad.Messages;
var CodeMirror = exp.CodeMirror = CMeditor;
CodeMirror.modeURL = "cm/mode/%N/%N";
@ -211,7 +213,7 @@ define([
isSelect: true,
feedback: 'CODE_LANGUAGE',
};
var $block = exp.$language = Cryptpad.createDropdown(dropdownConfig);
var $block = exp.$language = UIElements.createDropdown(dropdownConfig);
$block.find('button').attr('title', Messages.languageButtonTitle);
$block.find('a').click(function () {
setMode($(this).attr('data-value'), onModeChanged);
@ -248,7 +250,7 @@ define([
initialValue: lastTheme,
feedback: 'CODE_THEME',
};
var $block = exp.$theme = Cryptpad.createDropdown(dropdownConfig);
var $block = exp.$theme = UIElements.createDropdown(dropdownConfig);
$block.find('button').attr('title', Messages.themeButtonTitle);
setTheme(lastTheme, $block);
@ -324,8 +326,8 @@ define([
//var cursor = editor.getCursor();
//var cleanName = data.name.replace(/[\[\]]/g, '');
//var text = '!['+cleanName+']('+data.url+')';
var parsed = Cryptpad.parsePadUrl(data.url);
var hexFileName = Cryptpad.base64ToHex(parsed.hashData.channel);
var parsed = Hash.parsePadUrl(data.url);
var hexFileName = Util.base64ToHex(parsed.hashData.channel);
var src = '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName;
var mt = '<media-tag src="' + src + '" data-crypto-key="cryptpad:' +
parsed.hashData.key + '"></media-tag>';

View File

@ -2,8 +2,10 @@ define([
'jquery',
'/file/file-crypto.js',
'/common/common-thumbnail.js',
'/common/common-interface.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
], function ($, FileCrypto, Thumb) {
], function ($, FileCrypto, Thumb, UI) {
var Nacl = window.nacl;
var module = {};
@ -123,7 +125,7 @@ define([
window.open(origin + $link.attr('href'), '_blank');
});
var title = metadata.name;
Cryptpad.log(Messages._getKey('upload_success', [title]));
UI.log(Messages._getKey('upload_success', [title]));
common.prepareFeedback('upload')();
if (config.onUploaded) {
@ -140,18 +142,18 @@ define([
queue.next();
if (e === 'TOO_LARGE') {
// TODO update table to say too big?
return void Cryptpad.alert(Messages.upload_tooLarge);
return void UI.alert(Messages.upload_tooLarge);
}
if (e === 'NOT_ENOUGH_SPACE') {
// TODO update table to say not enough space?
return void Cryptpad.alert(Messages.upload_notEnoughSpace);
return void UI.alert(Messages.upload_notEnoughSpace);
}
console.error(e);
return void Cryptpad.alert(Messages.upload_serverError);
return void UI.alert(Messages.upload_serverError);
};
onPending = function (cb) {
Cryptpad.confirm(Messages.upload_uploadPending, cb);
UI.confirm(Messages.upload_uploadPending, cb);
};
file.noStore = config.noStore;
@ -161,7 +163,7 @@ define([
console.log('Upload started...');
});
} catch (e) {
Cryptpad.alert(Messages.upload_serverError);
UI.alert(Messages.upload_serverError);
}
};
@ -260,7 +262,7 @@ define([
var onFileDrop = File.onFileDrop = function (file, e) {
if (!common.isLoggedIn()) {
return Cryptpad.alert(common.Messages.upload_mustLogin);
return UI.alert(common.Messages.upload_mustLogin);
}
Array.prototype.slice.call(file).forEach(function (d) {

View File

@ -1,8 +1,10 @@
define([
'jquery',
'/common/common-interface.js',
'/bower_components/chainpad-json-validator/json-ot.js',
'/bower_components/chainpad/chainpad.dist.js',
], function ($, JsonOT) {
], function ($, UI, JsonOT) {
var ChainPad = window.ChainPad;
var History = {};
@ -203,11 +205,11 @@ define([
onClose();
});
$rev.click(function () {
Cryptpad.confirm(Messages.history_restorePrompt, function (yes) {
UI.confirm(Messages.history_restorePrompt, function (yes) {
if (!yes) { return; }
close();
onRevert();
Cryptpad.log(Messages.history_restoreDone);
UI.log(Messages.history_restoreDone);
});
});

View File

@ -16,6 +16,7 @@ define([
'/common/common-realtime.js',
'/common/common-util.js',
'/common/common-thumbnail.js',
'/common/common-interface.js',
'/bower_components/localforage/dist/localforage.min.js'
], function (
$,
@ -24,7 +25,7 @@ define([
CpNfInner,
SFrameChannel,
Title,
UI,
UIElements,
History,
File,
CodeMirror,
@ -34,6 +35,7 @@ define([
CommonRealtime,
Util,
Thumb,
UI,
localForage
) {
// Chainpad Netflux Inner
@ -74,16 +76,16 @@ define([
};
// UI
funcs.createUserAdminMenu = callWithCommon(UI.createUserAdminMenu);
funcs.initFilePicker = callWithCommon(UI.initFilePicker);
funcs.openFilePicker = callWithCommon(UI.openFilePicker);
funcs.openTemplatePicker = callWithCommon(UI.openTemplatePicker);
funcs.displayMediatagImage = callWithCommon(UI.displayMediatagImage);
funcs.displayAvatar = callWithCommon(UI.displayAvatar);
funcs.createButton = callWithCommon(UI.createButton);
funcs.createUsageBar = callWithCommon(UI.createUsageBar);
funcs.updateTags = callWithCommon(UI.updateTags);
funcs.createLanguageSelector = callWithCommon(UI.createLanguageSelector);
funcs.createUserAdminMenu = callWithCommon(UIElements.createUserAdminMenu);
funcs.initFilePicker = callWithCommon(UIElements.initFilePicker);
funcs.openFilePicker = callWithCommon(UIElements.openFilePicker);
funcs.openTemplatePicker = callWithCommon(UIElements.openTemplatePicker);
funcs.displayMediatagImage = callWithCommon(UIElements.displayMediatagImage);
funcs.displayAvatar = callWithCommon(UIElements.displayAvatar);
funcs.createButton = callWithCommon(UIElements.createButton);
funcs.createUsageBar = callWithCommon(UIElements.createUsageBar);
funcs.updateTags = callWithCommon(UIElements.updateTags);
funcs.createLanguageSelector = callWithCommon(UIElements.createLanguageSelector);
// Thumb
funcs.displayThumbnail = callWithCommon(Thumb.displayThumbnail);
@ -357,19 +359,19 @@ define([
};
});
UI.addTooltips();
UIElements.addTooltips();
ctx.sframeChan.on('EV_RT_CONNECT', function () { CommonRealtime.setConnectionState(true); });
ctx.sframeChan.on('EV_RT_DISCONNECT', function () { CommonRealtime.setConnectionState(false); });
ctx.sframeChan.on('Q_INCOMING_FRIEND_REQUEST', function (confirmMsg, cb) {
Cryptpad.confirm(confirmMsg, cb, null, true);
UI.confirm(confirmMsg, cb, null, true);
});
ctx.sframeChan.on('EV_FRIEND_REQUEST', function (data) {
var i = pendingFriends.indexOf(data.netfluxId);
if (i !== -1) { pendingFriends.splice(i, 1); }
Cryptpad.log(data.logText);
UI.log(data.logText);
});
ctx.sframeChan.ready();

View File

@ -1,865 +0,0 @@
define([
'jquery',
'/customize/application_config.js',
'/api/config'
], function ($, Config, ApiConfig) {
var urlArgs = ApiConfig.requireConf.urlArgs;
var Messages = {};
var Bar = {
constants: {},
};
/** Id of the div containing the user list. */
var USER_LIST_CLS = Bar.constants.userlist = 'cryptpad-user-list';
/** Id of the div containing the lag info. */
var LAG_ELEM_CLS = Bar.constants.lag = 'cryptpad-lag';
var LIMIT_ELEM_CLS = Bar.constants.lag = 'cryptpad-limit';
/** The toolbar class which contains the user list, debug link and lag. */
var TOOLBAR_CLS = Bar.constants.toolbar = 'cryptpad-toolbar';
var TOP_CLS = Bar.constants.top = 'cryptpad-toolbar-top';
var LEFTSIDE_CLS = Bar.constants.leftside = 'cryptpad-toolbar-leftside';
var RIGHTSIDE_CLS = Bar.constants.rightside = 'cryptpad-toolbar-rightside';
var HISTORY_CLS = Bar.constants.history = 'cryptpad-toolbar-history';
var SPINNER_CLS = Bar.constants.spinner = 'cryptpad-spinner';
var STATE_CLS = Bar.constants.state = 'cryptpad-state';
var USERNAME_CLS = Bar.constants.username = 'cryptpad-toolbar-username';
var READONLY_CLS = Bar.constants.readonly = 'cryptpad-readonly';
var USERBUTTONS_CONTAINER_CLS = Bar.constants.userButtonsContainer = "cryptpad-userbuttons-container";
var USERLIST_CLS = Bar.constants.userlist = "cryptpad-dropdown-users";
var EDITSHARE_CLS = Bar.constants.editShare = "cryptpad-dropdown-editShare";
var VIEWSHARE_CLS = Bar.constants.viewShare = "cryptpad-dropdown-viewShare";
var SHARE_CLS = Bar.constants.viewShare = "cryptpad-dropdown-share";
var DROPDOWN_CONTAINER_CLS = Bar.constants.dropdownContainer = "cryptpad-dropdown-container";
var DROPDOWN_CLS = Bar.constants.dropdown = "cryptpad-dropdown";
var TITLE_CLS = Bar.constants.title = "cryptpad-title";
var USER_CLS = Bar.constants.userAdmin = "cryptpad-user";
var USERBUTTON_CLS = Bar.constants.changeUsername = "cryptpad-change-username";
var SPINNER_DISAPPEAR_TIME = 3000;
var uid = function () {
return 'cryptpad-uid-' + String(Math.random()).substring(2);
};
var $style;
var connected = false;
var firstConnection = true;
var lagErrors = 0;
var styleToolbar = function ($container, href, version) {
href = href || '/customize/toolbar.css' + (version?('?' + version): '');
$.ajax({
url: href,
dataType: 'text',
success: function (data) {
$container.append($('<style>').text(data));
},
});
};
var createRealtimeToolbar = function ($container, config) {
var $toolbar = $('<div>', {
'class': TOOLBAR_CLS,
id: uid(),
})
.append($('<div>', {'class': TOP_CLS}))
.append($('<div>', {'class': LEFTSIDE_CLS}))
.append($('<div>', {'class': RIGHTSIDE_CLS}))
.append($('<div>', {'class': HISTORY_CLS}));
// The 'notitle' class removes the line added for the title with a small screen
if (!config || typeof config !== "object") {
$toolbar.addClass('notitle');
}
$container.prepend($toolbar);
if (ApiConfig && ApiConfig.requireConf && ApiConfig.requireConf.urlArgs) {
styleToolbar($container, undefined, ApiConfig.requireConf.urlArgs);
} else {
styleToolbar($container);
}
return $toolbar;
};
var createSpinner = function ($container, config) {
if (config.displayed.indexOf('spinner') !== -1) {
var $spin = $('<span>', {'class':SPINNER_CLS});
var $spinner = $('<span>', {
id: uid(),
'class': 'spin fa fa-spinner fa-pulse',
}).appendTo($spin).hide();
$('<span>', {
id: uid(),
'class': 'synced fa fa-check',
title: Messages.synced
}).appendTo($spin);
$container.prepend($spin);
return $spin[0];
}
};
var kickSpinner = function (Cryptpad, realtime, local, spinnerElement) {
if (!spinnerElement) { return; }
$(spinnerElement).find('.spin').show();
$(spinnerElement).find('.synced').hide();
var onSynced = function () {
if (spinnerElement.timeout) { clearTimeout(spinnerElement.timeout); }
spinnerElement.timeout = setTimeout(function () {
$(spinnerElement).find('.spin').hide();
$(spinnerElement).find('.synced').show();
}, local ? 0 : SPINNER_DISAPPEAR_TIME);
};
if (Cryptpad) {
Cryptpad.whenRealtimeSyncs(realtime, onSynced);
return;
}
onSynced();
};
var createUserButtons = function ($userlistElement, config, readOnly, Cryptpad) {
// User list button
if (config.displayed.indexOf('userlist') !== -1) {
if (!config.userData) {
throw new Error("You must provide a `userData` object to display the userlist");
}
var dropdownConfig = {
options: [{
tag: 'p',
attributes: {'class': USERLIST_CLS},
}] // Entries displayed in the menu
};
var $block = Cryptpad.createDropdown(dropdownConfig);
$block.attr('id', 'userButtons');
$userlistElement.append($block);
}
// Share button
if (config.displayed.indexOf('share') !== -1) {
var secret = Cryptpad.find(config, ['share', 'secret']);
var channel = Cryptpad.find(config, ['share', 'channel']);
if (!secret || !channel) {
throw new Error("Unable to display the share button: share.secret and share.channel required");
}
Cryptpad.getRecentPads(function (err, recent) {
var $shareIcon = $('<span>', {'class': 'fa fa-share-alt'});
var $span = $('<span>', {'class': 'large'}).append(' ' +Messages.shareButton);
var hashes = Cryptpad.getHashes(channel, secret);
var options = [];
// If we have a stronger version in drive, add it and add a redirect button
var stronger = recent && Cryptpad.findStronger(null, recent);
if (stronger) {
var parsed = Cryptpad.parsePadUrl(stronger);
hashes.editHash = parsed.hash;
}
if (hashes.editHash) {
options.push({
tag: 'a',
attributes: {title: Messages.editShareTitle, 'class': 'editShare'},
content: '<span class="fa fa-users"></span> ' + Messages.editShare
});
if (stronger) {
// We're in view mode, display the "open editing link" button
options.push({
tag: 'a',
attributes: {
title: Messages.editOpenTitle,
'class': 'editOpen',
href: window.location.pathname + '#' + hashes.editHash,
target: '_blank'
},
content: '<span class="fa fa-users"></span> ' + Messages.editOpen
});
}
options.push({tag: 'hr'});
}
if (hashes.viewHash) {
options.push({
tag: 'a',
attributes: {title: Messages.viewShareTitle, 'class': 'viewShare'},
content: '<span class="fa fa-eye"></span> ' + Messages.viewShare
});
if (hashes.editHash && !stronger) {
// We're in edit mode, display the "open readonly" button
options.push({
tag: 'a',
attributes: {
title: Messages.viewOpenTitle,
'class': 'viewOpen',
href: window.location.pathname + '#' + hashes.viewHash,
target: '_blank'
},
content: '<span class="fa fa-eye"></span> ' + Messages.viewOpen
});
}
}
if (hashes.fileHash) {
options.push({
tag: 'a',
attributes: {title: Messages.viewShareTitle, 'class': 'fileShare'},
content: '<span class="fa fa-eye"></span> ' + Messages.viewShare
});
}
var dropdownConfigShare = {
text: $('<div>').append($shareIcon).append($span).html(),
options: options
};
var $shareBlock = Cryptpad.createDropdown(dropdownConfigShare);
$shareBlock.find('button').attr('id', 'shareButton');
$shareBlock.find('.dropdown-bar-content').addClass(SHARE_CLS).addClass(EDITSHARE_CLS).addClass(VIEWSHARE_CLS);
$userlistElement.append($shareBlock);
if (hashes.editHash) {
$shareBlock.find('a.editShare').click(function () {
var url = window.location.origin + window.location.pathname + '#' + hashes.editHash;
var success = Cryptpad.Clipboard.copy(url);
if (success) { Cryptpad.log(Messages.shareSuccess); }
});
}
if (hashes.viewHash) {
$shareBlock.find('a.viewShare').click(function () {
var url = window.location.origin + window.location.pathname + '#' + hashes.viewHash ;
var success = Cryptpad.Clipboard.copy(url);
if (success) { Cryptpad.log(Messages.shareSuccess); }
});
}
if (hashes.fileHash) {
$shareBlock.find('a.fileShare').click(function () {
var url = window.location.origin + window.location.pathname + '#' + hashes.fileHash ;
var success = Cryptpad.Clipboard.copy(url);
if (success) { Cryptpad.log(Messages.shareSuccess); }
});
}
});
}
};
var createUserList = function ($container, config, readOnly, Cryptpad) {
if (config.displayed.indexOf('userlist') === -1 && config.displayed.indexOf('share') === -1) { return; }
var $userlist = $('<div>', {
'class': USER_LIST_CLS,
id: uid(),
});
createUserButtons($userlist, config, readOnly, Cryptpad);
$container.append($userlist);
return $userlist[0];
};
var getOtherUsers = function(myUserName, userList, userData) {
var i = 0; // duplicates counter
var list = [];
var myUid = userData[myUserName] ? userData[myUserName].uid : undefined;
var uids = [];
userList.forEach(function(user) {
if(user !== myUserName) {
var data = (userData) ? (userData[user] || null) : null;
var userName = (data) ? data.name : null;
var userId = (data) ? data.uid : null;
if (userName && uids.indexOf(userId) === -1 && (!myUid || userId !== myUid)) {
uids.push(userId);
list.push(userName);
} else { i++; }
}
});
return {
list: list,
duplicates: i
};
};
var arrayIntersect = function(a, b) {
return $.grep(a, function(i) {
return $.inArray(i, b) > -1;
});
};
var getViewers = function (n) {
if (!n || !parseInt(n) || n === 0) { return ''; }
if (n === 1) { return '; + ' + Messages.oneViewer; }
return '; + ' + Messages._getKey('viewers', [n]);
};
var checkSynchronizing = function (userList, myUserName, $stateElement) {
var meIdx = userList.indexOf(myUserName);
if (meIdx === -1) {
$stateElement.text(Messages.synchronizing);
return;
}
$stateElement.text('');
};
var updateUserList = function (config, myUserName, userlistElement, userList, userData, readOnly, $userAdminElement) {
// Make sure the elements are displayed
var $userButtons = $(userlistElement).find("#userButtons");
$userButtons.attr('display', 'inline');
if (config.displayed.indexOf('userlist') !== -1) {
var numberOfUsers = userList.length;
// If we are using old pads (readonly unavailable), only editing users are in userList.
// With new pads, we also have readonly users in userList, so we have to intersect with
// the userData to have only the editing users. We can't use userData directly since it
// may contain data about users that have already left the channel.
userList = readOnly === -1 ? userList : arrayIntersect(userList, Object.keys(userData));
// Names of editing users
var others = getOtherUsers(myUserName, userList, userData);
var editUsersNames = others.list;
var duplicates = others.duplicates;
var numberOfEditUsers = userList.length - duplicates;
var numberOfViewUsers = numberOfUsers - numberOfEditUsers - duplicates;
// Number of anonymous editing users
var anonymous = numberOfEditUsers - editUsersNames.length;
// Update the userlist
var $usersTitle = $('<h2>').text(Messages.users);
var $editUsers = $userButtons.find('.' + USERLIST_CLS);
$editUsers.html('').append($usersTitle);
var $editUsersList = $('<pre>');
if (readOnly !== 1) { // Yourself - edit
$editUsers.append('<span class="yourself">' + Messages.yourself + '</span>');
anonymous--;
}
// Editors
$editUsersList.text(editUsersNames.join('\n')); // .text() to avoid XSS
$editUsers.append($editUsersList);
if (anonymous > 0) { // Anonymous editors
var text = anonymous === 1 ? Messages.anonymousUser : Messages.anonymousUsers;
$editUsers.append('<span class="anonymous">' + anonymous + ' ' + text + '</span>');
}
if (numberOfViewUsers > 0) { // Viewers
var viewText = '<span class="viewer">';
if (numberOfEditUsers > 0) {
$editUsers.append('<br>');
viewText += Messages.and + ' ';
}
var viewerText = numberOfViewUsers !== 1 ? Messages.viewers : Messages.viewer;
viewText += numberOfViewUsers + ' ' + viewerText + '</span>';
$editUsers.append(viewText);
}
// Update the buttons
var fa_editusers = '<span class="fa fa-users"></span>';
var fa_viewusers = '<span class="fa fa-eye"></span>';
var viewersText = numberOfViewUsers !== 1 ? Messages.viewers : Messages.viewer;
var editorsText = numberOfEditUsers !== 1 ? Messages.editors : Messages.editor;
var $span = $('<span>', {'class': 'large'}).html(fa_editusers + ' ' + numberOfEditUsers + ' ' + editorsText + '&nbsp;&nbsp; ' + fa_viewusers + ' ' + numberOfViewUsers + ' ' + viewersText);
var $spansmall = $('<span>', {'class': 'narrow'}).html(fa_editusers + ' ' + numberOfEditUsers + '&nbsp;&nbsp; ' + fa_viewusers + ' ' + numberOfViewUsers);
$userButtons.find('.buttonTitle').html('').append($span).append($spansmall);
}
if (config.displayed.indexOf('useradmin') !== -1) {
// Change username in useradmin dropdown
var $userElement = $userAdminElement.find('.' + USERNAME_CLS);
$userElement.show();
if (readOnly === 1) {
$userElement.addClass(READONLY_CLS).text(Messages.readonly);
}
else {
var name = userData[myUserName] && userData[myUserName].name;
if (!name) {
name = Messages.anonymous;
}
$userElement.removeClass(READONLY_CLS).text(name);
}
}
};
var createLagElement = function () {
var $lag = $('<span>', {
'class': LAG_ELEM_CLS,
id: uid(),
});
var $a = $('<span>', {'class': 'cryptpad-lag', id: 'newLag'});
$('<span>', {'class': 'bar1'}).appendTo($a);
$('<span>', {'class': 'bar2'}).appendTo($a);
$('<span>', {'class': 'bar3'}).appendTo($a);
$('<span>', {'class': 'bar4'}).appendTo($a);
return $a[0];
};
var checkLag = function (getLag, lagElement) {
var lag;
if(typeof getLag === "function") {
lag = getLag();
}
var lagLight = $('<div>', {
'class': 'lag'
});
var title;
var $lag = $(lagElement);
if (lag) {
$lag.attr('class', 'cryptpad-lag');
firstConnection = false;
title = Messages.lag + ' : ' + lag + ' ms\n';
if (lag > 30000) {
$lag.addClass('lag0');
title = Messages.redLight;
} else if (lag > 5000) {
$lag.addClass('lag1');
title += Messages.orangeLight;
} else if (lag > 1000) {
$lag.addClass('lag2');
title += Messages.orangeLight;
} else if (lag > 300) {
$lag.addClass('lag3');
title += Messages.greenLight;
} else {
$lag.addClass('lag4');
title += Messages.greenLight;
}
}
else if (!firstConnection) {
$lag.attr('class', 'cryptpad-lag');
// Display the red light at the 2nd failed attemp to get the lag
lagLight.addClass('lag-red');
title = Messages.redLight;
}
if (title) {
$lag.attr('title', title);
}
};
var createLinkToMain = function ($topContainer) {
var $linkContainer = $('<span>', {
'class': "cryptpad-link"
}).appendTo($topContainer);
var $imgTag = $('<img>', {
src: "/customize/cryptofist_mini.png?" + urlArgs,
alt: "Cryptpad"
});
// We need to override the "a" tag action here because it is inside the iframe!
var $aTagSmall = $('<a>', {
href: "/",
title: Messages.header_logoTitle,
'class': "cryptpad-logo"
}).append($imgTag);
var $span = $('<span>').text('CryptPad');
var $aTagBig = $aTagSmall.clone().addClass('large').append($span);
$aTagSmall.addClass('narrow');
var onClick = function (e) {
e.preventDefault();
if (e.ctrlKey) {
window.open('/');
return;
}
window.location = "/";
};
var onContext = function (e) { e.stopPropagation(); };
$aTagBig.click(onClick).contextmenu(onContext);
$aTagSmall.click(onClick).contextmenu(onContext);
$linkContainer.append($aTagSmall).append($aTagBig);
};
var createUserAdmin = function ($topContainer, config, readOnly, lagElement, Cryptpad) {
var $lag = $(lagElement);
var $userContainer = $('<span>', {
'class': USER_CLS
}).appendTo($topContainer);
if (config.displayed.indexOf('state') !== -1) {
var $state = $('<span>', {
'class': STATE_CLS
}).text(Messages.synchronizing).appendTo($userContainer);
}
if (config.displayed.indexOf('lag') !== -1) {
$userContainer.append($lag);
}
if (config.displayed.indexOf('limit') !== -1 && Config.enablePinning) {
var usage;
var $limitIcon = $('<span>', {'class': 'fa fa-exclamation-triangle'});
var $limit = $('<span>', {
'class': LIMIT_ELEM_CLS,
'title': Messages.pinLimitReached
}).append($limitIcon).hide().appendTo($userContainer);
var todo = function (e, overLimit) {
if (e) { return void console.error("Unable to get the pinned usage"); }
if (overLimit) {
var message = Messages.pinLimitReachedAlert;
if (ApiConfig.noSubscriptionButton === true) {
message = Messages.pinLimitReachedAlertNoAccounts;
}
$limit.show().click(function () {
Cryptpad.alert(message, null, true);
});
}
};
Cryptpad.isOverPinLimit(todo);
}
if (config.displayed.indexOf('newpad') !== -1) {
var pads_options = [];
Config.availablePadTypes.forEach(function (p) {
if (p === 'drive') { return; }
pads_options.push({
tag: 'a',
attributes: {
'target': '_blank',
'href': '/' + p + '/',
},
content: Messages.type[p]
});
});
var $plusIcon = $('<span>', {'class': 'fa fa-plus'});
var $newbig = $('<span>', {'class': 'big'}).append(' ' +Messages.newButton);
var $newButton = $('<div>').append($plusIcon).append($newbig);
var dropdownConfig = {
text: $newButton.html(), // Button initial text
options: pads_options, // Entries displayed in the menu
left: true, // Open to the left of the button
};
var $newPadBlock = Cryptpad.createDropdown(dropdownConfig);
$newPadBlock.find('button').attr('title', Messages.newButtonTitle);
$newPadBlock.find('button').attr('id', 'newdoc');
$newPadBlock.appendTo($userContainer);
}
// User dropdown
if (config.displayed.indexOf('useradmin') !== -1) {
var userMenuCfg = {};
if (!config.hideDisplayName) {
userMenuCfg = {
displayNameCls: USERNAME_CLS,
changeNameButtonCls: USERBUTTON_CLS,
};
}
if (readOnly !== 1) {
userMenuCfg.displayName = 1;
userMenuCfg.displayChangeName = 1;
}
var $userAdmin = Cryptpad.createUserAdminMenu(userMenuCfg);
$userAdmin.attr('id', 'userDropdown');
$userContainer.append($userAdmin);
var $userButton = $userAdmin.find('a.' + USERBUTTON_CLS);
var renameAlertOpened;
$userButton.click(function (e) {
e.preventDefault();
e.stopPropagation();
Cryptpad.getLastName(function (err, lastName) {
if (err) { return void console.error("Cannot get last name", err); }
Cryptpad.prompt(Messages.changeNamePrompt, lastName || '', function (newName) {
if (newName === null && typeof(lastName) === "string") { return; }
if (newName === null) { newName = ''; }
Cryptpad.changeDisplayName(newName);
});
});
});
Cryptpad.onDisplayNameChanged(function (newName) {
Cryptpad.findCancelButton().click();
});
}
return $userContainer;
};
var createTitle = function ($container, readOnly, config, Cryptpad) {
var $titleContainer = $('<span>', {
id: 'toolbarTitle',
'class': TITLE_CLS
}).appendTo($container);
if (!config || typeof config !== "object") { return; }
var callback = config.onRename;
var placeholder = config.defaultName;
var suggestName = config.suggestName;
// Buttons
var $text = $('<span>', {
'class': 'title'
}).appendTo($titleContainer);
var $pencilIcon = $('<span>', {
'class': 'pencilIcon',
'title': Messages.clickToEdit
});
if (readOnly === 1 || typeof(Cryptpad) === "undefined") { return $titleContainer; }
var $input = $('<input>', {
type: 'text',
placeholder: placeholder
}).appendTo($titleContainer).hide();
if (readOnly !== 1) {
$text.attr("title", Messages.clickToEdit);
$text.addClass("editable");
var $icon = $('<span>', {
'class': 'fa fa-pencil readonly',
style: 'font-family: FontAwesome;'
});
$pencilIcon.append($icon).appendTo($titleContainer);
}
// Events
$input.on('mousedown', function (e) {
if (!$input.is(":focus")) {
$input.focus();
}
e.stopPropagation();
return true;
});
$input.on('keyup', function (e) {
if (e.which === 13 && connected === true) {
var name = $input.val().trim();
if (name === "") {
name = $input.attr('placeholder');
}
Cryptpad.renamePad(name, function (err, newtitle) {
if (err) { return; }
$text.text(newtitle);
callback(null, newtitle);
$input.hide();
$text.show();
//$pencilIcon.css('display', '');
});
}
else if (e.which === 27) {
$input.hide();
$text.show();
//$pencilIcon.css('display', '');
}
});
var displayInput = function () {
if (connected === false) { return; }
$text.hide();
//$pencilIcon.css('display', 'none');
var inputVal = suggestName() || "";
$input.val(inputVal);
$input.show();
$input.focus();
};
$text.on('click', displayInput);
$pencilIcon.on('click', displayInput);
return $titleContainer;
};
var create = Bar.create = function ($container, myUserName, realtime, getLag, userList, config) {
config = config || {};
var readOnly = (typeof config.readOnly !== "undefined") ? (config.readOnly ? 1 : 0) : -1;
var Cryptpad = config.common;
Messages = Cryptpad.Messages;
config.displayed = config.displayed || [];
var toolbar = createRealtimeToolbar($container, config.title);
var userListElement = createUserList(toolbar.find('.' + LEFTSIDE_CLS), config, readOnly, Cryptpad);
var $titleElement = createTitle(toolbar.find('.' + TOP_CLS), readOnly, config.title, Cryptpad);
var $linkElement = createLinkToMain(toolbar.find('.' + TOP_CLS));
var lagElement = createLagElement();
var $userAdminElement = createUserAdmin(toolbar.find('.' + TOP_CLS), config, readOnly, lagElement, Cryptpad);
var spinner = createSpinner($userAdminElement, config);
var userData = config.userData;
// readOnly = 1 (readOnly enabled), 0 (disabled), -1 (old pad without readOnly mode)
var saveElement;
var loadElement;
var $stateElement = toolbar.find('.' + STATE_CLS);
if (config.ifrw) {
var removeDropdowns = function (e) {
$container.find('.cryptpad-dropdown').hide();
};
var cancelEditTitle = function (e) {
// Now we want to apply the title even if we click somewhere else
if ($(e.target).parents('.' + TITLE_CLS).length || !$titleElement) {
return;
}
if (!$titleElement.find('input').is(':visible')) { return; }
var ev = $.Event("keyup");
ev.which = 13;
$titleElement.find('input').trigger(ev);
/*
$titleElement.find('input').hide();
$titleElement.find('span.title').show();
$titleElement.find('span.pencilIcon').css('display', '');
*/
};
$(config.ifrw).on('click', removeDropdowns);
$(config.ifrw).on('click', cancelEditTitle);
try {
if (config.ifrw.$('iframe').length) {
var innerIfrw = config.ifrw.$('iframe').each(function (i, el) {
$(el.contentWindow).on('click', removeDropdowns);
$(el.contentWindow).on('click', cancelEditTitle);
});
}
} catch (e) {
// empty try catch in case this iframe is problematic
}
}
// Update user list
if (userList) {
if (userData) {
userList.change.push(function (newUserData) {
var users = userList.users;
if (users.indexOf(myUserName) !== -1) { connected = true; }
if (!connected) { return; }
checkSynchronizing(users, myUserName, $stateElement);
updateUserList(config, myUserName, userListElement, users, userData, readOnly, $userAdminElement);
});
} else {
userList.change.push(function () {
var users = userList.users;
if (users.indexOf(myUserName) !== -1) { connected = true; }
if (!connected) { return; }
checkSynchronizing(users, myUserName, $stateElement);
});
}
}
// Display notifications when users are joining/leaving the session
var oldUserData;
if (typeof Cryptpad !== "undefined" && userList) {
var notify = function(type, name, oldname) {
// type : 1 (+1 user), 0 (rename existing user), -1 (-1 user)
if (typeof name === "undefined") { return; }
name = (name === "") ? Messages.anonymous : name;
switch(type) {
case 1:
Cryptpad.log(Messages._getKey("notifyJoined", [name]));
break;
case 0:
oldname = (oldname === "") ? Messages.anonymous : oldname;
Cryptpad.log(Messages._getKey("notifyRenamed", [oldname, name]));
break;
case -1:
Cryptpad.log(Messages._getKey("notifyLeft", [name]));
break;
default:
console.log("Invalid type of notification");
break;
}
};
var userPresent = function (id, user, data) {
if (!(user && user.uid)) {
console.log('no uid');
return 0;
}
if (!data) {
console.log('no data');
return 0;
}
var count = 0;
Object.keys(data).forEach(function (k) {
if (data[k] && data[k].uid === user.uid) { count++; }
});
return count;
};
userList.change.push(function (newdata) {
// Notify for disconnected users
if (typeof oldUserData !== "undefined") {
for (var u in oldUserData) {
// if a user's uid is still present after having left, don't notify
if (userList.users.indexOf(u) === -1) {
var temp = JSON.parse(JSON.stringify(oldUserData[u]));
delete oldUserData[u];
if (userPresent(u, temp, newdata || oldUserData) < 1) {
notify(-1, temp.name);
}
}
}
}
// Update the "oldUserData" object and notify for new users and names changed
if (typeof newdata === "undefined") { return; }
if (typeof oldUserData === "undefined") {
oldUserData = JSON.parse(JSON.stringify(newdata));
return;
}
if (readOnly === 0 && !oldUserData[myUserName]) {
oldUserData = JSON.parse(JSON.stringify(newdata));
return;
}
for (var k in newdata) {
if (k !== myUserName && userList.users.indexOf(k) !== -1) {
if (typeof oldUserData[k] === "undefined") {
// if the same uid is already present in the userdata, don't notify
if (!userPresent(k, newdata[k], oldUserData)) {
notify(1, newdata[k].name);
}
} else if (oldUserData[k].name !== newdata[k].name) {
notify(0, newdata[k].name, oldUserData[k].name);
}
}
}
oldUserData = JSON.parse(JSON.stringify(newdata));
});
}
var ks = function (local) {
return function () {
if (connected) { kickSpinner(Cryptpad, realtime, local, spinner); }
};
};
if (realtime) {
realtime.onPatch(ks());
realtime.onMessage(ks(true));
checkLag(getLag, lagElement);
setInterval(function () {
if (!connected) { return; }
checkLag(getLag, lagElement);
}, 3000);
} else { connected = true; }
var failed = function () {
connected = false;
$stateElement.text(Messages.disconnected);
checkLag(undefined, lagElement);
};
// On log out, remove permanently the realtime elements of the toolbar
Cryptpad.onLogout(function () {
failed();
$userAdminElement.find('#userDropdown').hide();
$(userListElement).hide();
});
return {
failed: failed,
reconnecting: function (userId) {
myUserName = userId;
connected = false;
$stateElement.text(Messages.reconnecting);
checkLag(getLag, lagElement);
},
connected: function () {
connected = true;
}
};
};
return Bar;
});

View File

@ -2,7 +2,9 @@ define([
'jquery',
'/customize/application_config.js',
'/api/config',
], function ($, Config, ApiConfig) {
'/common/common-ui-elements.js',
'/common/common-interface.js'
], function ($, Config, ApiConfig, UIElements, UI) {
var Messages = {};
var Cryptpad;
var Common;
@ -426,7 +428,7 @@ define([
options: options,
feedback: 'SHARE_MENU',
};
var $shareBlock = Cryptpad.createDropdown(dropdownConfigShare);
var $shareBlock = UIElements.createDropdown(dropdownConfigShare);
$shareBlock.find('.cp-dropdown-content').addClass(SHARE_CLS).addClass(EDITSHARE_CLS).addClass(VIEWSHARE_CLS);
$shareBlock.addClass('cp-toolbar-share-button');
$shareBlock.find('button').attr('title', Messages.shareButton);
@ -434,21 +436,21 @@ define([
if (hashes.editHash) {
$shareBlock.find('a.cp-toolbar-share-edit-copy').click(function () {
/*Common.storeLinkToClipboard(false, function (err) {
if (!err) { Cryptpad.log(Messages.shareSuccess); }
if (!err) { UI.log(Messages.shareSuccess); }
});*/
var url = origin + pathname + '#' + hashes.editHash;
var success = Cryptpad.Clipboard.copy(url);
if (success) { Cryptpad.log(Messages.shareSuccess); }
if (success) { UI.log(Messages.shareSuccess); }
});
}
if (hashes.viewHash) {
$shareBlock.find('a.cp-toolbar-share-view-copy').click(function () {
/*Common.storeLinkToClipboard(true, function (err) {
if (!err) { Cryptpad.log(Messages.shareSuccess); }
if (!err) { UI.log(Messages.shareSuccess); }
});*/
var url = origin + pathname + '#' + hashes.viewHash;
var success = Cryptpad.Clipboard.copy(url);
if (success) { Cryptpad.log(Messages.shareSuccess); }
if (success) { UI.log(Messages.shareSuccess); }
});
$shareBlock.find('a.cp-toolbar-share-view-embed').click(function () {
var url = origin + pathname + '#' + hashes.viewHash;
@ -468,12 +470,12 @@ define([
readonly: 'readonly',
value: iframeEmbed,
}).appendTo($tag);
Cryptpad.alert($content.html(), null, true);
UI.alert($content.html(), null, true);
$('#'+iframeId).click(function () {
this.select();
});
//var success = Cryptpad.Clipboard.copy(url);
//if (success) { Cryptpad.log(Messages.shareSuccess); }
//if (success) { UI.log(Messages.shareSuccess); }
});
}
@ -511,7 +513,7 @@ define([
options: options,
feedback: 'FILESHARE_MENU',
};
var $shareBlock = Cryptpad.createDropdown(dropdownConfigShare);
var $shareBlock = UIElements.createDropdown(dropdownConfigShare);
$shareBlock.find('.cp-dropdown-content').addClass(SHARE_CLS);
$shareBlock.addClass('cp-toolbar-share-button');
$shareBlock.find('button').attr('title', Messages.shareButton);
@ -519,7 +521,7 @@ define([
// Add handlers
$shareBlock.find('a.cp-toolbar-share-file-copy').click(function () {
var success = Cryptpad.Clipboard.copy(url);
if (success) { Cryptpad.log(Messages.shareSuccess); }
if (success) { UI.log(Messages.shareSuccess); }
});
$shareBlock.find('a.cp-toolbar-share-file-embed').click(function () {
var $content = $('<div>');
@ -531,7 +533,7 @@ define([
var $tag = $('<p>').text(Messages.fileEmbedTag).appendTo($content);
$('<br>').appendTo($tag);
$tag.append(Cryptpad.dialog.selectable(Common.getMediatagFromHref(url)));
Cryptpad.alert($content[0], null, true);
UI.alert($content[0], null, true);
});
toolbar.$leftside.append($shareBlock);
@ -760,7 +762,7 @@ define([
key = 'pinLimitReachedAlertNoAccounts';
}
$limit.show().click(function () {
Cryptpad.alert(Messages._getKey(key, [encodeURIComponent(window.location.hostname)]), null, true);
UI.alert(Messages._getKey(key, [encodeURIComponent(window.location.hostname)]), null, true);
});
}
};
@ -796,7 +798,7 @@ define([
feedback: /drive/.test(window.location.pathname)?
'DRIVE_NEWPAD': 'NEWPAD',
};
var $newPadBlock = Cryptpad.createDropdown(dropdownConfig);
var $newPadBlock = UIElements.createDropdown(dropdownConfig);
$newPadBlock.find('button').attr('title', Messages.newButtonTitle);
$newPadBlock.find('button').addClass('fa fa-th');
return $newPadBlock;
@ -830,7 +832,7 @@ define([
e.stopPropagation();
var myData = metadataMgr.getMetadata().users[metadataMgr.getNetfluxId()];
var lastName = myData.name;
Cryptpad.prompt(Messages.changeNamePrompt, lastName || '', function (newName) {
UI.prompt(Messages.changeNamePrompt, lastName || '', function (newName) {
if (newName === null && typeof(lastName) === "string") { return; }
if (newName === null) { newName = ''; }
else { Common.feedback('NAME_CHANGED'); }
@ -900,14 +902,14 @@ define([
if (Config.disableUserlistNotifications) { return; }
switch(type) {
case 1:
Cryptpad.log(Messages._getKey("notifyJoined", [name]));
UI.log(Messages._getKey("notifyJoined", [name]));
break;
case 0:
oldname = (!oldname) ? Messages.anonymous : oldname;
Cryptpad.log(Messages._getKey("notifyRenamed", [oldname, name]));
UI.log(Messages._getKey("notifyRenamed", [oldname, name]));
break;
case -1:
Cryptpad.log(Messages._getKey("notifyLeft", [name]));
UI.log(Messages._getKey("notifyLeft", [name]));
break;
default:
console.log("Invalid type of notification");

View File

@ -95,7 +95,7 @@ define([
if (data.error) {
Cryptpad.warn(data.error);
} else {
Cryptpad.log(data.response);
UI.log(data.response);
}
});*/
});

View File

@ -1,14 +1,16 @@
define([
'jquery',
'/common/cryptpad-common.js',
'/customize/messages.js',
'/common/common-util.js',
'/common/common-interface.js',
'/common/hyperscript.js',
'/bower_components/marked/marked.min.js',
'/common/media-tag.js',
], function ($, Cryptpad, h, Marked, MediaTag) {
], function ($, Cryptpad, Messages, Util, UI, h, Marked, MediaTag) {
'use strict';
var UI = {};
var Messages = Cryptpad.Messages;
var m = function (md) {
var d = h('div.cp-app-contacts-content');
@ -163,12 +165,12 @@ define([
});
$(removeHistory).click(function () {
Cryptpad.confirm(Messages.contacts_confirmRemoveHistory, function (yes) {
UI.confirm(Messages.contacts_confirmRemoveHistory, function (yes) {
if (!yes) { return; }
Cryptpad.clearOwnedChannel(data.channel, function (e) {
if (e) {
console.error(e);
Cryptpad.alert(Messages.contacts_removeHistoryServerError);
UI.alert(Messages.contacts_removeHistoryServerError);
return;
}
});
@ -355,8 +357,8 @@ define([
$(remove).click(function (e) {
e.stopPropagation();
Cryptpad.confirm(Messages._getKey('contacts_confirmRemove', [
Cryptpad.fixHTML(data.displayName)
UI.confirm(Messages._getKey('contacts_confirmRemove', [
Util.fixHTML(data.displayName)
]), function (yes) {
if (!yes) { return; }
removeFriend(curvePublic, function (e) {

View File

@ -5,6 +5,8 @@ define([
'json.sortify',
'/common/cryptpad-common.js',
'/common/common-util.js',
'/common/common-ui-elements.js',
'/common/common-interface.js',
'/common/cryptget.js',
'/bower_components/nthen/index.js',
'/common/sframe-common.js',
@ -23,6 +25,8 @@ define([
JSONSortify,
Cryptpad,
Util,
UIElements,
UI,
Cryptget,
nThen,
SFCommon,
@ -76,7 +80,7 @@ define([
var logError = config.logError = function () {
console.error.apply(console, arguments);
};
var log = config.log = Cryptpad.log;
var log = config.log = UI.log;
var localStore = window.cryptpadStore;
APP.store = {};
@ -255,7 +259,7 @@ define([
currentPath = [FILES_DATA];
$tree.hide();
if (Object.keys(files.root).length && !proxy.anonymousAlert) {
Cryptpad.alert(Messages.fm_alert_anonymous, null, true);
UI.alert(Messages.fm_alert_anonymous, null, true);
proxy.anonymousAlert = true;
}
}
@ -1442,7 +1446,7 @@ define([
$button.addClass('cp-app-drive-toolbar-emptytrash');
$button.attr('title', Messages.fc_empty);
$button.click(function () {
Cryptpad.confirm(Messages.fm_emptyTrashDialog, function(res) {
UI.confirm(Messages.fm_emptyTrashDialog, function(res) {
if (!res) { return; }
filesOp.emptyTrash(refresh);
});
@ -1471,9 +1475,9 @@ define([
var onCreated = function (err, info) {
if (err) {
if (err === E_OVER_LIMIT) {
return void Cryptpad.alert(Messages.pinLimitDrive, null, true);
return void UI.alert(Messages.pinLimitDrive, null, true);
}
return void Cryptpad.alert(Messages.fm_error_cantPin);
return void UI.alert(Messages.fm_error_cantPin);
}
APP.newFolder = info.newPath;
refresh();
@ -1549,7 +1553,7 @@ define([
options: options,
feedback: 'DRIVE_NEWPAD_LOCALFOLDER',
};
var $block = Cryptpad.createDropdown(dropdownConfig);
var $block = UIElements.createDropdown(dropdownConfig);
// Custom style:
$block.find('button').addClass('cp-app-drive-toolbar-new');
@ -2593,7 +2597,7 @@ define([
el = filesOp.find(paths[0].path);
getProperties(el, function (e, $prop) {
if (e) { return void logError(e); }
Cryptpad.alert($prop[0], undefined, true);
UI.alert($prop[0], undefined, true);
});
}
else if ($(this).hasClass("cp-app-drive-context-hashtag")) {
@ -2639,7 +2643,7 @@ define([
if (paths.length === 1) {
msg = Messages.fm_removePermanentlyDialog;
}
Cryptpad.confirm(msg, function(res) {
UI.confirm(msg, function(res) {
$(window).focus();
if (!res) { return; }
filesOp.delete(pathsList, refresh);
@ -2653,7 +2657,7 @@ define([
el = filesOp.find(paths[0].path);
getProperties(el, function (e, $prop) {
if (e) { return void logError(e); }
Cryptpad.alert($prop[0], undefined, true);
UI.alert($prop[0], undefined, true);
});
}
else if ($(this).hasClass("cp-app-drive-context-hashtag")) {
@ -2672,10 +2676,10 @@ define([
var path = $(this).data('path');
var onCreated = function (err, info) {
if (err === E_OVER_LIMIT) {
return void Cryptpad.alert(Messages.pinLimitDrive, null, true);
return void UI.alert(Messages.pinLimitDrive, null, true);
}
if (err) {
return void Cryptpad.alert(Messages.fm_error_cantPin);
return void UI.alert(Messages.fm_error_cantPin);
}
APP.newFolder = info.newPath;
refresh();
@ -2700,7 +2704,7 @@ define([
return;
}
if ($(this).hasClass("cp-app-drive-context-empty")) {
Cryptpad.confirm(Messages.fm_emptyTrashDialog, function(res) {
UI.confirm(Messages.fm_emptyTrashDialog, function(res) {
if (!res) { return; }
filesOp.emptyTrash(refresh);
});
@ -2720,7 +2724,7 @@ define([
var name = paths[0].path[paths[0].path.length - 1];
if ($(this).hasClass("cp-app-drive-context-remove")) {
if (paths.length === 1) {
Cryptpad.confirm(Messages.fm_removePermanentlyDialog, function(res) {
UI.confirm(Messages.fm_removePermanentlyDialog, function(res) {
if (!res) { return; }
filesOp.delete([path], refresh);
});
@ -2729,7 +2733,7 @@ define([
var pathsList = [];
paths.forEach(function (p) { pathsList.push(p.path); });
var msg = Messages._getKey("fm_removeSeveralPermanentlyDialog", [paths.length]);
Cryptpad.confirm(msg, function(res) {
UI.confirm(msg, function(res) {
if (!res) { return; }
filesOp.delete(pathsList, refresh);
});
@ -2744,7 +2748,7 @@ define([
name = path[1];
}
}
Cryptpad.confirm(Messages._getKey("fm_restoreDialog", [name]), function(res) {
UI.confirm(Messages._getKey("fm_restoreDialog", [name]), function(res) {
if (!res) { return; }
filesOp.restore(path, refresh);
});
@ -2753,7 +2757,7 @@ define([
if (paths.length !== 1 || path.length !== 4) { return; }
var element = filesOp.find(path.slice(0,3)); // element containing the oldpath
var sPath = stringifyPath(element.path);
Cryptpad.alert('<strong>' + Messages.fm_originalPath + "</strong>:<br>" + sPath, undefined, true);
UI.alert('<strong>' + Messages.fm_originalPath + "</strong>:<br>" + sPath, undefined, true);
}
APP.hideMenu();
});
@ -2802,7 +2806,7 @@ define([
msg = Messages.fm_removePermanentlyDialog;
}
Cryptpad.confirm(msg, function(res) {
UI.confirm(msg, function(res) {
$(window).focus();
if (!res) { return; }
filesOp.delete(paths, refresh);
@ -2996,7 +3000,7 @@ define([
$backupButton.on('click', function() {
var url = window.location.origin + window.location.pathname + '#' + editHash;
var msg = Messages.fm_alert_backupUrl + '<input type="text" readonly="readonly" id="fm_backupUrl" value="'+url+'">';
Cryptpad.alert(msg, undefined, true);
UI.alert(msg, undefined, true);
$('#fm_backupUrl').val(url);
$('#fm_backupUrl').click(function () {
$(this).select();
@ -3025,13 +3029,13 @@ define([
setEditable(false);
if (APP.refresh) { APP.refresh(); }
APP.toolbar.failed();
if (!noAlert) { Cryptpad.alert(Messages.common_connectionLost, undefined, true); }
if (!noAlert) { UI.alert(Messages.common_connectionLost, undefined, true); }
};
var onReconnect = function (info) {
setEditable(true);
if (APP.refresh) { APP.refresh(); }
APP.toolbar.reconnecting(info.myId);
Cryptpad.findOKButton().click();
UI.findOKButton().click();
};
proxy.on('create', function (info) {

View File

@ -49,7 +49,7 @@ define([
});
var firstUser = function () {
Cryptpad.log("You are the first user to visit this board");
UI.log("You are the first user to visit this board");
};
var whenReady = function () {
@ -81,7 +81,7 @@ define([
window.location.hash = info.channel + secret.key;
})
.on('ready', function () {
Cryptpad.log("Ready!");
UI.log("Ready!");
whenReady({
});

View File

@ -6,6 +6,8 @@ define([
'/bower_components/nthen/index.js',
'/common/sframe-common.js',
'/common/common-realtime.js',
'/common/common-util.js',
'/common/common-interface.js',
'/file/file-crypto.js',
'/common/media-tag.js',
@ -24,6 +26,8 @@ define([
nThen,
SFCommon,
CommonRealtime,
Util,
UI,
FileCrypto,
MediaTag)
{
@ -128,7 +132,7 @@ define([
}
$dlButton.addClass('btn btn-success');
var text = Messages.download_mt_button + '<br>';
text += '<b>' + Cryptpad.fixHTML(title) + '</b><br>';
text += '<b>' + Util.fixHTML(title) + '</b><br>';
text += '<em>' + Messages._getKey('formattedMB', [sizeMb]) + '</em>';
$dlButton.html(text);
@ -165,7 +169,7 @@ define([
})
.on('decryptionError', function (e) {
var error = e.originalEvent;
//Cryptpad.alert(error.message);
//UI.alert(error.message);
cb(error.message);
})
.on('decryptionProgress', function (e) {
@ -205,7 +209,7 @@ define([
$dlform.show();
Cryptpad.removeLoadingScreen();
$dllabel.append($('<br>'));
$dllabel.append(Cryptpad.fixHTML(metadata.name));
$dllabel.append(Util.fixHTML(metadata.name));
// don't display the size if you don't know it.
if (typeof(sizeM) === 'number') {
@ -217,7 +221,7 @@ define([
if (decrypting) { return; }
decrypting = true;
displayFile(ev, sizeMb, function (err) {
if (err) { Cryptpad.alert(err); }
if (err) { UI.alert(err); }
});
};
if (typeof(sizeMb) === 'number' && sizeMb < 5) { return void onClick(); }
@ -238,7 +242,7 @@ define([
// we're in upload mode
if (!common.isLoggedIn()) {
return Cryptpad.alert(Messages.upload_mustLogin, function () {
return UI.alert(Messages.upload_mustLogin, function () {
Cryptpad.errorLoadingScreen(Messages.upload_mustLogin);
common.setLoginRedirect(function () {
common.gotoURL('/login/');

View File

@ -1,10 +1,11 @@
define([
'jquery',
'/common/cryptpad-common.js',
'/bower_components/chainpad-listmap/chainpad-listmap.js',
'/common/common-interface.js',
//'/bower_components/chainpad-listmap/chainpad-listmap.js',
//'/common/curve.js',
'less!/invite/main.less',
], function ($, Cryptpad /*, Listmap, Curve*/) {
], function ($, Cryptpad, UI /*, Listmap, Curve*/) {
var Messages = Cryptpad.Messages;
var comingSoon = function () {
return $('<div>', {
@ -38,7 +39,7 @@ define([
if (!info.pubkey) {
Cryptpad.removeLoadingScreen();
Cryptpad.alert('invalid invite');
UI.alert('invalid invite');
return;
}

View File

@ -2,9 +2,10 @@ define([
'jquery',
'/common/cryptpad-common.js',
'/common/login.js',
'/common/common-interface.js',
'less!/bower_components/components-font-awesome/css/font-awesome.min.css',
], function ($, Cryptpad, Login) {
], function ($, Cryptpad, Login, UI) {
$(function () {
var $main = $('#mainBlock');
var Messages = Cryptpad.Messages;
@ -103,21 +104,21 @@ define([
switch (err) {
case 'NO_SUCH_USER':
Cryptpad.removeLoadingScreen(function () {
Cryptpad.alert(Messages.login_noSuchUser, function () {
UI.alert(Messages.login_noSuchUser, function () {
hashing = false;
});
});
break;
case 'INVAL_USER':
Cryptpad.removeLoadingScreen(function () {
Cryptpad.alert(Messages.login_invalUser, function () {
UI.alert(Messages.login_invalUser, function () {
hashing = false;
});
});
break;
case 'INVAL_PASS':
Cryptpad.removeLoadingScreen(function () {
Cryptpad.alert(Messages.login_invalPass, function () {
UI.alert(Messages.login_invalPass, function () {
hashing = false;
});
});

View File

@ -14,8 +14,8 @@ define([
'/poll/render.js',
'/common/diffMarked.js',
'/common/sframe-common-codemirror.js',
'/common/common-ui-elements.js',
'/common/common-thumbnail.js',
'/common/common-interface.js',
'cm/lib/codemirror',
'cm/addon/display/placeholder',
@ -44,8 +44,8 @@ define([
Renderer,
DiffMd,
SframeCM,
SFUI,
Thumb,
UI,
CMeditor)
{
var Messages = Cryptpad.Messages;
@ -118,7 +118,7 @@ define([
var exportFile = function () {
var csv = getCSV();
var suggestion = Title.suggestTitle(Title.defaultTitle);
Cryptpad.prompt(Messages.exportPrompt,
UI.prompt(Messages.exportPrompt,
Cryptpad.fixFileName(suggestion) + '.csv', function (filename) {
if (!(typeof(filename) === 'string' && filename)) { return; }
var blob = new Blob([csv], {type: "application/csv;charset=utf-8"});
@ -495,7 +495,7 @@ define([
var isLocked = span.className && span.className.split(' ').indexOf('fa-lock') !== -1;
if (type === 'row') {
if (isRemove) {
Cryptpad.confirm(Messages.poll_removeOption, function (res) {
UI.confirm(Messages.poll_removeOption, function (res) {
if (!res) { return; }
Render.removeRow(APP.proxy, id, function () {
change();
@ -508,7 +508,7 @@ define([
}
} else if (type === 'col') {
if (isRemove) {
Cryptpad.confirm(Messages.poll_removeUser, function (res) {
UI.confirm(Messages.poll_removeUser, function (res) {
if (!res) { return; }
Render.removeColumn(APP.proxy, id, function () {
change();
@ -1051,12 +1051,12 @@ define([
var onDisconnect = function () {
setEditable(false);
Cryptpad.alert(Messages.common_connectionLost, undefined, true);
UI.alert(Messages.common_connectionLost, undefined, true);
};
var onReconnect = function () {
setEditable(true);
Cryptpad.findOKButton().click();
UI.findOKButton().click();
};
var getHeadingText = function () {

View File

@ -6,6 +6,8 @@ define([
'/common/cryptpad-common.js',
'/bower_components/nthen/index.js',
'/common/sframe-common.js',
'/common/common-util.js',
'/common/common-interface.js',
'/bower_components/marked/marked.min.js',
'cm/lib/codemirror',
'cm/mode/markdown/markdown',
@ -24,6 +26,8 @@ define([
Cryptpad,
nThen,
SFCommon,
Util,
UI,
Marked,
CodeMirror
)
@ -44,7 +48,7 @@ define([
})
.on('decryptionError', function (e) {
var error = e.originalEvent;
Cryptpad.alert(error.message);
UI.alert(error.message);
});
$(window).click(function () {
@ -114,7 +118,7 @@ define([
setValue(newVal, function (err) {
if (err) { return void console.error(err); }
lastVal = newVal;
Cryptpad.log(Messages._getKey('profile_fieldSaved', [newVal || fallbackValue]));
UI.log(Messages._getKey('profile_fieldSaved', [newVal || fallbackValue]));
editing = false;
});
};
@ -158,7 +162,7 @@ define([
var unsafeName = obj.name || '';
console.log(unsafeName);
var name = Cryptpad.fixHTML(unsafeName) || Messages.anonymous;
var name = Util.fixHTML(unsafeName) || Messages.anonymous;
console.log(name);
console.log("Creating invite button");
@ -169,10 +173,10 @@ define([
.addClass('btn btn-success')
.text(Messages.profile_inviteButton)
.click(function () {
Cryptpad.confirm(Messages._getKey('profile_inviteExplanation', [name]), function (yes) {
UI.confirm(Messages._getKey('profile_inviteExplanation', [name]), function (yes) {
if (!yes) { return; }
console.log(obj.curveKey);
Cryptpad.alert("TODO");
UI.alert("TODO");
// TODO create a listmap object using your curve keys
// TODO fill the listmap object with your invite data
// TODO generate link to invite object
@ -280,7 +284,7 @@ define([
$delButton.click(function () {
var old = common.getMetadataMgr().getUserData().avatar;
sframeChan.query("Q_PROFILE_AVATAR_REMOVE", old, function (err, err2) {
if (err || err2) { return void Cryptpad.log(err || err2); }
if (err || err2) { return void UI.log(err || err2); }
delete APP.lm.proxy.avatar;
displayAvatar();
});
@ -297,14 +301,14 @@ define([
var old = common.getMetadataMgr().getUserData().avatar;
var todo = function () {
sframeChan.query("Q_PROFILE_AVATAR_ADD", data.url, function (err, err2) {
if (err || err2) { return void Cryptpad.log(err || err2); }
if (err || err2) { return void UI.log(err || err2); }
APP.lm.proxy.avatar = data.url;
displayAvatar();
});
};
if (old) {
sframeChan.query("Q_PROFILE_AVATAR_REMOVE", old, function (err, err2) {
if (err || err2) { return void Cryptpad.log(err || err2); }
if (err || err2) { return void UI.log(err || err2); }
todo();
});
return;

View File

@ -56,7 +56,7 @@ define([
// TODO
}
return;
//return void Cryptpad.log(Messages._getKey('profile_error', [e])) // TODO
//return void UI.log(Messages._getKey('profile_error', [e])) // TODO
}
obj.profile = {};
obj.profile.edit = Cryptpad.getEditHashFromKeys(secret.channel, secret.keys);

View File

@ -4,9 +4,10 @@ define([
'/common/cryptpad-common.js',
'/common/test.js',
'/common/credential.js', // preloaded for login.js
'/common/common-interface.js',
'less!/bower_components/components-font-awesome/css/font-awesome.min.css',
], function ($, Login, Cryptpad, Test, Cred) {
], function ($, Login, Cryptpad, Test, Cred, UI) {
var Messages = Cryptpad.Messages;
$(function () {
@ -100,21 +101,21 @@ define([
var warning = Messages._getKey('register_passwordTooShort', [
Cred.MINIMUM_PASSWORD_LENGTH
]);
return void Cryptpad.alert(warning, function () {
return void UI.alert(warning, function () {
registering = false;
});
}
if (passwd !== confirmPassword) { // do their passwords match?
return void Cryptpad.alert(Messages.register_passwordsDontMatch);
return void UI.alert(Messages.register_passwordsDontMatch);
}
if (!doesAccept) { // do they accept the terms of service?
return void Cryptpad.alert(Messages.register_mustAcceptTerms);
return void UI.alert(Messages.register_mustAcceptTerms);
}
setTimeout(function () {
Cryptpad.confirm("<h2 class='bright msg'>" + Messages.register_warning + "</h2>",
UI.confirm("<h2 class='bright msg'>" + Messages.register_warning + "</h2>",
function (yes) {
if (!yes) { return; }
@ -135,21 +136,21 @@ define([
switch (err) {
case 'NO_SUCH_USER':
Cryptpad.removeLoadingScreen(function () {
Cryptpad.alert(Messages.login_noSuchUser, function () {
UI.alert(Messages.login_noSuchUser, function () {
registering = false;
});
});
break;
case 'INVAL_USER':
Cryptpad.removeLoadingScreen(function () {
Cryptpad.alert(Messages.login_invalUser, function () {
UI.alert(Messages.login_invalUser, function () {
registering = false;
});
});
break;
case 'INVAL_PASS':
Cryptpad.removeLoadingScreen(function () {
Cryptpad.alert(Messages.login_invalPass, function () {
UI.alert(Messages.login_invalPass, function () {
registering = false;
});
});
@ -159,7 +160,7 @@ define([
var warning = Messages._getKey('register_passwordTooShort', [
Cred.MINIMUM_PASSWORD_LENGTH
]);
Cryptpad.alert(warning, function () {
UI.alert(warning, function () {
registering = false;
});
});
@ -167,7 +168,7 @@ define([
case 'ALREADY_REGISTERED':
// logMeIn should reset registering = false
Cryptpad.removeLoadingScreen(function () {
Cryptpad.confirm(Messages.register_alreadyRegistered, function (yes) {
UI.confirm(Messages.register_alreadyRegistered, function (yes) {
if (!yes) { return; }
proxy.login_name = uname;
@ -240,7 +241,7 @@ define([
$register.click();
window.setTimeout(function () {
Cryptpad.findOKButton().click();
UI.findOKButton().click();
}, 1000);
});
});

View File

@ -4,6 +4,7 @@ define([
'/common/cryptpad-common.js',
'/bower_components/nthen/index.js',
'/common/sframe-common.js',
'/common/common-interface.js',
'/bower_components/file-saver/FileSaver.min.js',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
@ -14,7 +15,8 @@ define([
Toolbar,
Cryptpad,
nThen,
SFCommon
SFCommon,
UI
)
{
var saveAs = window.saveAs;
@ -198,7 +200,7 @@ define([
localStore.put(k, undefined);
}
});
Cryptpad.alert(Messages.settings_resetTipsDone);
UI.alert(Messages.settings_resetTipsDone);
});
return $div;
@ -249,7 +251,7 @@ define([
$button.click(function () {
sframeChan.query("Q_THUMBNAIL_CLEAR", null, function (err) {
if (err) { return void console.error("Cannot clear localForage"); }
Cryptpad.alert(Messages.settings_resetThumbnailsDone);
UI.alert(Messages.settings_resetThumbnailsDone);
});
});
@ -268,7 +270,7 @@ define([
var sjson = JSON.stringify(data);
var name = displayName || accountName || Messages.anonymous;
var suggestion = name + '-' + new Date().toDateString();
Cryptpad.prompt(Cryptpad.Messages.exportPrompt,
UI.prompt(Cryptpad.Messages.exportPrompt,
Cryptpad.fixFileName(suggestion) + '.json', function (filename) {
if (!(typeof(filename) === 'string' && filename)) { return; }
var blob = new Blob([sjson], {type: "application/json;charset=utf-8"});
@ -314,14 +316,14 @@ define([
.text(Messages.settings_resetButton).appendTo($div);
$button.click(function () {
Cryptpad.prompt(Messages.settings_resetPrompt, "", function (val) {
UI.prompt(Messages.settings_resetPrompt, "", function (val) {
if (val !== "I love CryptPad") {
Cryptpad.alert(Messages.settings_resetError);
UI.alert(Messages.settings_resetError);
return;
}
sframeChan.query("Q_SETTINGS_DRIVE_RESET", null, function (err) {
if (err) { return void console.error(err); }
Cryptpad.alert(Messages.settings_resetDone);
UI.alert(Messages.settings_resetDone);
});
}, undefined, true);
});
@ -392,7 +394,7 @@ define([
$button.click(function () {
Cryptpad.confirm(Messages.settings_logoutEverywhereConfirm, function (yes) {
UI.confirm(Messages.settings_logoutEverywhereConfirm, function (yes) {
if (!yes) { return; }
$spinner.show();
$ok.hide();
@ -424,14 +426,14 @@ define([
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).hide().appendTo($div);
$button.click(function () {
Cryptpad.confirm(Messages.settings_importConfirm, function (yes) {
UI.confirm(Messages.settings_importConfirm, function (yes) {
if (!yes) { return; }
$spinner.show();
$ok.hide();
sframeChan.query('Q_SETTINGS_IMPORT_LOCAL', null, function () {
$spinner.hide();
$ok.show();
Cryptpad.alert(Messages.settings_importDone);
UI.alert(Messages.settings_importDone);
});
}, undefined, true);
});

View File

@ -1,528 +0,0 @@
define([
'jquery',
'/common/cryptpad-common.js',
'/common/hyperscript.js',
'/bower_components/marked/marked.min.js',
'/common/media-tag.js',
], function ($, Cryptpad, h, Marked, MediaTag) {
'use strict';
var UI = {};
var Messages = Cryptpad.Messages;
var m = function (md) {
var d = h('div.cp-app-contacts-content');
try {
d.innerHTML = Marked(md || '');
var $d = $(d);
// remove potentially malicious elements
$d.find('script, iframe, object, applet, video, audio').remove();
// activate media-tags
$d.find('media-tag').each(function (i, e) { MediaTag(e); });
} catch (e) {
console.error(md);
console.error(e);
}
return d;
};
var dataQuery = function (curvePublic) {
return '[data-key="' + curvePublic + '"]';
};
var initChannel = function (state, curvePublic, info) {
console.log('initializing channel for [%s]', curvePublic);
state.channels[curvePublic] = {
messages: [],
HEAD: info.lastKnownHash,
TAIL: null,
};
};
UI.create = function (messenger, $userlist, $messages, common) {
var origin = common.getMetadataMgr().getPrivateData().origin;
var state = window.state = {
active: '',
};
state.channels = {};
var displayNames = state.displayNames = {};
var avatars = state.avatars = {};
var setActive = function (curvePublic) {
state.active = curvePublic;
};
var isActive = function (curvePublic) {
return curvePublic === state.active;
};
var find = {};
find.inList = function (curvePublic) {
return $userlist.find(dataQuery(curvePublic));
};
var notify = function (curvePublic) {
find.inList(curvePublic).addClass('cp-app-contacts-notify');
};
var unnotify = function (curvePublic) {
find.inList(curvePublic).removeClass('cp-app-contacts-notify');
};
var markup = {};
markup.message = function (msg) {
var curvePublic = msg.author;
var name = displayNames[msg.author];
return h('div.cp-app-contacts-message', {
title: msg.time? new Date(msg.time).toLocaleString(): '?',
'data-key': curvePublic,
}, [
name? h('div.cp-app-contacts-sender', name): undefined,
m(msg.text),
]);
};
var getChat = function (curvePublic) {
return $messages.find(dataQuery(curvePublic));
};
var normalizeLabels = function ($messagebox) {
$messagebox.find('div.cp-app-contacts-message').toArray().reduce(function (a, b) {
var $b = $(b);
if ($(a).data('key') === $b.data('key')) {
$b.find('.cp-app-contacts-sender').hide();
return a;
}
return b;
}, []);
};
markup.chatbox = function (curvePublic, data) {
var moreHistory = h('span.cp-app-contacts-more-history.fa.fa-history', {
title: Messages.contacts_fetchHistory,
});
var displayName = data.displayName;
var fetching = false;
var $moreHistory = $(moreHistory).click(function () {
if (fetching) { return; }
// get oldest known message...
var channel = state.channels[curvePublic];
if (channel.exhausted) {
return void $moreHistory.addClass('cp-app-contacts-faded');
}
console.log('getting history');
var sig = channel.TAIL || channel.HEAD;
fetching = true;
var $messagebox = $(getChat(curvePublic)).find('.cp-app-contacts-messages');
messenger.getMoreHistory(curvePublic, sig, 10, function (e, history) {
fetching = false;
if (e) { return void console.error(e); }
if (history.length === 0) {
channel.exhausted = true;
return;
}
history.forEach(function (msg) {
if (channel.exhausted) { return; }
if (msg.sig) {
if (msg.sig === channel.TAIL) {
console.error('No more messages to fetch');
channel.exhausted = true;
console.log(channel);
return void $moreHistory.addClass('cp-app-contacts-faded');
} else {
channel.TAIL = msg.sig;
}
} else {
return void console.error('expected signature');
}
if (msg.type !== 'MSG') { return; }
// FIXME Schlameil the painter (performance does not scale well)
if (channel.messages.some(function (old) {
return msg.sig === old.sig;
})) { return; }
channel.messages.unshift(msg);
var el_message = markup.message(msg);
$messagebox.prepend(el_message);
});
normalizeLabels($messagebox);
});
});
var removeHistory = h('span.cp-app-contacts-remove-history.fa.fa-eraser', {
title: Messages.contacts_removeHistoryTitle
});
$(removeHistory).click(function () {
Cryptpad.confirm(Messages.contacts_confirmRemoveHistory, function (yes) {
if (!yes) { return; }
Cryptpad.clearOwnedChannel(data.channel, function (e) {
if (e) {
console.error(e);
Cryptpad.alert(Messages.contacts_removeHistoryServerError);
return;
}
});
});
});
var avatar = h('div.cp-avatar');
var header = h('div.cp-app-contacts-header', [
avatar,
moreHistory,
removeHistory,
]);
var messages = h('div.cp-app-contacts-messages');
var input = h('textarea', {
placeholder: Messages.contacts_typeHere
});
var sendButton = h('button.btn.btn-primary.fa.fa-paper-plane', {
title: Messages.contacts_send,
});
var rightCol = h('span.cp-app-contacts-right-col', [
h('span.cp-app-contacts-name', displayName),
]);
var $avatar = $(avatar);
if (data.avatar && avatars[data.avatar]) {
$avatar.append(avatars[data.avatar]).append(rightCol);
} else {
common.displayAvatar($avatar, data.avatar, data.displayName, function ($img) {
if (data.avatar && $img) {
avatars[data.avatar] = $img[0].outerHTML;
}
$(rightCol).insertAfter($avatar);
});
}
var sending = false;
var send = function (content) {
if (typeof(content) !== 'string' || !content.trim()) { return; }
if (sending) { return false; }
sending = true;
messenger.sendMessage(curvePublic, content, function (e) {
if (e) {
// failed to send
return void console.error('failed to send');
}
input.value = '';
sending = false;
console.log('sent successfully');
var $messagebox = $(messages);
var height = $messagebox[0].scrollHeight;
$messagebox.scrollTop(height);
});
};
var onKeyDown = function (e) {
// ignore anything that isn't 'enter'
if (e.keyCode !== 13) { return; }
// send unless they're holding a ctrl-key or shift
if (!e.ctrlKey && !e.shiftKey) {
send(this.value);
return false;
}
// insert a newline if they're holding either
var val = this.value;
var start = this.selectionState;
var end = this.selectionEnd;
if (![start,end].some(function (x) {
return typeof(x) !== 'number';
})) {
this.value = val.slice(0, start) + '\n' + val.slice(end);
this.selectionStart = this.selectionEnd = start + 1;
} else if (document.selection && document.selection.createRange) {
this.focus();
var range = document.selection.createRange();
range.text = '\r\n';
range.collapse(false);
range.select();
}
return false;
};
$(input).on('keydown', onKeyDown);
$(sendButton).click(function () { send(input.value); });
return h('div.cp-app-contacts-chat', {
'data-key': curvePublic,
}, [
header,
messages,
h('div.cp-app-contacts-input', [
input,
sendButton,
]),
]);
};
var hideInfo = function () {
$messages.find('.cp-app-contacts-info').hide();
};
var updateStatus = function (curvePublic) {
var $status = find.inList(curvePublic).find('.cp-app-contacts-status');
// FIXME this stopped working :(
messenger.getStatus(curvePublic, function (e, online) {
// if error maybe you shouldn't display this friend...
if (e) {
find.inList(curvePublic).hide();
getChat(curvePublic).hide();
return void console.error(curvePublic, e);
}
if (online) {
return void $status
.removeClass('cp-app-contacts-offline').addClass('cp-app-contacts-online');
}
$status.removeClass('cp-app-contacts-online').addClass('cp-app-contacts-offline');
});
};
var display = function (curvePublic) {
var channel = state.channels[curvePublic];
var lastMsg = channel.messages.slice(-1)[0];
if (lastMsg) {
channel.HEAD = lastMsg.sig;
messenger.setChannelHead(curvePublic, channel.HEAD, function (e) {
if (e) { console.error(e); }
});
}
setActive(curvePublic);
unnotify(curvePublic);
var $chat = getChat(curvePublic);
hideInfo();
$messages.find('div.cp-app-contacts-chat[data-key]').hide();
if ($chat.length) {
var $chat_messages = $chat.find('div.cp-app-contacts-message');
if (!$chat_messages.length) {
var $more = $chat.find('.cp-app-contacts-more-history');
$more.click();
}
return void $chat.show();
}
messenger.getFriendInfo(curvePublic, function (e, info) {
if (e) { return void console.error(e); } // FIXME
var chatbox = markup.chatbox(curvePublic, info);
$messages.append(chatbox);
});
};
var removeFriend = function (curvePublic) {
messenger.removeFriend(curvePublic, function (e /*, removed */) {
if (e) { return void console.error(e); }
find.inList(curvePublic).remove();
//console.log(removed);
});
};
markup.friend = function (data) {
var curvePublic = data.curvePublic;
var friend = h('div.cp-app-contacts-friend.cp-avatar', {
'data-key': curvePublic,
});
var remove = h('span.cp-app-contacts-remove.fa.fa-user-times', {
title: Messages.contacts_remove
});
var status = h('span.cp-app-contacts-status');
var rightCol = h('span.cp-app-contacts-right-col', [
h('span.cp-app-contacts-name', [data.displayName]),
remove,
]);
var $friend = $(friend)
.click(function () {
display(curvePublic);
})
.dblclick(function () {
if (data.profile) { window.open(origin + '/profile/#' + data.profile); }
});
$(remove).click(function (e) {
e.stopPropagation();
Cryptpad.confirm(Messages._getKey('contacts_confirmRemove', [
Cryptpad.fixHTML(data.displayName)
]), function (yes) {
if (!yes) { return; }
removeFriend(curvePublic, function (e) {
if (e) { return void console.error(e); }
});
// TODO remove friend from userlist ui
// FIXME seems to trigger EJOINED from netflux-websocket (from server);
// (tried to join a channel in which you were already present)
}, undefined, true);
});
if (data.avatar && avatars[data.avatar]) {
$friend.append(avatars[data.avatar]);
$friend.append(rightCol);
} else {
common.displayAvatar($friend, data.avatar, data.displayName, function ($img) {
if (data.avatar && $img) {
avatars[data.avatar] = $img[0].outerHTML;
}
$friend.append(rightCol);
});
}
$friend.append(status);
return $friend;
};
var isBottomedOut = function ($elem) {
return ($elem[0].scrollHeight - $elem.scrollTop() === $elem.outerHeight());
};
var initializing = true;
messenger.on('message', function (message) {
if (!initializing) { Cryptpad.notify(); }
var curvePublic = message.curve;
var name = displayNames[curvePublic];
var chat = getChat(curvePublic, name);
console.log(message);
var el_message = markup.message(message);
state.channels[curvePublic].messages.push(message);
var $chat = $(chat);
if (!$chat.length) {
console.error("Got a message but the chat isn't open");
}
var $messagebox = $chat.find('.cp-app-contacts-messages');
var shouldScroll = isBottomedOut($messagebox);
$messagebox.append(el_message);
if (shouldScroll) {
$messagebox.scrollTop($messagebox.outerHeight());
}
normalizeLabels($messagebox);
var channel = state.channels[curvePublic];
if (!channel) {
console.error('expected channel [%s] to be open', curvePublic);
return;
}
if (isActive(curvePublic)) {
channel.HEAD = message.sig;
messenger.setChannelHead(curvePublic, message.sig, function (e) {
if (e) { return void console.error(e); }
});
return;
}
var lastMsg = channel.messages.slice(-1)[0];
if (lastMsg.sig !== channel.HEAD) {
return void notify(curvePublic);
}
unnotify(curvePublic);
});
messenger.on('join', function (curvePublic, channel) {
channel = channel;
updateStatus(curvePublic);
});
messenger.on('leave', function (curvePublic, channel) {
channel = channel;
updateStatus(curvePublic);
});
// change in your friend list
messenger.on('update', function (info, curvePublic) {
var name = displayNames[curvePublic] = info.displayName;
// update label in friend list
find.inList(curvePublic).find('.cp-app-contacts-name').text(name);
// update title bar and messages
$messages.find(dataQuery(curvePublic) + ' .cp-app-contacts-header ' +
'.cp-app-contacts-name, div.cp-app-contacts-message'+
dataQuery(curvePublic) + ' div.cp-app-contacts-sender').text(name).text(name);
});
var connectToFriend = function (curvePublic, cb) {
messenger.getFriendInfo(curvePublic, function (e, info) {
if (e) { return void console.error(e); }
var name = displayNames[curvePublic] = info.displayName;
initChannel(state, curvePublic, info);
var chatbox = markup.chatbox(curvePublic, info);
$(chatbox).hide();
$messages.append(chatbox);
var friend = markup.friend(info, name);
$userlist.append(friend);
messenger.openFriendChannel(curvePublic, function (e) {
if (e) { return void console.error(e); }
cb();
updateStatus(curvePublic);
// don't add friends that are already in your userlist
//if (friendExistsInUserList(k)) { return; }
});
});
};
messenger.on('friend', function (curvePublic) {
console.log('new friend: ', curvePublic);
//console.error("TODO redraw user list");
//console.error("TODO connect to new friend");
// FIXME this doesn't work right now because the friend hasn't been fully added?
connectToFriend(curvePublic, function () {
//console.error('connected');
});
});
messenger.on('unfriend', function (curvePublic) {
console.log('unfriend', curvePublic);
find.inList(curvePublic).remove();
console.error('TODO remove chatbox');
console.error('TODO show something if that chatbox was active');
});
Cryptpad.onDisplayNameChanged(function () {
//messenger.checkNewFriends();
messenger.updateMyData();
});
// FIXME dirty hack
messenger.getMyInfo(function (e, info) {
displayNames[info.curvePublic] = info.displayName;
});
messenger.getFriendList(function (e, keys) {
var count = keys.length + 1;
var ready = function () {
count--;
if (count === 0) {
initializing = false;
Cryptpad.removeLoadingScreen();
}
};
ready();
keys.forEach(function (curvePublic) {
connectToFriend(curvePublic, ready);
});
});
};
return UI;
});

View File

@ -7,6 +7,7 @@ define([
'/slide/slide.js',
'/common/sframe-app-framework.js',
'/common/common-util.js',
'/common/common-interface.js',
'cm/lib/codemirror',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
@ -48,6 +49,7 @@ define([
Slide,
Framework,
Util,
UI,
CMeditor)
{
window.CodeMirror = CMeditor;
@ -104,7 +106,7 @@ define([
Slide.update(editor.getValue(), true);
$print.html($content.html());
// TODO use translation key
Cryptpad.confirm("Are you sure you want to print?", function (yes) {
UI.confirm("Are you sure you want to print?", function (yes) {
if (yes) {
window.focus();
window.print();
@ -224,7 +226,7 @@ define([
slideOptionsTmp.style = '';
parseLess(mkLess(less), function (err, css) {
if (err) {
Cryptpad.alert(
UI.alert(
'<strong>' + Messages.slide_invalidLess + '</strong>' +
'<br>' +
'<pre class="cp-slide-css-error">' + Util.fixHTML(
@ -245,14 +247,14 @@ define([
updateLocalOptions(slideOptionsTmp);
}
$container.remove();
Cryptpad.stopListening(h);
UI.stopListening(h);
};
var todoCancel = function () {
$container.remove();
Cryptpad.stopListening(h);
UI.stopListening(h);
};
h = Cryptpad.listenForKeys(todo, todoCancel);
h = UI.listenForKeys(todo, todoCancel);
var $nav = $('<nav>').appendTo($div);
$('<button>', {'class': 'cancel'}).text(Messages.cancelButton).appendTo($nav).click(todoCancel);

View File

@ -10,7 +10,7 @@ define([
'/common/cryptget.js',
'/bower_components/nthen/index.js',
'/common/sframe-common.js',
'/common/common-ui-elements.js',
'/common/common-interface.js',
'/api/config',
'/common/common-realtime.js',
'/customize/pages.js',
@ -37,7 +37,7 @@ define([
Cryptget,
nThen,
SFCommon,
SFUI,
UI,
ApiConfig,
CommonRealtime,
Pages,
@ -228,7 +228,7 @@ define([
var saveImage = APP.saveImage = function () {
var defaultName = "pretty-picture.png";
Cryptpad.prompt(Messages.exportPrompt, defaultName, function (filename) {
UI.prompt(Messages.exportPrompt, defaultName, function (filename) {
if (!(typeof(filename) === 'string' && filename)) { return; }
$canvas[0].toBlob(function (blob) {
saveAs(blob, filename);
@ -436,7 +436,7 @@ define([
if (common.isLoggedIn()) {
common.createButton('savetodrive', true, {}, function () {})
.click(function () {
Cryptpad.prompt(Messages.exportPrompt, document.title + '.png',
UI.prompt(Messages.exportPrompt, document.title + '.png',
function (name) {
if (name === null || !name.trim()) { return; }
APP.upload(name);
@ -592,16 +592,16 @@ define([
// inform of network disconnect
setEditable(false);
toolbar.failed();
Cryptpad.alert(Messages.common_connectionLost, undefined, true);
UI.alert(Messages.common_connectionLost, undefined, true);
};
config.onConnectionChange = function (info) {
setEditable(info.state);
if (info.state) {
initializing = true;
Cryptpad.findOKButton().click();
UI.findOKButton().click();
} else {
Cryptpad.alert(Messages.common_connectionLost, undefined, true);
UI.alert(Messages.common_connectionLost, undefined, true);
}
};
@ -612,7 +612,7 @@ define([
cpNfInner.onInfiniteSpinner(function () {
setEditable(false);
Cryptpad.confirm(Messages.realtime_unrecoverableError, function (yes) {
UI.confirm(Messages.realtime_unrecoverableError, function (yes) {
if (!yes) { return; }
common.gotoURL();
});