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.

ShortcutsTab.tsx 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import { Theme } from '@mui/material';
  2. import { withStyles } from '@mui/styles';
  3. import React from 'react';
  4. import { WithTranslation } from 'react-i18next';
  5. // @ts-expect-error
  6. import keyboardShortcut from '../../../../../modules/keyboardshortcut/keyboardshortcut';
  7. import AbstractDialogTab, {
  8. IProps as AbstractDialogTabProps } from '../../../base/dialog/components/web/AbstractDialogTab';
  9. import { translate } from '../../../base/i18n/functions';
  10. import { withPixelLineHeight } from '../../../base/styles/functions.web';
  11. import Checkbox from '../../../base/ui/components/web/Checkbox';
  12. /**
  13. * The type of the React {@code Component} props of {@link ShortcutsTab}.
  14. */
  15. export interface IProps extends AbstractDialogTabProps, WithTranslation {
  16. /**
  17. * CSS classes object.
  18. */
  19. classes: any;
  20. /**
  21. * Whether to display the shortcuts or not.
  22. */
  23. displayShortcuts: boolean;
  24. /**
  25. * Wether the keyboard shortcuts are enabled or not.
  26. */
  27. keyboardShortcutsEnabled: boolean;
  28. }
  29. const styles = (theme: Theme) => {
  30. return {
  31. container: {
  32. display: 'flex',
  33. flexDirection: 'column' as const,
  34. width: '100%',
  35. paddingBottom: theme.spacing(3)
  36. },
  37. checkbox: {
  38. marginBottom: theme.spacing(3)
  39. },
  40. listContainer: {
  41. listStyleType: 'none',
  42. padding: 0,
  43. margin: 0
  44. },
  45. listItem: {
  46. display: 'flex',
  47. justifyContent: 'space-between',
  48. alignItems: 'center',
  49. padding: `${theme.spacing(1)} 0`,
  50. ...withPixelLineHeight(theme.typography.bodyShortRegular),
  51. color: theme.palette.text01
  52. },
  53. listItemKey: {
  54. backgroundColor: theme.palette.ui04,
  55. ...withPixelLineHeight(theme.typography.labelBold),
  56. padding: `${theme.spacing(1)} ${theme.spacing(2)}`,
  57. borderRadius: `${Number(theme.shape.borderRadius) / 2}px`
  58. }
  59. };
  60. };
  61. /**
  62. * React {@code Component} for modifying the local user's profile.
  63. *
  64. * @augments Component
  65. */
  66. class ShortcutsTab extends AbstractDialogTab<IProps, any> {
  67. /**
  68. * Initializes a new {@code MoreTab} instance.
  69. *
  70. * @param {Object} props - The read-only properties with which the new
  71. * instance is to be initialized.
  72. */
  73. constructor(props: IProps) {
  74. super(props);
  75. // Bind event handler so it is only bound once for every instance.
  76. this._onKeyboardShortcutEnableChanged = this._onKeyboardShortcutEnableChanged.bind(this);
  77. this._renderShortcutsListItem = this._renderShortcutsListItem.bind(this);
  78. }
  79. /**
  80. * Callback invoked to select if global keyboard shortcuts
  81. * should be enabled.
  82. *
  83. * @param {Object} e - The key event to handle.
  84. *
  85. * @returns {void}
  86. */
  87. _onKeyboardShortcutEnableChanged({ target: { checked } }: React.ChangeEvent<HTMLInputElement>) {
  88. super._onChange({ keyboardShortcutsEnabled: checked });
  89. }
  90. /**
  91. * Render a keyboard shortcut with key and description.
  92. *
  93. * @param {string} keyboardKey - The keyboard key for the shortcut.
  94. * @param {string} translationKey - The translation key for the shortcut description.
  95. * @returns {JSX}
  96. */
  97. _renderShortcutsListItem(keyboardKey: string, translationKey: string) {
  98. const { classes, t } = this.props;
  99. let modifierKey = 'Alt';
  100. if (window.navigator?.platform) {
  101. if (window.navigator.platform.indexOf('Mac') !== -1) {
  102. modifierKey = '⌥';
  103. }
  104. }
  105. return (
  106. <li
  107. className = { classes.listItem }
  108. key = { keyboardKey }>
  109. <span
  110. aria-label = { t(translationKey) }>
  111. {t(translationKey)}
  112. </span>
  113. <span className = { classes.listItemKey }>
  114. {keyboardKey.startsWith(':')
  115. ? `${modifierKey} + ${keyboardKey.slice(1)}`
  116. : keyboardKey}
  117. </span>
  118. </li>
  119. );
  120. }
  121. /**
  122. * Implements React's {@link Component#render()}.
  123. *
  124. * @inheritdoc
  125. * @returns {ReactElement}
  126. */
  127. render() {
  128. const {
  129. classes,
  130. displayShortcuts,
  131. keyboardShortcutsEnabled,
  132. t
  133. } = this.props;
  134. const shortcutDescriptions: Map<string, string> = displayShortcuts
  135. ? keyboardShortcut.getShortcutsDescriptions()
  136. : new Map();
  137. return (
  138. <div className = { classes.container }>
  139. <Checkbox
  140. checked = { keyboardShortcutsEnabled }
  141. className = { classes.checkbox }
  142. label = { t('prejoin.keyboardShortcuts') }
  143. name = 'enable-keyboard-shortcuts'
  144. onChange = { this._onKeyboardShortcutEnableChanged } />
  145. {displayShortcuts && (
  146. <ul className = { classes.listContainer }>
  147. {Array.from(shortcutDescriptions)
  148. .map(description => this._renderShortcutsListItem(...description))}
  149. </ul>
  150. )}
  151. </div>
  152. );
  153. }
  154. }
  155. export default withStyles(styles)(translate(ShortcutsTab));