|
@@ -1,91 +1,62 @@
|
1
|
1
|
/* global APP, $, JitsiMeetJS */
|
2
|
|
-//maps keycode to character, id of popover for given function and function
|
3
|
|
-var shortcuts = {};
|
4
|
|
-function initShortcutHandlers() {
|
5
|
|
- shortcuts = {
|
6
|
|
- "ESCAPE": {
|
7
|
|
- character: "Esc",
|
8
|
|
- function: function() {
|
9
|
|
- APP.UI.showKeyboardShortcutsPanel(false);
|
10
|
|
- }
|
11
|
|
- },
|
12
|
|
- "C": {
|
13
|
|
- character: "C",
|
14
|
|
- id: "toggleChatPopover",
|
15
|
|
- function: function() {
|
16
|
|
- JitsiMeetJS.analytics.sendEvent('shortcut.chat.toggled');
|
17
|
|
- APP.UI.toggleChat();
|
18
|
|
- }
|
19
|
|
- },
|
20
|
|
- "D": {
|
21
|
|
- character: "D",
|
22
|
|
- id: "toggleDesktopSharingPopover",
|
23
|
|
- function: function () {
|
24
|
|
- JitsiMeetJS.analytics.sendEvent('shortcut.screen.toggled');
|
25
|
|
- APP.conference.toggleScreenSharing();
|
26
|
|
- }
|
27
|
|
- },
|
28
|
|
- "F": {
|
29
|
|
- character: "F",
|
30
|
|
- id: "filmstripPopover",
|
31
|
|
- function: function() {
|
32
|
|
- JitsiMeetJS.analytics.sendEvent('shortcut.film.toggled');
|
33
|
|
- APP.UI.toggleFilmStrip();
|
34
|
|
- }
|
35
|
|
- },
|
36
|
|
- "M": {
|
37
|
|
- character: "M",
|
38
|
|
- id: "mutePopover",
|
39
|
|
- function: function() {
|
40
|
|
- JitsiMeetJS.analytics.sendEvent('shortcut.audiomute.toggled');
|
41
|
|
- APP.conference.toggleAudioMuted();
|
42
|
|
- }
|
43
|
|
- },
|
44
|
|
- "R": {
|
45
|
|
- character: "R",
|
46
|
|
- function: function() {
|
47
|
|
- JitsiMeetJS.analytics.sendEvent('shortcut.raisedhand.toggled');
|
48
|
|
- APP.conference.maybeToggleRaisedHand();
|
49
|
|
- }
|
50
|
2
|
|
51
|
|
- },
|
52
|
|
- "T": {
|
53
|
|
- character: "T",
|
54
|
|
- function: function() {
|
55
|
|
- JitsiMeetJS.analytics.sendEvent('shortcut.talk.clicked');
|
56
|
|
- APP.conference.muteAudio(true);
|
57
|
|
- }
|
58
|
|
- },
|
59
|
|
- "V": {
|
60
|
|
- character: "V",
|
61
|
|
- id: "toggleVideoPopover",
|
62
|
|
- function: function() {
|
63
|
|
- JitsiMeetJS.analytics.sendEvent('shortcut.videomute.toggled');
|
64
|
|
- APP.conference.toggleVideoMuted();
|
65
|
|
- }
|
66
|
|
- },
|
67
|
|
- "?": {
|
68
|
|
- character: "?",
|
69
|
|
- function: function(e) {
|
70
|
|
- JitsiMeetJS.analytics.sendEvent('shortcut.shortcut.help');
|
71
|
|
- APP.UI.toggleKeyboardShortcutsPanel();
|
72
|
|
- }
|
73
|
|
- }
|
74
|
|
- };
|
|
3
|
+/**
|
|
4
|
+ * Initialise global shortcuts.
|
|
5
|
+ * Global shortcuts are shortcuts for features that don't have a button or
|
|
6
|
+ * link associated with the action. In other words they represent actions
|
|
7
|
+ * triggered _only_ with a shortcut.
|
|
8
|
+ */
|
|
9
|
+function initGlobalShortcuts() {
|
|
10
|
+
|
|
11
|
+ KeyboardShortcut.registerShortcut("ESCAPE", null, function() {
|
|
12
|
+ APP.UI.showKeyboardShortcutsPanel(false);
|
|
13
|
+ });
|
|
14
|
+
|
|
15
|
+ KeyboardShortcut.registerShortcut("?", null, function() {
|
|
16
|
+ JitsiMeetJS.analytics.sendEvent("shortcut.shortcut.help");
|
|
17
|
+ APP.UI.toggleKeyboardShortcutsPanel();
|
|
18
|
+ }, "keyboardShortcuts.toggleShortcuts");
|
|
19
|
+
|
|
20
|
+ KeyboardShortcut.registerShortcut("R", null, function() {
|
|
21
|
+ JitsiMeetJS.analytics.sendEvent("shortcut.raisedhand.toggled");
|
|
22
|
+ APP.conference.maybeToggleRaisedHand();
|
|
23
|
+ }, "keyboardShortcuts.raiseHand");
|
|
24
|
+
|
|
25
|
+ KeyboardShortcut.registerShortcut("T", null, function() {
|
|
26
|
+ JitsiMeetJS.analytics.sendEvent("shortcut.talk.clicked");
|
|
27
|
+ APP.conference.muteAudio(true);
|
|
28
|
+ }, "keyboardShortcuts.pushToTalk");
|
|
29
|
+
|
|
30
|
+ /**
|
|
31
|
+ * FIXME: Currently focus keys are directly implemented below in onkeyup.
|
|
32
|
+ * They should be moved to the SmallVideo instead.
|
|
33
|
+ */
|
|
34
|
+ KeyboardShortcut._addShortcutToHelp("0", "keyboardShortcuts.focusLocal");
|
|
35
|
+ KeyboardShortcut._addShortcutToHelp("1-9", "keyboardShortcuts.focusRemote");
|
75
|
36
|
}
|
76
|
37
|
|
|
38
|
+/**
|
|
39
|
+ * Map of shortcuts. When a shortcut is registered it enters the mapping.
|
|
40
|
+ * @type {{}}
|
|
41
|
+ */
|
|
42
|
+let _shortcuts = {};
|
|
43
|
+
|
|
44
|
+/**
|
|
45
|
+ * Maps keycode to character, id of popover for given function and function.
|
|
46
|
+ */
|
77
|
47
|
var KeyboardShortcut = {
|
78
|
48
|
init: function () {
|
79
|
|
- initShortcutHandlers();
|
|
49
|
+ initGlobalShortcuts();
|
|
50
|
+
|
80
|
51
|
var self = this;
|
81
|
52
|
window.onkeyup = function(e) {
|
82
|
|
- var key = self.getKeyboardKey(e).toUpperCase();
|
|
53
|
+ var key = self._getKeyboardKey(e).toUpperCase();
|
83
|
54
|
var num = parseInt(key, 10);
|
84
|
55
|
if(!($(":focus").is("input[type=text]") ||
|
85
|
56
|
$(":focus").is("input[type=password]") ||
|
86
|
57
|
$(":focus").is("textarea"))) {
|
87
|
|
- if (shortcuts.hasOwnProperty(key)) {
|
88
|
|
- shortcuts[key].function(e);
|
|
58
|
+ if (_shortcuts.hasOwnProperty(key)) {
|
|
59
|
+ _shortcuts[key].function(e);
|
89
|
60
|
}
|
90
|
61
|
else if (!isNaN(num) && num >= 0 && num <= 9) {
|
91
|
62
|
APP.UI.clickOnVideo(num + 1);
|
|
@@ -101,7 +72,7 @@ var KeyboardShortcut = {
|
101
|
72
|
if(!($(":focus").is("input[type=text]") ||
|
102
|
73
|
$(":focus").is("input[type=password]") ||
|
103
|
74
|
$(":focus").is("textarea"))) {
|
104
|
|
- var key = self.getKeyboardKey(e).toUpperCase();
|
|
75
|
+ var key = self._getKeyboardKey(e).toUpperCase();
|
105
|
76
|
if(key === "T") {
|
106
|
77
|
if(APP.conference.isLocalAudioMuted())
|
107
|
78
|
APP.conference.muteAudio(false);
|
|
@@ -112,20 +83,58 @@ var KeyboardShortcut = {
|
112
|
83
|
trigger: 'click hover',
|
113
|
84
|
content: function() {
|
114
|
85
|
return this.getAttribute("content") +
|
115
|
|
- self.getShortcut(this.getAttribute("shortcut"));
|
|
86
|
+ self._getShortcut(this.getAttribute("shortcut"));
|
116
|
87
|
}
|
117
|
88
|
});
|
118
|
89
|
},
|
|
90
|
+
|
|
91
|
+ /**
|
|
92
|
+ * Registers a new shortcut.
|
|
93
|
+ *
|
|
94
|
+ * @param shortcutChar the shortcut character triggering the action
|
|
95
|
+ * @param shortcutAttr the "shortcut" html element attribute mappring an
|
|
96
|
+ * element to this shortcut and used to show the shortcut character on the
|
|
97
|
+ * element tooltip
|
|
98
|
+ * @param exec the function to be executed when the shortcut is pressed
|
|
99
|
+ * @param helpDescription the description of the shortcut that would appear
|
|
100
|
+ * in the help menu
|
|
101
|
+ */
|
|
102
|
+ registerShortcut: function( shortcutChar,
|
|
103
|
+ shortcutAttr,
|
|
104
|
+ exec,
|
|
105
|
+ helpDescription) {
|
|
106
|
+ _shortcuts[shortcutChar] = {
|
|
107
|
+ character: shortcutChar,
|
|
108
|
+ shortcutAttr: shortcutAttr,
|
|
109
|
+ function: exec
|
|
110
|
+ };
|
|
111
|
+
|
|
112
|
+ if (helpDescription)
|
|
113
|
+ this._addShortcutToHelp(shortcutChar, helpDescription);
|
|
114
|
+ },
|
|
115
|
+
|
|
116
|
+ /**
|
|
117
|
+ * Unregisters a shortcut.
|
|
118
|
+ *
|
|
119
|
+ * @param shortcutChar unregisters the given shortcut, which means it will
|
|
120
|
+ * no longer be usable
|
|
121
|
+ */
|
|
122
|
+ unregisterShortcut: function(shortcutChar) {
|
|
123
|
+ _shortcuts.remove(shortcutChar);
|
|
124
|
+
|
|
125
|
+ this._removeShortcutFromHelp(shortcutChar);
|
|
126
|
+ },
|
|
127
|
+
|
119
|
128
|
/**
|
120
|
129
|
*
|
121
|
130
|
* @param id indicates the popover associated with the shortcut
|
122
|
131
|
* @returns {string} the keyboard shortcut used for the id given
|
123
|
132
|
*/
|
124
|
|
- getShortcut: function (id) {
|
125
|
|
- for (var key in shortcuts) {
|
126
|
|
- if (shortcuts.hasOwnProperty(key)) {
|
127
|
|
- if (shortcuts[key].id === id) {
|
128
|
|
- return " (" + shortcuts[key].character + ")";
|
|
133
|
+ _getShortcut: function (id) {
|
|
134
|
+ for (var key in _shortcuts) {
|
|
135
|
+ if (_shortcuts.hasOwnProperty(key)) {
|
|
136
|
+ if (_shortcuts[key].shortcutAttr === id) {
|
|
137
|
+ return " (" + _shortcuts[key].character + ")";
|
129
|
138
|
}
|
130
|
139
|
}
|
131
|
140
|
}
|
|
@@ -135,7 +144,7 @@ var KeyboardShortcut = {
|
135
|
144
|
* @param e a KeyboardEvent
|
136
|
145
|
* @returns {string} e.key or something close if not supported
|
137
|
146
|
*/
|
138
|
|
- getKeyboardKey: function (e) {
|
|
147
|
+ _getKeyboardKey: function (e) {
|
139
|
148
|
if (typeof e.key === "string") {
|
140
|
149
|
return e.key;
|
141
|
150
|
}
|
|
@@ -156,6 +165,57 @@ var KeyboardShortcut = {
|
156
|
165
|
} else {
|
157
|
166
|
return String.fromCharCode(e.which).toLowerCase();
|
158
|
167
|
}
|
|
168
|
+ },
|
|
169
|
+
|
|
170
|
+ /**
|
|
171
|
+ * Adds the given shortcut to the help dialog.
|
|
172
|
+ *
|
|
173
|
+ * @param shortcutChar the shortcut character
|
|
174
|
+ * @param shortcutDescriptionKey the description of the shortcut
|
|
175
|
+ * @private
|
|
176
|
+ */
|
|
177
|
+ _addShortcutToHelp: function (shortcutChar, shortcutDescriptionKey) {
|
|
178
|
+
|
|
179
|
+ var listElement = document.createElement("li");
|
|
180
|
+ listElement.id = shortcutChar;
|
|
181
|
+
|
|
182
|
+ var spanElement = document.createElement("span");
|
|
183
|
+ spanElement.className = "item-action";
|
|
184
|
+
|
|
185
|
+ var kbdElement = document.createElement("kbd");
|
|
186
|
+ kbdElement.className = "regular-key";
|
|
187
|
+ kbdElement.innerHTML = shortcutChar;
|
|
188
|
+ spanElement.appendChild(kbdElement);
|
|
189
|
+
|
|
190
|
+ var descriptionElement = document.createElement("span");
|
|
191
|
+ descriptionElement.className = "item-description";
|
|
192
|
+ descriptionElement.setAttribute("data-i18n", shortcutDescriptionKey);
|
|
193
|
+ descriptionElement.innerHTML
|
|
194
|
+ = APP.translation.translateString(shortcutDescriptionKey);
|
|
195
|
+
|
|
196
|
+ listElement.appendChild(spanElement);
|
|
197
|
+ listElement.appendChild(descriptionElement);
|
|
198
|
+
|
|
199
|
+ var parentListElement
|
|
200
|
+ = document.getElementById("keyboard-shortcuts-list");
|
|
201
|
+
|
|
202
|
+ if (parentListElement)
|
|
203
|
+ parentListElement.appendChild(listElement);
|
|
204
|
+ },
|
|
205
|
+
|
|
206
|
+ /**
|
|
207
|
+ * Removes the list element corresponding to the given shortcut from the
|
|
208
|
+ * help dialog
|
|
209
|
+ * @private
|
|
210
|
+ */
|
|
211
|
+ _removeShortcutFromHelp: function (shortcutChar) {
|
|
212
|
+ var parentListElement
|
|
213
|
+ = document.getElementById("keyboard-shortcuts-list");
|
|
214
|
+
|
|
215
|
+ var shortcutElement = document.getElementById(shortcutChar);
|
|
216
|
+
|
|
217
|
+ if (shortcutElement)
|
|
218
|
+ parentListElement.removeChild(shortcutElement);
|
159
|
219
|
}
|
160
|
220
|
};
|
161
|
221
|
|