diff --git a/app.js b/app.js index 895508e01..31b202feb 100644 --- a/app.js +++ b/app.js @@ -8,10 +8,14 @@ import "jquery-ui"; import "strophe"; import "strophe-disco"; import "strophe-caps"; -import "tooltip"; -import "popover"; import "jQuery-Impromptu"; import "autosize"; + +import 'aui'; +import 'aui-experimental'; +import 'aui-css'; +import 'aui-experimental-css'; + window.toastr = require("toastr"); import URLProcessor from "./modules/config/URLProcessor"; diff --git a/css/_toolbars.scss b/css/_toolbars.scss index 75eea0be3..2e1675533 100644 --- a/css/_toolbars.scss +++ b/css/_toolbars.scss @@ -129,6 +129,7 @@ a.button:hover, a.button:active, a.button.selected { cursor: pointer; + text-decoration: none; // sum opacity with background layer should give us 0.8 background: $toolbarSelectBackground; } diff --git a/index.html b/index.html index 8a31ba044..082c3aa48 100644 --- a/index.html +++ b/index.html @@ -120,28 +120,28 @@ - + - - + + - - - - + + + - - - - - - - + + + + + + +
@@ -208,7 +208,7 @@
- +
diff --git a/modules/UI/Feedback.js b/modules/UI/Feedback.js index 2338721f4..a7351593d 100644 --- a/modules/UI/Feedback.js +++ b/modules/UI/Feedback.js @@ -140,10 +140,14 @@ var Feedback = { _showFeedbackButton(this.enabled); - $("#feedbackButton").click(function (event) { + let $feedbackButton = $("#feedbackButton"); + + $feedbackButton.click(function (event) { Feedback.openFeedbackWindow(); }); + UIUtil.setTooltip($feedbackButton.get(0), 'feedback', 'right'); + // Show / hide the feedback button whenever the film strip is // shown / hidden. emitter.addListener(UIEvents.TOGGLE_FILM_STRIP, function () { diff --git a/modules/UI/UI.js b/modules/UI/UI.js index 6af1bef2a..a79d3d7d9 100644 --- a/modules/UI/UI.js +++ b/modules/UI/UI.js @@ -339,6 +339,22 @@ UI.handleToggleFilmStrip = () => { VideoLayout.resizeVideoArea(true, false); }; +/** + * Sets tooltip defaults. + * + * @private + */ +function _setTooltipDefaults() { + $.fn.tooltip.defaults = { + opacity: 1, //defaults to 1 + offset: 1, + delayIn: 0, //defaults to 500 + hoverable: true, + hideOnClick: true, + aria: true + }; +} + /** * Setup some UI event listeners. */ @@ -431,6 +447,9 @@ UI.start = function () { // Set the defaults for prompt dialogs. $.prompt.setDefaults({persistent: false}); + // Set the defaults for tooltips. + _setTooltipDefaults(); + registerListeners(); ToolbarToggler.init(); @@ -476,7 +495,6 @@ UI.start = function () { $("#downloadlog").css("display", "none"); FilmStrip.setupFilmStripOnly(); messageHandler.enableNotifications(false); - $('body').popover("disable"); JitsiPopover.enabled = false; } diff --git a/modules/UI/recording/Recording.js b/modules/UI/recording/Recording.js index 720b19014..cf3041adb 100644 --- a/modules/UI/recording/Recording.js +++ b/modules/UI/recording/Recording.js @@ -270,6 +270,9 @@ var Recording = { initRecordingButton(recordingType) { let selector = $('#toolbar_button_record'); + let button = selector.get(0); + UIUtil.setTooltip(button, 'liveStreaming.buttonTooltip', 'right'); + if (recordingType === 'jibri') { this.baseClass = "fa fa-play-circle"; this.recordingTitle = "dialog.liveStreaming"; diff --git a/modules/UI/toolbars/Toolbar.js b/modules/UI/toolbars/Toolbar.js index 01a36dc39..258e787a7 100644 --- a/modules/UI/toolbars/Toolbar.js +++ b/modules/UI/toolbars/Toolbar.js @@ -180,6 +180,7 @@ const buttonHandlers = { const defaultToolbarButtons = { 'microphone': { id: 'toolbar_button_mute', + tooltipKey: 'toolbar.mute', className: "button icon-microphone", shortcut: 'M', shortcutAttr: 'mutePopover', @@ -205,6 +206,7 @@ const defaultToolbarButtons = { }, 'camera': { id: 'toolbar_button_camera', + tooltipKey: 'toolbar.videomute', className: "button icon-camera", shortcut: 'V', shortcutAttr: 'toggleVideoPopover', @@ -218,6 +220,7 @@ const defaultToolbarButtons = { }, 'desktop': { id: 'toolbar_button_desktopsharing', + tooltipKey: 'toolbar.sharescreen', className: 'button icon-share-desktop', shortcut: 'D', shortcutAttr: 'toggleDesktopSharingPopover', @@ -230,16 +233,19 @@ const defaultToolbarButtons = { i18n: '[content]toolbar.sharescreen' }, 'security': { - id: 'toolbar_button_security' + id: 'toolbar_button_security', + tooltipKey: 'toolbar.lock' }, 'invite': { id: 'toolbar_button_link', + tooltipKey: 'toolbar.invite', className: 'button icon-link', content: 'Invite others', i18n: '[content]toolbar.invite' }, 'chat': { id: 'toolbar_button_chat', + tooltipKey: 'toolbar.chat', shortcut: 'C', shortcutAttr: 'toggleChatPopover', shortcutFunc: function() { @@ -251,17 +257,21 @@ const defaultToolbarButtons = { }, 'contacts': { id: 'toolbar_contact_list', + tooltipKey: 'bottomtoolbar.contactlist', sideContainerId: 'contacts_container' }, 'profile': { id: 'toolbar_button_profile', + tooltipKey: 'profile.setDisplayNameLabel', sideContainerId: 'profile_container' }, 'etherpad': { - id: 'toolbar_button_etherpad' + id: 'toolbar_button_etherpad', + tooltipKey: 'toolbar.etherpad', }, 'fullscreen': { id: 'toolbar_button_fullScreen', + tooltipKey: 'toolbar.fullscreen', className: "button icon-full-screen", shortcut: 'F', shortcutAttr: 'toggleFullscreenPopover', @@ -275,16 +285,19 @@ const defaultToolbarButtons = { }, 'settings': { id: 'toolbar_button_settings', + tooltipKey: 'toolbar.Settings', sideContainerId: "settings_container" }, 'hangup': { id: 'toolbar_button_hangup', + tooltipKey: 'toolbar.hangup', className: "button icon-hangup", content: "Hang Up", i18n: "[content]toolbar.hangup" }, 'filmstrip': { id: 'toolbar_film_strip', + tooltipKey: 'toolbar.filmstrip', shortcut: "F", shortcutAttr: "filmstripPopover", shortcutFunc: function() { @@ -295,6 +308,7 @@ const defaultToolbarButtons = { }, 'raisehand': { id: "toolbar_button_raisehand", + tooltipKey: 'toolbar.raiseHand', className: "button icon-raised-hand", shortcut: "R", shortcutAttr: "raiseHandPopover", @@ -351,7 +365,17 @@ const Toolbar = { Object.keys(defaultToolbarButtons).forEach( id => { if (UIUtil.isButtonEnabled(id)) { - var button = defaultToolbarButtons[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( @@ -452,9 +476,11 @@ const Toolbar = { // Shows or hides the 'shared video' button. showSharedVideoButton () { + let $element = $('#toolbar_button_sharedvideo'); if (UIUtil.isButtonEnabled('sharedvideo') && config.disableThirdPartyRequests !== true) { - $('#toolbar_button_sharedvideo').css({display: "inline-block"}); + $element.css({display: "inline-block"}); + UIUtil.setTooltip($element.get(0), 'toolbar.sharedvideo', 'right'); } else { $('#toolbar_button_sharedvideo').css({display: "none"}); } @@ -744,7 +770,6 @@ const Toolbar = { buttonElement.setAttribute("data-i18n", button.i18n); buttonElement.setAttribute("data-container", "body"); - buttonElement.setAttribute("data-toggle", "popover"); buttonElement.setAttribute("data-placement", "bottom"); this._addPopups(buttonElement, button.popups); diff --git a/modules/UI/util/UIUtil.js b/modules/UI/util/UIUtil.js index b55191189..f3ce11eea 100644 --- a/modules/UI/util/UIUtil.js +++ b/modules/UI/util/UIUtil.js @@ -1,4 +1,6 @@ -/* global $, config, interfaceConfig */ +/* global $, APP, config, AJS, interfaceConfig */ + +import KeyboardShortcut from '../../keyboardshortcut/keyboardshortcut'; /** * Created by hristo on 12/22/14. @@ -82,12 +84,50 @@ context.putImageData(imgData, 0, 0); }, + /** + * Sets the tooltip to the given element. + * + * @param element the element to set the tooltip to + * @param key the tooltip data-i18n key + * @param position the position of the tooltip in relation to the element + */ setTooltip: function (element, key, position) { - element.setAttribute("data-i18n", "[data-content]" + key); - element.setAttribute("data-toggle", "popover"); - element.setAttribute("data-placement", position); - element.setAttribute("data-html", true); - element.setAttribute("data-container", "body"); + let positions = { + 'top': 's', + 'top-left': 'se', + 'left': 'e', + 'bottom-left': 'ne', + 'bottom': 'n', + 'bottom-right': 'nw', + 'right': 'w', + 'top-right': 'sw' + }; + + element.setAttribute("data-i18n", "[content]" + key); + APP.translation.translateElement($(element)); + + AJS.$(element).tooltip({ + gravity: positions[position], + title: this._getTooltipText.bind(this, element), + html: true + }); + }, + + /** + * Internal util function for generating tooltip title. + * + * @param element + * @returns {string|*} + * @private + */ + _getTooltipText: function (element) { + let title = element.getAttribute('content'); + let shortcut = element.getAttribute('shortcut'); + if(shortcut) { + let shortcutString = KeyboardShortcut.getShortcutTooltip(shortcut); + title += ` ${shortcutString}`; + } + return title; }, /** diff --git a/modules/UI/videolayout/SmallVideo.js b/modules/UI/videolayout/SmallVideo.js index b905b6eb8..0cb0f71b8 100644 --- a/modules/UI/videolayout/SmallVideo.js +++ b/modules/UI/videolayout/SmallVideo.js @@ -197,7 +197,6 @@ SmallVideo.prototype.showAudioIndicator = function(isMuted) { if (!isMuted) { if (audioMutedSpan.length > 0) { - audioMutedSpan.popover('hide'); audioMutedSpan.remove(); this.updateIconPositions(); } @@ -304,7 +303,7 @@ SmallVideo.prototype.createModeratorIndicatorElement = function () { UIUtil.setTooltip(indicatorSpan[0], "videothumbnail.moderator", - "top"); + "top-left"); //translates text in focus indicators APP.translation diff --git a/modules/keyboardshortcut/keyboardshortcut.js b/modules/keyboardshortcut/keyboardshortcut.js index 4bb98fb2c..9acd2d504 100644 --- a/modules/keyboardshortcut/keyboardshortcut.js +++ b/modules/keyboardshortcut/keyboardshortcut.js @@ -74,13 +74,6 @@ var KeyboardShortcut = { } } }; - $('body').popover({ selector: '[data-toggle=popover]', - trigger: 'click hover', - content: function() { - return this.getAttribute("content") - + self._getShortcutTooltip(this.getAttribute("shortcut")); - } - }); }, /** @@ -128,7 +121,7 @@ var KeyboardShortcut = { * or an empty string if the shortcutAttr is null, an empty string or not * found in the shortcut mapping */ - _getShortcutTooltip: function (shortcutAttr) { + getShortcutTooltip: function (shortcutAttr) { if (typeof shortcutAttr === "string" && shortcutAttr.length > 0) { for (var key in _shortcuts) { if (_shortcuts.hasOwnProperty(key) diff --git a/package.json b/package.json index 1a6cfa30a..57164364d 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "readmeFilename": "README.md", "//": "Callstats.io does not work with recent versions of jsSHA (2.0.1 in particular)", "dependencies": { + "@atlassian/aui": "^6.0.0", "async": "0.9.0", "autosize": "^1.18.13", "bootstrap": "3.1.1", @@ -83,7 +84,11 @@ "tooltip": "./node_modules/bootstrap/js/tooltip.js", "popover": "./node_modules/bootstrap/js/popover.js", "jQuery-Impromptu": "./node_modules/jQuery-Impromptu/dist/jquery-impromptu.js", - "autosize": "./node_modules/autosize/build/jquery.autosize.js" + "autosize": "./node_modules/autosize/build/jquery.autosize.js", + "aui": "./node_modules/@atlassian/aui/dist/aui/js/aui.js", + "aui-experimental": "./node_modules/@atlassian/aui/dist/aui/js/aui-experimental.js", + "aui-css": "./node_modules/@atlassian/aui/dist/aui/css/aui.min.css", + "aui-experimental-css": "./node_modules/@atlassian/aui/dist/aui/css/aui-experimental.min.css" }, "browserify-shim": { "jquery": [ @@ -109,6 +114,9 @@ "jQuery-Impromptu": { "depends": "jquery:jQuery" }, + "aui-experimental": { + "depends": "aui:AJS" + }, "jquery-contextmenu": { "depends": "jquery:jQuery" },