224 lines
7.5 KiB
JavaScript
224 lines
7.5 KiB
JavaScript
/* global APP, $, JitsiMeetJS */
|
|
|
|
/**
|
|
* Initialise global shortcuts.
|
|
* Global shortcuts are shortcuts for features that don't have a button or
|
|
* link associated with the action. In other words they represent actions
|
|
* triggered _only_ with a shortcut.
|
|
*/
|
|
function initGlobalShortcuts() {
|
|
|
|
KeyboardShortcut.registerShortcut("ESCAPE", null, function() {
|
|
APP.UI.showKeyboardShortcutsPanel(false);
|
|
});
|
|
|
|
KeyboardShortcut.registerShortcut("?", null, function() {
|
|
JitsiMeetJS.analytics.sendEvent("shortcut.shortcut.help");
|
|
APP.UI.toggleKeyboardShortcutsPanel();
|
|
}, "keyboardShortcuts.toggleShortcuts");
|
|
|
|
KeyboardShortcut.registerShortcut("T", null, function() {
|
|
JitsiMeetJS.analytics.sendEvent("shortcut.talk.clicked");
|
|
APP.conference.muteAudio(true);
|
|
}, "keyboardShortcuts.pushToTalk");
|
|
|
|
/**
|
|
* FIXME: Currently focus keys are directly implemented below in onkeyup.
|
|
* They should be moved to the SmallVideo instead.
|
|
*/
|
|
KeyboardShortcut._addShortcutToHelp("0", "keyboardShortcuts.focusLocal");
|
|
KeyboardShortcut._addShortcutToHelp("1-9", "keyboardShortcuts.focusRemote");
|
|
}
|
|
|
|
/**
|
|
* Map of shortcuts. When a shortcut is registered it enters the mapping.
|
|
* @type {{}}
|
|
*/
|
|
let _shortcuts = {};
|
|
|
|
/**
|
|
* Maps keycode to character, id of popover for given function and function.
|
|
*/
|
|
var KeyboardShortcut = {
|
|
init: function () {
|
|
initGlobalShortcuts();
|
|
|
|
var self = this;
|
|
window.onkeyup = function(e) {
|
|
var key = self._getKeyboardKey(e).toUpperCase();
|
|
var num = parseInt(key, 10);
|
|
if(!($(":focus").is("input[type=text]") ||
|
|
$(":focus").is("input[type=password]") ||
|
|
$(":focus").is("textarea"))) {
|
|
if (_shortcuts.hasOwnProperty(key)) {
|
|
_shortcuts[key].function(e);
|
|
}
|
|
else if (!isNaN(num) && num >= 0 && num <= 9) {
|
|
APP.UI.clickOnVideo(num + 1);
|
|
}
|
|
//esc while the smileys are visible hides them
|
|
} else if (key === "ESCAPE" &&
|
|
$('#smileysContainer').is(':visible')) {
|
|
APP.UI.toggleSmileys();
|
|
}
|
|
};
|
|
|
|
window.onkeydown = function(e) {
|
|
if(!($(":focus").is("input[type=text]") ||
|
|
$(":focus").is("input[type=password]") ||
|
|
$(":focus").is("textarea"))) {
|
|
var key = self._getKeyboardKey(e).toUpperCase();
|
|
if(key === "T") {
|
|
if(APP.conference.isLocalAudioMuted())
|
|
APP.conference.muteAudio(false);
|
|
}
|
|
}
|
|
};
|
|
$('body').popover({ selector: '[data-toggle=popover]',
|
|
trigger: 'click hover',
|
|
content: function() {
|
|
return this.getAttribute("content")
|
|
+ self._getShortcutTooltip(this.getAttribute("shortcut"));
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Registers a new shortcut.
|
|
*
|
|
* @param shortcutChar the shortcut character triggering the action
|
|
* @param shortcutAttr the "shortcut" html element attribute mappring an
|
|
* element to this shortcut and used to show the shortcut character on the
|
|
* element tooltip
|
|
* @param exec the function to be executed when the shortcut is pressed
|
|
* @param helpDescription the description of the shortcut that would appear
|
|
* in the help menu
|
|
*/
|
|
registerShortcut: function( shortcutChar,
|
|
shortcutAttr,
|
|
exec,
|
|
helpDescription) {
|
|
_shortcuts[shortcutChar] = {
|
|
character: shortcutChar,
|
|
shortcutAttr: shortcutAttr,
|
|
function: exec
|
|
};
|
|
|
|
if (helpDescription)
|
|
this._addShortcutToHelp(shortcutChar, helpDescription);
|
|
},
|
|
|
|
/**
|
|
* Unregisters a shortcut.
|
|
*
|
|
* @param shortcutChar unregisters the given shortcut, which means it will
|
|
* no longer be usable
|
|
*/
|
|
unregisterShortcut: function(shortcutChar) {
|
|
_shortcuts.remove(shortcutChar);
|
|
|
|
this._removeShortcutFromHelp(shortcutChar);
|
|
},
|
|
|
|
/**
|
|
* Returns the tooltip string for the given shortcut attribute.
|
|
*
|
|
* @param shortcutAttr indicates the popover associated with the shortcut
|
|
* @returns {string} the tooltip string to add to the given shortcut popover
|
|
* or an empty string if the shortcutAttr is null, an empty string or not
|
|
* found in the shortcut mapping
|
|
*/
|
|
_getShortcutTooltip: function (shortcutAttr) {
|
|
if (typeof shortcutAttr === "string" && shortcutAttr.length > 0) {
|
|
for (var key in _shortcuts) {
|
|
if (_shortcuts.hasOwnProperty(key)
|
|
&& _shortcuts[key].shortcutAttr
|
|
&& _shortcuts[key].shortcutAttr === shortcutAttr) {
|
|
return " (" + _shortcuts[key].character + ")";
|
|
}
|
|
}
|
|
}
|
|
|
|
return "";
|
|
},
|
|
/**
|
|
* @param e a KeyboardEvent
|
|
* @returns {string} e.key or something close if not supported
|
|
*/
|
|
_getKeyboardKey: function (e) {
|
|
if (typeof e.key === "string") {
|
|
return e.key;
|
|
}
|
|
if (e.type === "keypress" && (
|
|
(e.which >= 32 && e.which <= 126) ||
|
|
(e.which >= 160 && e.which <= 255) )) {
|
|
return String.fromCharCode(e.which);
|
|
}
|
|
// try to fallback (0-9A-Za-z and QWERTY keyboard)
|
|
switch (e.which) {
|
|
case 27:
|
|
return "Escape";
|
|
case 191:
|
|
return e.shiftKey ? "?" : "/";
|
|
}
|
|
if (e.shiftKey || e.type === "keypress") {
|
|
return String.fromCharCode(e.which);
|
|
} else {
|
|
return String.fromCharCode(e.which).toLowerCase();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Adds the given shortcut to the help dialog.
|
|
*
|
|
* @param shortcutChar the shortcut character
|
|
* @param shortcutDescriptionKey the description of the shortcut
|
|
* @private
|
|
*/
|
|
_addShortcutToHelp: function (shortcutChar, shortcutDescriptionKey) {
|
|
|
|
var listElement = document.createElement("li");
|
|
listElement.id = shortcutChar;
|
|
|
|
var spanElement = document.createElement("span");
|
|
spanElement.className = "item-action";
|
|
|
|
var kbdElement = document.createElement("kbd");
|
|
kbdElement.className = "regular-key";
|
|
kbdElement.innerHTML = shortcutChar;
|
|
spanElement.appendChild(kbdElement);
|
|
|
|
var descriptionElement = document.createElement("span");
|
|
descriptionElement.className = "item-description";
|
|
descriptionElement.setAttribute("data-i18n", shortcutDescriptionKey);
|
|
descriptionElement.innerHTML
|
|
= APP.translation.translateString(shortcutDescriptionKey);
|
|
|
|
listElement.appendChild(spanElement);
|
|
listElement.appendChild(descriptionElement);
|
|
|
|
var parentListElement
|
|
= document.getElementById("keyboard-shortcuts-list");
|
|
|
|
if (parentListElement)
|
|
parentListElement.appendChild(listElement);
|
|
},
|
|
|
|
/**
|
|
* Removes the list element corresponding to the given shortcut from the
|
|
* help dialog
|
|
* @private
|
|
*/
|
|
_removeShortcutFromHelp: function (shortcutChar) {
|
|
var parentListElement
|
|
= document.getElementById("keyboard-shortcuts-list");
|
|
|
|
var shortcutElement = document.getElementById(shortcutChar);
|
|
|
|
if (shortcutElement)
|
|
parentListElement.removeChild(shortcutElement);
|
|
}
|
|
};
|
|
|
|
module.exports = KeyboardShortcut;
|