diff --git a/customize.dist/main.css b/customize.dist/main.css index 7a638b7d5..157346865 100644 --- a/customize.dist/main.css +++ b/customize.dist/main.css @@ -380,6 +380,7 @@ padding: 5px; margin: 0; white-space: normal; + text-align: left; } .dropdown-bar .dropdown-bar-content p.cryptpad-dropdown-users { text-align: baseline; diff --git a/customize.dist/src/less/dropdown.less b/customize.dist/src/less/dropdown.less index 43bdab128..d45749fa3 100644 --- a/customize.dist/src/less/dropdown.less +++ b/customize.dist/src/less/dropdown.less @@ -67,6 +67,7 @@ padding: 5px; margin: 0; white-space: normal; + text-align: left; &.cryptpad-dropdown-users { text-align:baseline; .yourself, .anonymous, .viewer { diff --git a/customize.dist/toolbar.css b/customize.dist/toolbar.css index 5fb4f90b6..2e9501266 100644 --- a/customize.dist/toolbar.css +++ b/customize.dist/toolbar.css @@ -49,6 +49,7 @@ padding: 5px; margin: 0; white-space: normal; + text-align: left; } .dropdown-bar .dropdown-bar-content p.cryptpad-dropdown-users { text-align: baseline; diff --git a/www/code/main.js b/www/code/main.js index d0e7cb8f2..3ee72e285 100644 --- a/www/code/main.js +++ b/www/code/main.js @@ -375,6 +375,7 @@ define([ }); var config = { + displayed: ['useradmin', 'language', 'spinner', 'lag', 'state', 'share', 'userlist'], userData: userData, readOnly: readOnly, ifrw: ifrw, diff --git a/www/common/toolbar.js b/www/common/toolbar.js index c92840610..77dfddd6f 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -39,10 +39,6 @@ define([ var TITLE_CLS = Bar.constants.title = "cryptpad-title"; var USER_CLS = Bar.constants.userAdmin = "cryptpad-user"; - /** Key in the localStore which indicates realtime activity should be disallowed. */ - // TODO remove? will never be used in cryptpad - var LOCALSTORAGE_DISALLOW = Bar.constants.localstorageDisallow = 'cryptpad-disallow'; - var SPINNER_DISAPPEAR_TIME = 3000; var uid = function () { @@ -79,16 +75,19 @@ define([ return $toolbar; }; - var createSpinner = function ($container) { - var $spinner = $('', { - id: uid(), - 'class': SPINNER_CLS + ' fa fa fa-spinner fa-pulse', - }).hide(); - $container.prepend($spinner); - return $spinner[0]; + var createSpinner = function ($container, config) { + if (config.displayed.indexOf('spinner') !== -1) { + var $spinner = $('', { + id: uid(), + 'class': SPINNER_CLS + ' fa fa fa-spinner fa-pulse', + }).hide(); + $container.prepend($spinner); + return $spinner[0]; + } }; var kickSpinner = function (spinnerElement) { + if (!spinnerElement) { return; } $(spinnerElement).show(); if (spinnerElement.timeout) { clearTimeout(spinnerElement.timeout); } spinnerElement.timeout = setTimeout(function () { @@ -96,37 +95,45 @@ define([ }, SPINNER_DISAPPEAR_TIME); }; - var createUserButtons = function ($userlistElement, readOnly, Cryptpad) { + var createUserButtons = function ($userlistElement, config, readOnly, Cryptpad) { // User list button - 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); + 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 - var $shareIcon = $('', {'class': 'fa fa-share-alt'}); - var $span = $('', {'class': 'large'}).append($shareIcon.clone()).append(' ' +Messages.shareButton); - var $spanSmall = $('', {'class': 'small'}).append($shareIcon.clone()); - var dropdownConfigShare = { - text: $('
').append($span).append($spanSmall).html(), - options: [] - }; - var $shareBlock = Cryptpad.createDropdown(dropdownConfigShare); - $shareBlock.find('.dropdown-bar-content').addClass(SHARE_CLS).addClass(EDITSHARE_CLS).addClass(VIEWSHARE_CLS); - $userlistElement.append($shareBlock); + if (config.displayed.indexOf('share') !== -1) { + var $shareIcon = $('', {'class': 'fa fa-share-alt'}); + var $span = $('', {'class': 'large'}).append($shareIcon.clone()).append(' ' +Messages.shareButton); + var $spanSmall = $('', {'class': 'small'}).append($shareIcon.clone()); + var dropdownConfigShare = { + text: $('
').append($span).append($spanSmall).html(), + options: [] + }; + var $shareBlock = Cryptpad.createDropdown(dropdownConfigShare); + $shareBlock.find('.dropdown-bar-content').addClass(SHARE_CLS).addClass(EDITSHARE_CLS).addClass(VIEWSHARE_CLS); + $userlistElement.append($shareBlock); + } }; - var createUserList = function ($container, readOnly, Cryptpad) { + var createUserList = function ($container, config, readOnly, Cryptpad) { + if (config.displayed.indexOf('userlist') === -1 && config.displayed.indexOf('share') === -1) { return; } var $userlist = $('
', { 'class': USER_LIST_CLS, id: uid(), }); - createUserButtons($userlist, readOnly, Cryptpad); + createUserButtons($userlist, config, readOnly, Cryptpad); $container.append($userlist); return $userlist[0]; }; @@ -167,84 +174,82 @@ define([ $stateElement.text(''); }; - var updateUserList = function (myUserName, userlistElement, userList, userData, readOnly, $userAdminElement) { + 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'); - var numberOfUsers = userList.length; + 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)); + // 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)); - var numberOfEditUsers = userList.length; - var numberOfViewUsers = numberOfUsers - numberOfEditUsers; + var numberOfEditUsers = userList.length; + var numberOfViewUsers = numberOfUsers - numberOfEditUsers; - // Names of editing users - var editUsersNames = getOtherUsers(myUserName, userList, userData); + // Names of editing users + var editUsersNames = getOtherUsers(myUserName, userList, userData); - // Number of anonymous editing users - var anonymous = numberOfEditUsers - editUsersNames.length; + // Number of anonymous editing users + var anonymous = numberOfEditUsers - editUsersNames.length; - // Update the userlist - var editUsersList = ''; - if (readOnly !== 1) { - editUsersNames.unshift('' + Messages.yourself + ''); - anonymous--; - } - if (anonymous > 0) { - var text = anonymous === 1 ? Messages.anonymousUser : Messages.anonymousUsers; - editUsersNames.push('' + anonymous + ' ' + text + ''); - } - if (numberOfViewUsers > 0) { - var viewText = ''; - if (numberOfEditUsers > 0) { - editUsersNames.push(''); - viewText += Messages.and + ' '; + // Update the userlist + var editUsersList = ''; + if (readOnly !== 1) { + editUsersNames.unshift('' + Messages.yourself + ''); + anonymous--; + } + if (anonymous > 0) { + var text = anonymous === 1 ? Messages.anonymousUser : Messages.anonymousUsers; + editUsersNames.push('' + anonymous + ' ' + text + ''); + } + if (numberOfViewUsers > 0) { + var viewText = ''; + if (numberOfEditUsers > 0) { + editUsersNames.push(''); + viewText += Messages.and + ' '; + } + var viewerText = numberOfViewUsers > 1 ? Messages.viewers : Messages.viewer; + viewText += numberOfViewUsers + ' ' + viewerText + ''; + editUsersNames.push(viewText); + } + if (editUsersNames.length > 0) { + editUsersList += editUsersNames.join('
'); } - var viewerText = numberOfViewUsers > 1 ? Messages.viewers : Messages.viewer; - viewText += numberOfViewUsers + ' ' + viewerText + '
'; - editUsersNames.push(viewText); - } - if (editUsersNames.length > 0) { - editUsersList += editUsersNames.join('
'); - } - var $usersTitle = $('

').text(Messages.users); - var $editUsers = $userButtons.find('.' + USERLIST_CLS); - $editUsers.html('').append($usersTitle).append(editUsersList); - - // Update the buttons - var fa_caretdown = ''; - var fa_editusers = ''; - var fa_viewusers = ''; - var viewersText = numberOfViewUsers > 1 ? Messages.viewers : Messages.viewer; - var editorsText = numberOfEditUsers > 1 ? Messages.editors : Messages.editor; - // $userButtons.find('.userlist.edit').html(fa_editusers + ' ' + numberOfEditUsers + ' ' + editorsText + '   ' + fa_viewusers + ' ' + numberOfViewUsers + ' ' + viewersText + ' ' + fa_caretdown); - var $span = $('', {'class': 'large'}).html(fa_editusers + ' ' + numberOfEditUsers + ' ' + editorsText + '   ' + fa_viewusers + ' ' + numberOfViewUsers + ' ' + viewersText); - // $userButtons.find('.userlist.edit.small').html(fa_editusers + ' ' + numberOfEditUsers + '   ' + fa_viewusers + ' ' + numberOfViewUsers + ' ' + fa_caretdown); - var $spansmall = $('', {'class': 'small'}).html(fa_editusers + ' ' + numberOfEditUsers + '   ' + fa_viewusers + ' ' + numberOfViewUsers); - $userButtons.find('.buttonTitle').html('').append($span).append($spansmall); - - // Change username button - var $userElement = $userAdminElement.find('.' + USERNAME_CLS); - $userElement.show(); - if (readOnly === 1) { - //$userElement.html('' + Messages.readonly + ''); - $userElement.addClass('ro').text(Messages.readonly); + var $usersTitle = $('

').text(Messages.users); + var $editUsers = $userButtons.find('.' + USERLIST_CLS); + $editUsers.html('').append($usersTitle).append(editUsersList); + + // Update the buttons + var fa_caretdown = ''; + var fa_editusers = ''; + var fa_viewusers = ''; + var viewersText = numberOfViewUsers > 1 ? Messages.viewers : Messages.viewer; + var editorsText = numberOfEditUsers > 1 ? Messages.editors : Messages.editor; + var $span = $('', {'class': 'large'}).html(fa_editusers + ' ' + numberOfEditUsers + ' ' + editorsText + '   ' + fa_viewusers + ' ' + numberOfViewUsers + ' ' + viewersText); + var $spansmall = $('', {'class': 'small'}).html(fa_editusers + ' ' + numberOfEditUsers + '   ' + fa_viewusers + ' ' + numberOfViewUsers); + $userButtons.find('.buttonTitle').html('').append($span).append($spansmall); } - else { - var name = userData[myUserName] && userData[myUserName].name; - //var icon = ''; - if (!name) { - name = Messages.anonymous; + + 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); } - // $userElement.find("button").show(); - // $userElement.find("button").html(icon + ' ' + name); - $userElement.removeClass('ro').text(name); } }; @@ -321,6 +326,7 @@ define([ }; var createUserAdmin = function ($topContainer, config, lagElement, Cryptpad) { + if (config.displayed.indexOf('useradmin') === -1 && config.displayed.indexOf('share') === -1) { return; } var $lag = $(lagElement); //TODO check if we should displayed that button and if we can (userName.setName, userName.lastName and userdata required) @@ -328,65 +334,77 @@ define([ 'class': USER_CLS }).appendTo($topContainer); - var $state = $('', { - 'class': STATE_CLS - }).text(Messages.synchronizing).appendTo($userContainer); + if (config.displayed.indexOf('state') !== -1) { + var $state = $('', { + 'class': STATE_CLS + }).text(Messages.synchronizing).appendTo($userContainer); + } - $userContainer.append($lag); + if (config.displayed.indexOf('lag') !== -1) { + $userContainer.append($lag); + } - // Dropdown language selector - Cryptpad.createLanguageSelector($userContainer); + if (config.displayed.indexOf('language') !== -1) { + // Dropdown language selector + Cryptpad.createLanguageSelector($userContainer); + } // User dropdown - var $displayedName = $('', {'class': USERNAME_CLS}); - var accountName = null; //TODO Cryptpad.getStore().getAccountName() - var account = typeof accountName === "string"; - var $userAdminContent = $('

'); - if (account) { - var $userAccount = $('', {'class': 'userAccount'}).append('Account: ' + accountName); - $userAdminContent.append($userAccount); - $userAdminContent.append($('
')); - } - var $userName = $('', {'class': 'userDisplayName'}).append('Display name: ').append($displayedName.clone()); - $userAdminContent.append($userName); - var options = [{ - tag: 'p', - content: $userAdminContent.html() - }, { - tag: 'a', - attributes: {'class': 'changeUserName'}, - content: 'Change username' - }, { - tag: 'a', - attributes: {'class': 'login'}, //TODO - content: 'Login' - }, { - tag: 'a', - attributes: {'class': 'logout'}, //TODO - content: 'Logout' - }]; - var $icon = $('', {'class': 'fa fa-user'}); - var $button = $('

').append($icon).append($displayedName.clone()); - if (account) { - $button.append('(' + accountName + ')'); - } - var dropdownConfig = { - text: $button.html(), // Button initial text - options: options, // Entries displayed in the menu - left: true, // Open to the left of the button - }; - var $userAdmin = Cryptpad.createDropdown(dropdownConfig); - $userContainer.append($userAdmin); + if (config.displayed.indexOf('useradmin') !== -1) { + if (!config.userName || !config.userName.setName || !config.userName.lastName) { + throw new Error("You must provide a `userName` object containing `setName` (function) " + + "and `lastName` (object) if you want to display the user admin menu.") + } + var $displayedName = $('', {'class': USERNAME_CLS}); + var accountName = null; //TODO Cryptpad.getStore().getAccountName() + var account = typeof accountName === "string"; + var $userAdminContent = $('

'); + if (account) { + var $userAccount = $('', {'class': 'userAccount'}).append('Account: ' + accountName); + $userAdminContent.append($userAccount); + $userAdminContent.append($('
')); + } + var $userName = $('', {'class': 'userDisplayName'}).append('Display name: ').append($displayedName.clone()); + $userAdminContent.append($userName); + var options = [{ + tag: 'p', + content: $userAdminContent.html() + }, { + tag: 'a', + attributes: {'class': 'changeUserName'}, + content: 'Change username' + }, { + tag: 'a', + attributes: {'class': 'login'}, //TODO + content: 'Login' + }, { + tag: 'a', + attributes: {'class': 'logout'}, //TODO + content: 'Logout' + }]; + var $icon = $('', {'class': 'fa fa-user'}); + var $button = $('

').append($icon).append($displayedName.clone()); + if (account) { + $button.append('(' + accountName + ')'); + } + var dropdownConfig = { + text: $button.html(), // Button initial text + options: options, // Entries displayed in the menu + left: true, // Open to the left of the button + }; + var $userAdmin = Cryptpad.createDropdown(dropdownConfig); + $userContainer.append($userAdmin); - $userAdmin.find('a.logout').click(function (e) { - Cryptpad.logout(); - }); - if (config.userName && config.userName.setName && config.userName.lastName) { - $userAdmin.find('a.changeUserName').click(function (e) { - Cryptpad.prompt(Messages.changeNamePrompt, config.userName.lastName.lastName || '', function (newName) { - config.userName.setName(newName); - }); + $userAdmin.find('a.logout').click(function (e) { + Cryptpad.logout(); }); + if (config.userName && config.userName.setName && config.userName.lastName) { + $userAdmin.find('a.changeUserName').click(function (e) { + Cryptpad.prompt(Messages.changeNamePrompt, config.userName.lastName.lastName || '', function (newName) { + config.userName.setName(newName); + }); + }); + } } return $userContainer; @@ -474,19 +492,20 @@ define([ config = config || {}; var readOnly = (typeof config.readOnly !== "undefined") ? (config.readOnly ? 1 : 0) : -1; var Cryptpad = config.common; + config.displayed = config.displayed || []; var toolbar = createRealtimeToolbar($container); - var userListElement = config.userData ? createUserList(toolbar.find('.' + LEFTSIDE_CLS), readOnly, Cryptpad) : undefined; + 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, lagElement, Cryptpad); - var spinner = createSpinner($userAdminElement); + 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 = $userAdminElement.find('.' + STATE_CLS); + var $stateElement = toolbar.find('.' + STATE_CLS); var connected = false; @@ -524,7 +543,7 @@ define([ if (users.indexOf(myUserName) !== -1) { connected = true; } if (!connected) { return; } checkSynchronizing(users, myUserName, $stateElement); - updateUserList(myUserName, userListElement, users, userData, readOnly, $userAdminElement); + updateUserList(config, myUserName, userListElement, users, userData, readOnly, $userAdminElement); }); } else { userList.change.push(function () { diff --git a/www/drive/main.js b/www/drive/main.js index 17810848f..e0c93e097 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -1747,6 +1747,7 @@ define([ var userList = APP.userList = info.userList; APP.userName = {}; var config = { + displayed: ['useradmin', 'language', 'spinner', 'lag', 'state'], readOnly: readOnly, ifrw: window, common: Cryptpad, diff --git a/www/pad/main.js b/www/pad/main.js index 77bce183f..845a88a8d 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -568,6 +568,7 @@ define([ }); var config = { + displayed: ['useradmin', 'language', 'spinner', 'lag', 'state', 'share', 'userlist'], userData: userData, readOnly: readOnly, ifrw: ifrw, diff --git a/www/poll/main.js b/www/poll/main.js index 0cd55c8ef..64b53e350 100644 --- a/www/poll/main.js +++ b/www/poll/main.js @@ -652,6 +652,7 @@ define([ }); var config = { + displayed: ['useradmin', 'language', 'spinner', 'lag', 'state', 'share', 'userlist'], userData: userData, readOnly: readOnly, title: { diff --git a/www/slide/main.js b/www/slide/main.js index 54e0e7a5f..729d54921 100644 --- a/www/slide/main.js +++ b/www/slide/main.js @@ -418,6 +418,7 @@ define([ }); var config = { + displayed: ['useradmin', 'language', 'spinner', 'lag', 'state', 'share', 'userlist'], userData: userData, readOnly: readOnly, ifrw: ifrw,