define([ 'jquery', '/customize/application_config.js', '/api/config' ], function ($, Config, ApiConfig) { var Messages = {}; var Cryptpad; var Bar = { constants: {}, }; var SPINNER_DISAPPEAR_TIME = 1000; // Toolbar parts 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 DRAWER_CLS = Bar.constants.drawer = 'drawer-content'; var HISTORY_CLS = Bar.constants.history = 'cryptpad-toolbar-history'; // Userlist 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"; // Top parts var USER_CLS = Bar.constants.userAdmin = "cryptpad-user"; var SPINNER_CLS = Bar.constants.spinner = 'cryptpad-spinner'; var LIMIT_CLS = Bar.constants.lag = 'cryptpad-limit'; var TITLE_CLS = Bar.constants.title = "cryptpad-title"; var NEWPAD_CLS = Bar.constants.newpad = "cryptpad-new"; // User admin menu var USERADMIN_CLS = Bar.constants.user = 'cryptpad-user-dropdown'; var USERNAME_CLS = Bar.constants.username = 'cryptpad-toolbar-username'; var READONLY_CLS = Bar.constants.readonly = 'cryptpad-readonly'; var USERBUTTON_CLS = Bar.constants.changeUsername = "cryptpad-change-username"; // Create the toolbar element var uid = function () { return 'cryptpad-uid-' + String(Math.random()).substring(2); }; var createRealtimeToolbar = function (config) { if (!config.$container) { return; } var $container = config.$container; var $toolbar = $('
', { 'class': TOOLBAR_CLS, id: uid(), }); var parsed = Cryptpad.parsePadUrl(window.location.href); if (typeof parsed.type === "string") { config.$container.parents('body').addClass('app-' + parsed.type); } var $topContainer = $('
', {'class': TOP_CLS}); $('', {'class': 'filler'}).appendTo($topContainer); var $userContainer = $('', { 'class': USER_CLS }).appendTo($topContainer); $('', {'class': LIMIT_CLS}).hide().appendTo($userContainer); $('', {'class': NEWPAD_CLS + ' dropdown-bar'}).hide().appendTo($userContainer); $('', {'class': USERADMIN_CLS + ' dropdown-bar'}).hide().appendTo($userContainer); $toolbar.append($topContainer) .append($('
', {'class': LEFTSIDE_CLS})) .append($('
', {'class': RIGHTSIDE_CLS})) .append($('
', {'class': HISTORY_CLS})); var $rightside = $toolbar.find('.'+RIGHTSIDE_CLS); if (!config.hideDrawer) { var $drawerContent = $('
', { 'class': DRAWER_CLS,// + ' dropdown-bar-content cryptpad-dropdown' 'tabindex': 1 }).appendTo($rightside).hide(); var $drawer = Cryptpad.createButton('more', true).appendTo($rightside); $drawer.click(function () { $drawerContent.toggle(); $drawer.removeClass('active'); if ($drawerContent.is(':visible')) { $drawer.addClass('active'); $drawerContent.focus(); } }); var onBlur = function (e) { if (e.relatedTarget) { if ($(e.relatedTarget).is('.drawer-button')) { return; } if ($(e.relatedTarget).parents('.'+DRAWER_CLS).length) { $(e.relatedTarget).blur(onBlur); return; } } $drawer.removeClass('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('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.list.users; var userData = config.userList.data; var i = 0; // duplicates counter var list = []; // Display only one time each user (if he is connected in multiple tabs) var uids = []; userList.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 arrayIntersect = function(a, b) { return $.grep(a, function(i) { return $.inArray(i, b) > -1; }); }; var updateDisplayName = function (toolbar, config) { // Change username in useradmin dropdown var name = Cryptpad.getDisplayName(); if (config.displayed.indexOf('useradmin') !== -1) { var $userAdminElement = toolbar.$userAdmin; var $userElement = $userAdminElement.find('.' + USERNAME_CLS); $userElement.show(); if (config.readOnly === 1) { $userElement.addClass(READONLY_CLS).text(Messages.readonly); } else { if (!name) { name = Messages.anonymous; } $userElement.removeClass(READONLY_CLS).text(name); } } }; var avatars = {}; var updateUserList = function (toolbar, config) { // Make sure the elements are displayed var $userButtons = toolbar.userlist; var $userlistContent = toolbar.userlistContent; var userList = config.userList.list.users; var userData = config.userList.data; 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 = 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 = userList.length - duplicates; var numberOfViewUsers = numberOfUsers - userList.length; // Update the userlist var $editUsers = $userlistContent.find('.' + USERLIST_CLS).html(''); var $editUsersList = $('
', {'class': 'userlist-others'}); // Editors editUsersNames.forEach(function (data) { var name = data.name || Messages.anonymous; var $span = $('', {'title': name, 'class': 'avatar'}); var $rightCol = $('', {'class': 'right-col'}); $('', {'class': 'name'}).text(name).appendTo($rightCol); var proxy = Cryptpad.getProxy(); if (Cryptpad.isLoggedIn() && data.edPublic && data.edPublic !== proxy.edPublic) { if (!proxy.friends || !proxy.friends[data.edPublic]) { var $button = $('