Merge pull request #1054 from kkrisstoff/task/make-extended-toolbar-dynamically-created-buttons

make extended buttons dynamic
This commit is contained in:
hristoterezov 2016-10-31 16:50:14 -05:00 committed by GitHub
commit a7a7f269c3
5 changed files with 162 additions and 102 deletions

View File

@ -42,22 +42,7 @@
margin-right: auto; margin-right: auto;
width: auto; width: auto;
border-radius: 3px; border-radius: 3px;
overflow: hidden;
/**
* First button in the toolbar.
*/
.first {
border-bottom-left-radius: 3px;
border-top-left-radius: 3px;
}
/**
* Last button in the toolbar.
*/
.last {
border-bottom-right-radius: 3px;
border-top-right-radius: 3px;
}
/** /**
* Splitter button in the toolbar. * Splitter button in the toolbar.
@ -75,8 +60,8 @@
display: flex; display: flex;
width: $defaultToolbarSize; width: $defaultToolbarSize;
height: 100%; height: 100%;
top: 0px; top: 0;
left: 0px; left: 0;
padding-top: 10px; padding-top: 10px;
box-sizing: border-box; box-sizing: border-box;
flex-direction: column; flex-direction: column;

View File

@ -131,37 +131,13 @@
<div id="notice" class="notice" style="display: none"> <div id="notice" class="notice" style="display: none">
<span id="noticeText" class="noticeText"></span> <span id="noticeText" class="noticeText"></span>
</div> </div>
<span id="mainToolbar" class="toolbar"></span> <div id="mainToolbar" class="toolbar"></div>
</div> </div>
<div id="subject" class="hide"></div> <div id="subject" class="hide"></div>
<div id="extendedToolbar" class="toolbar"> <div id="extendedToolbar" class="toolbar">
<a class="button" id="toolbar_button_profile" data-container="body" data-placement="right" data-i18n="[content]toolbar.profile"> <div id="extendedToolbarButtons"></div>
<img id="avatar" src="images/avatar2.png"/>
</a>
<a class="button icon-contactList" id="toolbar_contact_list" shortcut="contactlistpopover">
<span class="badge-round">
<span id="numberOfParticipants"></span>
</span>
</a>
<!--a class="button icon-link" id="toolbar_button_link"></a-->
<a class="button icon-chat" id="toolbar_button_chat" shortcut="toggleChatPopover">
<span class="badge-round">
<span id="unreadMessages"></span>
</span>
</a>
<a class="button" id="toolbar_button_record" style="display: none"></a>
<a class="button icon-share-doc" id="toolbar_button_etherpad"></a>
<a class="button icon-shared-video" id="toolbar_button_sharedvideo" style="display: none">
<ul id="sharedVideoMutedPopup" class="loginmenu extendedToolbarPopup">
<li data-i18n="[html]toolbar.sharedVideoMutedPopup"></li>
</ul>
</a>
<a class="button icon-telephone" id="toolbar_button_sip" style="display: none"></a>
<a class="button icon-dialpad" id="toolbar_button_dialpad" style="display: none"></a>
<a class="button icon-settings" id="toolbar_button_settings"></a>
<a class="button icon-raised-hand" id="toolbar_button_raisehand" shortcut="raiseHandPopover"></a>
<a class="button icon-toggle-filmstrip" id="toolbar_film_strip" data-container="body" shortcut="filmstripPopover"></a>
<a class="button icon-feedback" id="feedbackButton"></a> <a class="button icon-feedback" id="feedbackButton"></a>
<div id="sideToolbarContainer"> <div id="sideToolbarContainer">

View File

@ -24,14 +24,26 @@ var interfaceConfig = { // eslint-disable-line no-unused-vars
AUTHENTICATION_ENABLE: true, AUTHENTICATION_ENABLE: true,
// the toolbar buttons line is intentionally left in one line, to be able // the toolbar buttons line is intentionally left in one line, to be able
// to easily override values or remove them using regex // to easily override values or remove them using regex
MAIN_TOOLBAR_BUTTONS: ['microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'hangup'], // jshint ignore:line
/** /**
* The index of the splitter button in the main toolbar. The splitter * The index of the splitter button in the main toolbar. The splitter
* button is a button in the toolbar that will be applied a special styling * button is a button in the toolbar that will be applied a special styling
* visually dividing the toolbar buttons. * visually dividing the toolbar buttons.
*/ */
//MAIN_TOOLBAR_SPLITTER_INDEX: -1, //MAIN_TOOLBAR_SPLITTER_INDEX: -1,
TOOLBAR_BUTTONS: ['profile', 'authentication', 'microphone', 'camera', 'desktop', 'recording', 'security', 'raisehand', 'chat', 'etherpad', 'sharedvideo', 'sip', 'dialpad', 'settings', 'hangup', 'filmstrip', 'contacts'], // jshint ignore:line /**
* the toolbar buttons line is intentionally left in one line, to be able
* to easily override values or remove them using regex
*/
TOOLBAR_BUTTONS: [
//main toolbar
'microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'hangup',
//extended toolbar
'profile', 'contacts', 'chat', 'recording', 'etherpad', 'sharedvideo', 'sip', 'dialpad', 'settings', 'raisehand', 'filmstrip'], // jshint ignore:line
/**
* Main Toolbar Buttons
* All of them should be in TOOLBAR_BUTTONS
*/
MAIN_TOOLBAR_BUTTONS: ['microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'hangup'], // jshint ignore:line
SETTINGS_SECTIONS: ['language', 'devices', 'moderator'], SETTINGS_SECTIONS: ['language', 'devices', 'moderator'],
// Determines how the video would fit the screen. 'both' would fit the whole // Determines how the video would fit the screen. 'both' would fit the whole
// screen, 'height' would fit the original video height to the height of the // screen, 'height' would fit the original video height to the height of the

View File

@ -1021,7 +1021,7 @@ UI.addMessage = function (from, displayName, message, stamp) {
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
UI.updateDTMFSupport = function (isDTMFSupported) { UI.updateDTMFSupport = function (isDTMFSupported) {
//TODO: enable when the UI is ready //TODO: enable when the UI is ready
//Toolbar.showDialPadButton(dtmfSupport); //Toolbar.showDialPadButton(isDTMFSupported);
}; };
/** /**

View File

@ -6,6 +6,11 @@ import SideContainerToggler from "../side_pannels/SideContainerToggler";
let emitter = null; let emitter = null;
let Toolbar; let Toolbar;
/**
* Handlers for toolbar buttons.
*
* buttonId {string}: handler {function}
*/
const buttonHandlers = { const buttonHandlers = {
"toolbar_button_profile": function () { "toolbar_button_profile": function () {
JitsiMeetJS.analytics.sendEvent('toolbar.profile.toggled'); JitsiMeetJS.analytics.sendEvent('toolbar.profile.toggled');
@ -124,6 +129,9 @@ const buttonHandlers = {
} }
}; };
/**
* All toolbars buttons description
*/
const defaultToolbarButtons = { const defaultToolbarButtons = {
'microphone': { 'microphone': {
id: 'toolbar_button_mute', id: 'toolbar_button_mute',
@ -194,6 +202,7 @@ const defaultToolbarButtons = {
'chat': { 'chat': {
id: 'toolbar_button_chat', id: 'toolbar_button_chat',
tooltipKey: 'toolbar.chat', tooltipKey: 'toolbar.chat',
className: 'button icon-chat',
shortcut: 'C', shortcut: 'C',
shortcutAttr: 'toggleChatPopover', shortcutAttr: 'toggleChatPopover',
shortcutFunc: function() { shortcutFunc: function() {
@ -201,21 +210,31 @@ const defaultToolbarButtons = {
APP.UI.toggleChat(); APP.UI.toggleChat();
}, },
shortcutDescription: 'keyboardShortcuts.toggleChat', shortcutDescription: 'keyboardShortcuts.toggleChat',
sideContainerId: 'chat_container' sideContainerId: 'chat_container',
html: `<span class="badge-round">
<span id="unreadMessages"></span>
</span>`
}, },
'contacts': { 'contacts': {
id: 'toolbar_contact_list', id: 'toolbar_contact_list',
tooltipKey: 'bottomtoolbar.contactlist', tooltipKey: 'bottomtoolbar.contactlist',
sideContainerId: 'contacts_container' className: 'button icon-contactList',
sideContainerId: 'contacts_container',
html: `<span class="badge-round">
<span id="numberOfParticipants"></span>
</span>`
}, },
'profile': { 'profile': {
id: 'toolbar_button_profile', id: 'toolbar_button_profile',
tooltipKey: 'profile.setDisplayNameLabel', tooltipKey: 'profile.setDisplayNameLabel',
sideContainerId: 'profile_container' className: 'button',
sideContainerId: 'profile_container',
html: `<img id="avatar" src="images/avatar2.png"/>`
}, },
'etherpad': { 'etherpad': {
id: 'toolbar_button_etherpad', id: 'toolbar_button_etherpad',
tooltipKey: 'toolbar.etherpad', tooltipKey: 'toolbar.etherpad',
className: 'button icon-share-doc'
}, },
'fullscreen': { 'fullscreen': {
id: 'toolbar_button_fullScreen', id: 'toolbar_button_fullScreen',
@ -234,6 +253,7 @@ const defaultToolbarButtons = {
'settings': { 'settings': {
id: 'toolbar_button_settings', id: 'toolbar_button_settings',
tooltipKey: 'toolbar.Settings', tooltipKey: 'toolbar.Settings',
className: 'button icon-settings',
sideContainerId: "settings_container" sideContainerId: "settings_container"
}, },
'hangup': { 'hangup': {
@ -246,6 +266,7 @@ const defaultToolbarButtons = {
'filmstrip': { 'filmstrip': {
id: 'toolbar_film_strip', id: 'toolbar_film_strip',
tooltipKey: 'toolbar.filmstrip', tooltipKey: 'toolbar.filmstrip',
className: "button icon-toggle-filmstrip",
shortcut: "F", shortcut: "F",
shortcutAttr: "filmstripPopover", shortcutAttr: "filmstripPopover",
shortcutFunc: function() { shortcutFunc: function() {
@ -267,6 +288,34 @@ const defaultToolbarButtons = {
shortcutDescription: "keyboardShortcuts.raiseHand", shortcutDescription: "keyboardShortcuts.raiseHand",
content: "Raise Hand", content: "Raise Hand",
i18n: "[content]toolbar.raiseHand" i18n: "[content]toolbar.raiseHand"
},
//init and btn handler: Recording.initRecordingButton (Recording.js)
'recording': {
id: 'toolbar_button_record',
tooltipKey: 'liveStreaming.buttonTooltip',
className: 'button'
},
'sharedvideo': {
id: 'toolbar_button_sharedvideo',
tooltipKey: 'toolbar.sharedvideo',
className: 'button icon-shared-video',
html: `<ul id="sharedVideoMutedPopup"
class="loginmenu extendedToolbarPopup">
<li data-i18n="[html]toolbar.sharedVideoMutedPopup"></li>
</ul>
`
},
'sip': {
id: 'toolbar_button_sip',
tooltipKey: 'toolbar.sip',
className: 'button icon-telephone'
},
'dialpad': {
id: 'toolbar_button_dialpad',
tooltipKey: 'toolbar.dialpad',
className: 'button icon-dialpad',
//TODO: remove it after UI.updateDTMFSupport fix
hidden: true
} }
}; };
@ -281,8 +330,7 @@ function showSipNumberInput () {
let titleKey = "dialog.sipMsg"; let titleKey = "dialog.sipMsg";
let msgString = (` let msgString = (`
<input name="sipNumber" type="text" <input name="sipNumber" type="text"
value="${defaultNumber}" autofocus> value="${defaultNumber}" autofocus>`);
`);
APP.UI.messageHandler.openTwoButtonDialog({ APP.UI.messageHandler.openTwoButtonDialog({
titleKey, titleKey,
@ -297,6 +345,19 @@ function showSipNumberInput () {
}); });
} }
/**
* Get place for toolbar button.
* Now it can be in main toolbar or in extended (left) toolbar
*
* @param btn {string}
* @returns {string}
*/
function getToolbarButtonPlace (btn) {
return interfaceConfig.MAIN_TOOLBAR_BUTTONS.includes(btn) ?
'main' :
'extended';
}
Toolbar = { Toolbar = {
init (eventEmitter) { init (eventEmitter) {
emitter = eventEmitter; emitter = eventEmitter;
@ -305,45 +366,14 @@ Toolbar = {
this.toolbarSelector = $("#mainToolbarContainer"); this.toolbarSelector = $("#mainToolbarContainer");
this.extendedToolbarSelector = $("#extendedToolbar"); this.extendedToolbarSelector = $("#extendedToolbar");
// First hide all disabled buttons in the extended toolbar. // Initialise the toolbar buttons.
// TODO: Make the extended toolbar dynamically created. // The main toolbar will only take into account
UIUtil.hideDisabledButtons(defaultToolbarButtons); // it's own configuration from interface_config.
this._initToolbarButtons();
// Initialise the main toolbar. The main toolbar will only take into this._setShortcutsAndTooltips();
// account it's own configuration from interface_config.
this._initMainToolbarButtons();
Object.keys(defaultToolbarButtons).forEach( this._setButtonHandlers();
id => {
if (UIUtil.isButtonEnabled(id)) {
let button = defaultToolbarButtons[id];
let buttonElement = document.getElementById(button.id);
let tooltipPosition
= (interfaceConfig.MAIN_TOOLBAR_BUTTONS
.indexOf(id) > -1)
? "bottom" : "right";
UIUtil.setTooltip( buttonElement,
button.tooltipKey,
tooltipPosition);
if (button.shortcut)
APP.keyboardshortcut.registerShortcut(
button.shortcut,
button.shortcutAttr,
button.shortcutFunc,
button.shortcutDescription
);
}
}
);
Object.keys(buttonHandlers).forEach(
buttonId => $(`#${buttonId}`).click(function(event) {
!$(this).prop('disabled') && buttonHandlers[buttonId](event);
})
);
APP.UI.addListener(UIEvents.SIDE_TOOLBAR_CONTAINER_TOGGLED, APP.UI.addListener(UIEvents.SIDE_TOOLBAR_CONTAINER_TOGGLED,
(containerId, isVisible) => { (containerId, isVisible) => {
@ -703,16 +733,17 @@ Toolbar = {
}, },
/** /**
* Initialise main toolbar buttons. * Initialise toolbar buttons.
*/ */
_initMainToolbarButtons() { _initToolbarButtons() {
interfaceConfig.MAIN_TOOLBAR_BUTTONS.forEach((value, index) => { interfaceConfig.TOOLBAR_BUTTONS.forEach((value, index) => {
let place = getToolbarButtonPlace(value);
if (value && value in defaultToolbarButtons) { if (value && value in defaultToolbarButtons) {
let button = defaultToolbarButtons[value]; let button = defaultToolbarButtons[value];
this._addMainToolbarButton( this._addToolbarButton(
button, button,
(index === 0), place,
(index === interfaceConfig.MAIN_TOOLBAR_BUTTONS.length -1),
(interfaceConfig.MAIN_TOOLBAR_SPLITTER_INDEX !== undefined (interfaceConfig.MAIN_TOOLBAR_SPLITTER_INDEX !== undefined
&& index && index
=== interfaceConfig.MAIN_TOOLBAR_SPLITTER_INDEX)); === interfaceConfig.MAIN_TOOLBAR_SPLITTER_INDEX));
@ -721,7 +752,7 @@ Toolbar = {
}, },
/** /**
* Adds the given button to the main (top) toolbar. * Adds the given button to the main (top) or extended (left) toolbar.
* *
* @param {Object} the button to add. * @param {Object} the button to add.
* @param {boolean} isFirst indicates if this is the first button in the * @param {boolean} isFirst indicates if this is the first button in the
@ -731,16 +762,26 @@ Toolbar = {
* @param {boolean} isSplitter if this button is a splitter button for * @param {boolean} isSplitter if this button is a splitter button for
* the dialog, which means that a special splitter style will be applied * the dialog, which means that a special splitter style will be applied
*/ */
_addMainToolbarButton(button, isFirst, isLast, isSplitter) { _addToolbarButton(button, place, isSplitter) {
const places = {
main: 'mainToolbar',
extended: 'extendedToolbarButtons'
};
let id = places[place];
let buttonElement = document.createElement("a"); let buttonElement = document.createElement("a");
if (button.className) if (button.className)
buttonElement.className = button.className buttonElement.className = button.className
+ ((isFirst) ? " first" : "")
+ ((isLast) ? " last" : "")
+ ((isSplitter) ? " splitter": ""); + ((isSplitter) ? " splitter": "");
buttonElement.id = button.id; buttonElement.id = button.id;
if (button.html)
buttonElement.innerHTML = button.html;
//TODO: remove it after UI.updateDTMFSupport fix
if (button.hidden)
buttonElement.style.display = 'none';
if (button.shortcutAttr) if (button.shortcutAttr)
buttonElement.setAttribute("shortcut", button.shortcutAttr); buttonElement.setAttribute("shortcut", button.shortcutAttr);
@ -754,7 +795,7 @@ Toolbar = {
buttonElement.setAttribute("data-placement", "bottom"); buttonElement.setAttribute("data-placement", "bottom");
this._addPopups(buttonElement, button.popups); this._addPopups(buttonElement, button.popups);
document.getElementById("mainToolbar") document.getElementById(id)
.appendChild(buttonElement); .appendChild(buttonElement);
}, },
@ -779,6 +820,52 @@ Toolbar = {
*/ */
_setToggledState(elementId, isToggled) { _setToggledState(elementId, isToggled) {
$("#" + elementId).toggleClass("toggled", isToggled); $("#" + elementId).toggleClass("toggled", isToggled);
},
/**
* Sets Shortcuts and Tooltips for all toolbar buttons
*
* @private
*/
_setShortcutsAndTooltips() {
Object.keys(defaultToolbarButtons).forEach(
id => {
if (UIUtil.isButtonEnabled(id)) {
let button = defaultToolbarButtons[id];
let buttonElement = document.getElementById(button.id);
if (!buttonElement) return false;
let tooltipPosition
= (interfaceConfig.MAIN_TOOLBAR_BUTTONS
.indexOf(id) > -1)
? "bottom" : "right";
UIUtil.setTooltip( buttonElement,
button.tooltipKey,
tooltipPosition);
if (button.shortcut)
APP.keyboardshortcut.registerShortcut(
button.shortcut,
button.shortcutAttr,
button.shortcutFunc,
button.shortcutDescription
);
}
}
);
},
/**
* Sets Handlers for all toolbar buttons
*
* @private
*/
_setButtonHandlers() {
Object.keys(buttonHandlers).forEach(
buttonId => $(`#${buttonId}`).click(function(event) {
!$(this).prop('disabled') && buttonHandlers[buttonId](event);
})
);
} }
}; };