define([
'jquery',
'/customize/application_config.js',
'/api/config',
], function ($, Config, ApiConfig) {
var Messages = {};
var Cryptpad;
var Common;
var Bar = {
constants: {},
};
var SPINNER_DISAPPEAR_TIME = 1000;
// Toolbar parts
var TOOLBAR_CLS = Bar.constants.toolbar = 'cp-toolbar';
var TOP_CLS = Bar.constants.top = 'cp-toolbar-top';
var LEFTSIDE_CLS = Bar.constants.leftside = 'cp-toolbar-leftside';
var RIGHTSIDE_CLS = Bar.constants.rightside = 'cp-toolbar-rightside';
var DRAWER_CLS = Bar.constants.drawer = 'cp-toolbar-drawer-content';
var HISTORY_CLS = Bar.constants.history = 'cp-toolbar-history';
// Userlist
var USERLIST_CLS = Bar.constants.userlist = "cp-toolbar-users";
var EDITSHARE_CLS = Bar.constants.editShare = "cp-toolbar-share-edit";
var VIEWSHARE_CLS = Bar.constants.viewShare = "cp-toolbar-share-view";
var SHARE_CLS = Bar.constants.viewShare = "cp-toolbar-share";
// Top parts
var USER_CLS = Bar.constants.userAdmin = "cp-toolbar-user";
var SPINNER_CLS = Bar.constants.spinner = 'cp-toolbar-spinner';
var LIMIT_CLS = Bar.constants.limit = 'cp-toolbar-limit';
var TITLE_CLS = Bar.constants.title = "cp-toolbar-title";
var NEWPAD_CLS = Bar.constants.newpad = "cp-toolbar-new";
var LINK_CLS = Bar.constants.link = "cp-toolbar-link";
// User admin menu
var USERADMIN_CLS = Bar.constants.user = 'cp-toolbar-user-dropdown';
var USERNAME_CLS = Bar.constants.username = 'cp-toolbar-user-name';
/*var READONLY_CLS = */Bar.constants.readonly = 'cp-toolbar-readonly';
var USERBUTTON_CLS = Bar.constants.changeUsername = "cp-toolbar-user-rename";
// Create the toolbar element
var uid = function () {
return 'cp-toolbar-uid-' + String(Math.random()).substring(2);
};
var createRealtimeToolbar = function (config) {
if (!config.$container) { return; }
var $container = config.$container;
var isEmbed = Bar.isEmbed = config.metadataMgr.getPrivateData().isEmbed;
if (isEmbed) {
$container.hide();
}
var $toolbar = $('
', {'class': HISTORY_CLS}));
var $rightside = $toolbar.find('.'+RIGHTSIDE_CLS);
if (!config.hideDrawer) {
var $drawerContent = $('
', {
'class': DRAWER_CLS,
'tabindex': 1
}).appendTo($rightside).hide();
var $drawer = Common.createButton('more', true).appendTo($rightside);
$drawer.click(function () {
$drawerContent.toggle();
$drawer.removeClass('cp-toolbar-button-active');
if ($drawerContent.is(':visible')) {
$drawer.addClass('cp-toolbar-button-active');
$drawerContent.focus();
}
});
var onBlur = function (e) {
if (e.relatedTarget) {
if ($(e.relatedTarget).is('.cp-toolbar-drawer-button')) { return; }
if ($(e.relatedTarget).parents('.'+DRAWER_CLS).length) {
$(e.relatedTarget).blur(onBlur);
return;
}
}
$drawer.removeClass('cp-toolbar-button-active');
$drawerContent.hide();
};
$drawerContent.blur(onBlur);
}
// The 'notitle' class removes the line added for the title with a small screen
if (!config.title || typeof config.title !== "object") {
$toolbar.addClass('cp-toolbar-notitle');
}
$container.prepend($toolbar);
$container.on('drop dragover', function (e) {
e.preventDefault();
e.stopPropagation();
});
return $toolbar;
};
// Userlist elements
var getOtherUsers = function(config) {
//var userList = config.userList.getUserlist();
var userData = config.metadataMgr.getMetadata().users;
var i = 0; // duplicates counter
var list = [];
// Display only one time each user (if he is connected in multiple tabs)
var uids = [];
Object.keys(userData).forEach(function(user) {
//if (user !== userNetfluxId) {
var data = userData[user] || {};
var userId = data.uid;
if (!userId) { return; }
//data.netfluxId = user;
if (uids.indexOf(userId) === -1) {// && (!myUid || userId !== myUid)) {
uids.push(userId);
list.push(data);
} else { i++; }
//}
});
return {
list: list,
duplicates: i
};
};
var avatars = {};
var updateUserList = function (toolbar, config) {
// Make sure the elements are displayed
var $userButtons = toolbar.userlist;
var $userlistContent = toolbar.userlistContent;
var metadataMgr = config.metadataMgr;
var userData = metadataMgr.getMetadata().users;
var viewers = metadataMgr.getViewers();
var priv = metadataMgr.getPrivateData();
var origin = priv.origin;
var friends = priv.friends;
var user = metadataMgr.getUserData();
// 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 = config.readOnly === -1 ? userList : arrayIntersect(userList, Object.keys(userData));
// Names of editing users
var others = getOtherUsers(config);
var editUsersNames = others.list;
var duplicates = others.duplicates; // Number of duplicates
editUsersNames.sort(function (a, b) {
var na = a.name || Messages.anonymous;
var nb = b.name || Messages.anonymous;
return na.toLowerCase() > nb.toLowerCase();
});
var numberOfEditUsers = Object.keys(userData).length - duplicates;
var numberOfViewUsers = viewers;
// Update the userlist
var $editUsers = $userlistContent.find('.' + USERLIST_CLS).html('');
var $editUsersList = $('
', {'class': 'cp-toolbar-userlist-others'});
// Editors
var pendingFriends = Common.getPendingFriends();
editUsersNames.forEach(function (data) {
var name = data.name || Messages.anonymous;
var $span = $('', {'class': 'cp-avatar'});
var $rightCol = $('', {'class': 'cp-toolbar-userlist-rightcol'});
var $nameSpan = $('', {'class': 'cp-toolbar-userlist-name'}).text(name).appendTo($rightCol);
var isMe = data.curvePublic === user.curvePublic;
if (Common.isLoggedIn() && data.curvePublic) {
if (isMe) {
$span.attr('title', Messages._getKey('userlist_thisIsYou', [
name
]));
$nameSpan.text(name);
} else if (!friends[data.curvePublic]) {
if (pendingFriends.indexOf(data.netfluxId) !== -1) {
$('', {'class': 'cp-toolbar-userlist-friend'}).text(Messages.userlist_pending)
.appendTo($rightCol);
} else {
$('', {
'class': 'fa fa-user-plus cp-toolbar-userlist-friend',
'title': Messages._getKey('userlist_addAsFriendTitle', [
name
])
}).appendTo($rightCol).click(function (e) {
e.stopPropagation();
Common.sendFriendRequest(data.netfluxId);
});
}
}
}
if (data.profile) {
$span.addClass('cp-userlist-clickable');
$span.click(function () {
window.open(origin+'/profile/#' + data.profile);
});
}
if (data.avatar && avatars[data.avatar]) {
$span.append(avatars[data.avatar]);
$span.append($rightCol);
} else {
Common.displayAvatar($span, data.avatar, name, function ($img) {
if (data.avatar && $img.length) {
avatars[data.avatar] = $img[0].outerHTML;
}
$span.append($rightCol);
});
}
$span.data('uid', data.uid);
$editUsersList.append($span);
});
$editUsers.append($editUsersList);
// Viewers
if (numberOfViewUsers > 0) {
var viewText = '
';
$editUsers.append(viewText);
}
// Update the buttons
var fa_editusers = '';
var fa_viewusers = '';
var $spansmall = $('').html(fa_editusers + ' ' + numberOfEditUsers + ' ' + fa_viewusers + ' ' + numberOfViewUsers);
$userButtons.find('.cp-dropdown-button-title').html('').append($spansmall);
};
var initUserList = function (toolbar, config) {
if (config.metadataMgr) {
var metadataMgr = config.metadataMgr;
metadataMgr.onChange(function () {
if (metadataMgr.isConnected()) {toolbar.connected = true;}
if (!toolbar.connected) { return; }
updateUserList(toolbar, config);
});
}
};
// Create sub-elements
var createUserList = function (toolbar, config) {
if (!config.metadataMgr) {
throw new Error("You must provide a `metadataMgr` to display the userlist");
}
var $content = $('
', {'class': 'cp-toolbar-userlist-drawer'});
$content.on('drop dragover', function (e) {
e.preventDefault();
e.stopPropagation();
});
var $closeIcon = $('', {"class": "fa fa-window-close cp-toolbar-userlist-drawer-close"}).appendTo($content);
$('
').text(Messages.users).appendTo($content);
$('
', {'class': USERLIST_CLS}).appendTo($content);
toolbar.userlistContent = $content;
var $container = $('', {id: 'cp-toolbar-userlist-drawer-open', title: Messages.userListButton});
var $button = $('