You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

actions.web.ts 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { batch } from 'react-redux';
  2. import { ACTION_SHORTCUT_PRESSED, ACTION_SHORTCUT_RELEASED, createShortcutEvent } from '../analytics/AnalyticsEvents';
  3. import { sendAnalytics } from '../analytics/functions';
  4. import { IStore } from '../app/types';
  5. import { clickOnVideo } from '../filmstrip/actions.web';
  6. import { openSettingsDialog } from '../settings/actions.web';
  7. import { SETTINGS_TABS } from '../settings/constants';
  8. import { iAmVisitor } from '../visitors/functions';
  9. import { registerShortcut } from './actions.any';
  10. import { areKeyboardShortcutsEnabled, getKeyboardShortcuts } from './functions';
  11. import logger from './logger';
  12. import { getKeyboardKey, getPriorityFocusedElement } from './utils';
  13. export * from './actions.any';
  14. /**
  15. * Initialise global shortcuts.
  16. * Global shortcuts are shortcuts for features that don't have a button or
  17. * link associated with the action. In other words they represent actions
  18. * triggered _only_ with a shortcut.
  19. *
  20. * @returns {Function}
  21. */
  22. const initGlobalKeyboardShortcuts = () =>
  23. (dispatch: IStore['dispatch']) => {
  24. batch(() => {
  25. dispatch(registerShortcut({
  26. character: '?',
  27. helpDescription: 'keyboardShortcuts.toggleShortcuts',
  28. handler: () => {
  29. sendAnalytics(createShortcutEvent('help'));
  30. dispatch(openSettingsDialog(SETTINGS_TABS.SHORTCUTS, false));
  31. }
  32. }));
  33. // register SPACE shortcut in two steps to insure visibility of help message
  34. dispatch(registerShortcut({
  35. character: ' ',
  36. helpCharacter: 'SPACE',
  37. helpDescription: 'keyboardShortcuts.pushToTalk',
  38. handler: () => {
  39. sendAnalytics(createShortcutEvent('push.to.talk', ACTION_SHORTCUT_RELEASED));
  40. logger.log('Talk shortcut released');
  41. APP.conference.muteAudio(true);
  42. }
  43. }));
  44. dispatch(registerShortcut({
  45. character: '0',
  46. helpDescription: 'keyboardShortcuts.focusLocal',
  47. handler: () => {
  48. dispatch(clickOnVideo(0));
  49. }
  50. }));
  51. Array(9).fill(1)
  52. .forEach((_, index) => {
  53. const num = index + 1;
  54. dispatch(registerShortcut({
  55. character: `${num}`,
  56. // only show help hint for the first shortcut
  57. helpCharacter: num === 1 ? '1-9' : undefined,
  58. helpDescription: num === 1 ? 'keyboardShortcuts.focusRemote' : undefined,
  59. handler: () => {
  60. dispatch(clickOnVideo(num));
  61. }
  62. }));
  63. });
  64. });
  65. };
  66. /**
  67. * Initializes keyboard shortcuts.
  68. *
  69. * @returns {Function}
  70. */
  71. export const initKeyboardShortcuts = () =>
  72. (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
  73. dispatch(initGlobalKeyboardShortcuts());
  74. window.onkeyup = (e: KeyboardEvent) => {
  75. const state = getState();
  76. const enabled = areKeyboardShortcutsEnabled(state);
  77. const shortcuts = getKeyboardShortcuts(state);
  78. if (!enabled || getPriorityFocusedElement()) {
  79. return;
  80. }
  81. const key = getKeyboardKey(e).toUpperCase();
  82. if (shortcuts.has(key)) {
  83. shortcuts.get(key)?.handler(e);
  84. }
  85. };
  86. window.onkeydown = (e: KeyboardEvent) => {
  87. const state = getState();
  88. const enabled = areKeyboardShortcutsEnabled(state);
  89. if (!enabled || iAmVisitor(state)) {
  90. return;
  91. }
  92. const focusedElement = getPriorityFocusedElement();
  93. const key = getKeyboardKey(e).toUpperCase();
  94. if (key === ' ' && !focusedElement) {
  95. sendAnalytics(createShortcutEvent('push.to.talk', ACTION_SHORTCUT_PRESSED));
  96. logger.log('Talk shortcut pressed');
  97. APP.conference.muteAudio(false);
  98. } else if (key === 'ESCAPE') {
  99. focusedElement?.blur();
  100. }
  101. };
  102. };