Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

NotificationsTab.tsx 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. import { Theme } from '@mui/material';
  2. import React from 'react';
  3. import { WithTranslation } from 'react-i18next';
  4. import { withStyles } from 'tss-react/mui';
  5. import AbstractDialogTab, {
  6. IProps as AbstractDialogTabProps } from '../../../base/dialog/components/web/AbstractDialogTab';
  7. import { translate } from '../../../base/i18n/functions';
  8. import { withPixelLineHeight } from '../../../base/styles/functions.web';
  9. import Checkbox from '../../../base/ui/components/web/Checkbox';
  10. /**
  11. * The type of the React {@code Component} props of {@link NotificationsTab}.
  12. */
  13. export interface IProps extends AbstractDialogTabProps, WithTranslation {
  14. /**
  15. * CSS classes object.
  16. */
  17. classes?: Partial<Record<keyof ReturnType<typeof styles>, string>>;
  18. /**
  19. * Array of disabled sounds ids.
  20. */
  21. disabledSounds: string[];
  22. /**
  23. * Whether or not the reactions feature is enabled.
  24. */
  25. enableReactions: Boolean;
  26. /**
  27. * The types of enabled notifications that can be configured and their specific visibility.
  28. */
  29. enabledNotifications: Object;
  30. /**
  31. * Whether or not moderator muted the sounds.
  32. */
  33. moderatorMutedSoundsReactions: Boolean;
  34. /**
  35. * Whether or not to display notifications settings.
  36. */
  37. showNotificationsSettings: boolean;
  38. /**
  39. * Whether sound settings should be displayed or not.
  40. */
  41. showSoundsSettings: boolean;
  42. /**
  43. * Whether or not the sound for the incoming message should play.
  44. */
  45. soundsIncomingMessage: Boolean;
  46. /**
  47. * Whether or not the sound for the participant joined should play.
  48. */
  49. soundsParticipantJoined: Boolean;
  50. /**
  51. * Whether or not the sound for the participant entering the lobby should play.
  52. */
  53. soundsParticipantKnocking: Boolean;
  54. /**
  55. * Whether or not the sound for the participant left should play.
  56. */
  57. soundsParticipantLeft: Boolean;
  58. /**
  59. * Whether or not the sound for reactions should play.
  60. */
  61. soundsReactions: Boolean;
  62. /**
  63. * Whether or not the sound for the talk while muted notification should play.
  64. */
  65. soundsTalkWhileMuted: Boolean;
  66. }
  67. const styles = (theme: Theme) => {
  68. return {
  69. container: {
  70. display: 'flex',
  71. width: '100%',
  72. '@media (max-width: 607px)': {
  73. flexDirection: 'column' as const
  74. }
  75. },
  76. column: {
  77. display: 'flex',
  78. flexDirection: 'column' as const,
  79. flex: 1,
  80. '&:first-child:not(:last-child)': {
  81. marginRight: theme.spacing(3),
  82. '@media (max-width: 607px)': {
  83. marginRight: 0,
  84. marginBottom: theme.spacing(3)
  85. }
  86. }
  87. },
  88. title: {
  89. ...withPixelLineHeight(theme.typography.heading6),
  90. color: `${theme.palette.text01} !important`,
  91. marginBottom: theme.spacing(3)
  92. },
  93. checkbox: {
  94. marginBottom: theme.spacing(3)
  95. }
  96. };
  97. };
  98. /**
  99. * React {@code Component} for modifying the local user's sound settings.
  100. *
  101. * @augments Component
  102. */
  103. class NotificationsTab extends AbstractDialogTab<IProps, any> {
  104. /**
  105. * Initializes a new {@code SoundsTab} instance.
  106. *
  107. * @param {IProps} props - The React {@code Component} props to initialize
  108. * the new {@code SoundsTab} instance with.
  109. */
  110. constructor(props: IProps) {
  111. super(props);
  112. // Bind event handlers so they are only bound once for every instance.
  113. this._onChange = this._onChange.bind(this);
  114. this._onEnabledNotificationsChanged = this._onEnabledNotificationsChanged.bind(this);
  115. }
  116. /**
  117. * Changes a sound setting state.
  118. *
  119. * @param {Object} e - The key event to handle.
  120. *
  121. * @returns {void}
  122. */
  123. _onChange({ target }: React.ChangeEvent<HTMLInputElement>) {
  124. super._onChange({ [target.name]: target.checked });
  125. }
  126. /**
  127. * Callback invoked to select if the given type of
  128. * notifications should be shown.
  129. *
  130. * @param {Object} e - The key event to handle.
  131. * @param {string} type - The type of the notification.
  132. *
  133. * @returns {void}
  134. */
  135. _onEnabledNotificationsChanged({ target: { checked } }: React.ChangeEvent<HTMLInputElement>, type: any) {
  136. super._onChange({
  137. enabledNotifications: {
  138. ...this.props.enabledNotifications,
  139. [type]: checked
  140. }
  141. });
  142. }
  143. /**
  144. * Implements React's {@link Component#render()}.
  145. *
  146. * @inheritdoc
  147. * @returns {ReactElement}
  148. */
  149. render() {
  150. const {
  151. disabledSounds,
  152. enabledNotifications,
  153. showNotificationsSettings,
  154. showSoundsSettings,
  155. soundsIncomingMessage,
  156. soundsParticipantJoined,
  157. soundsParticipantKnocking,
  158. soundsParticipantLeft,
  159. soundsTalkWhileMuted,
  160. soundsReactions,
  161. enableReactions,
  162. moderatorMutedSoundsReactions,
  163. t
  164. } = this.props;
  165. const classes = withStyles.getClasses(this.props);
  166. return (
  167. <div
  168. className = { classes.container }
  169. key = 'sounds'>
  170. {showSoundsSettings && (
  171. <div className = { classes.column }>
  172. <h2 className = { classes.title }>
  173. {t('settings.playSounds')}
  174. </h2>
  175. {enableReactions && <Checkbox
  176. checked = { soundsReactions && !disabledSounds.includes('REACTION_SOUND') }
  177. className = { classes.checkbox }
  178. disabled = { Boolean(moderatorMutedSoundsReactions
  179. || disabledSounds.includes('REACTION_SOUND')) }
  180. label = { t('settings.reactions') }
  181. name = 'soundsReactions'
  182. onChange = { this._onChange } />
  183. }
  184. <Checkbox
  185. checked = { soundsIncomingMessage && !disabledSounds.includes('INCOMING_MSG_SOUND') }
  186. className = { classes.checkbox }
  187. disabled = { disabledSounds.includes('INCOMING_MSG_SOUND') }
  188. label = { t('settings.incomingMessage') }
  189. name = 'soundsIncomingMessage'
  190. onChange = { this._onChange } />
  191. <Checkbox
  192. checked = { soundsParticipantJoined
  193. && !disabledSounds.includes('PARTICIPANT_JOINED_SOUND') }
  194. className = { classes.checkbox }
  195. disabled = { disabledSounds.includes('PARTICIPANT_JOINED_SOUND') }
  196. label = { t('settings.participantJoined') }
  197. name = 'soundsParticipantJoined'
  198. onChange = { this._onChange } />
  199. <Checkbox
  200. checked = { soundsParticipantLeft && !disabledSounds.includes('PARTICIPANT_LEFT_SOUND') }
  201. className = { classes.checkbox }
  202. disabled = { disabledSounds.includes('PARTICIPANT_LEFT_SOUND') }
  203. label = { t('settings.participantLeft') }
  204. name = 'soundsParticipantLeft'
  205. onChange = { this._onChange } />
  206. <Checkbox
  207. checked = { soundsTalkWhileMuted && !disabledSounds.includes('TALK_WHILE_MUTED_SOUND') }
  208. className = { classes.checkbox }
  209. disabled = { disabledSounds.includes('TALK_WHILE_MUTED_SOUND') }
  210. label = { t('settings.talkWhileMuted') }
  211. name = 'soundsTalkWhileMuted'
  212. onChange = { this._onChange } />
  213. <Checkbox
  214. checked = { soundsParticipantKnocking
  215. && !disabledSounds.includes('KNOCKING_PARTICIPANT_SOUND') }
  216. className = { classes.checkbox }
  217. disabled = { disabledSounds.includes('KNOCKING_PARTICIPANT_SOUND') }
  218. label = { t('settings.participantKnocking') }
  219. name = 'soundsParticipantKnocking'
  220. onChange = { this._onChange } />
  221. </div>
  222. )}
  223. {showNotificationsSettings && (
  224. <div className = { classes.column }>
  225. <h2 className = { classes.title }>
  226. {t('notify.displayNotifications')}
  227. </h2>
  228. {
  229. Object.keys(enabledNotifications).map(key => (
  230. <Checkbox
  231. checked = { Boolean(enabledNotifications[key as
  232. keyof typeof enabledNotifications]) }
  233. className = { classes.checkbox }
  234. key = { key }
  235. label = { t(key) }
  236. name = { `show-${key}` }
  237. /* eslint-disable-next-line react/jsx-no-bind */
  238. onChange = { e => this._onEnabledNotificationsChanged(e, key) } />
  239. ))
  240. }
  241. </div>
  242. )}
  243. </div>
  244. );
  245. }
  246. }
  247. export default withStyles(translate(NotificationsTab), styles);