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.

middleware.any.ts 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import i18next from 'i18next';
  2. import { registerE2eeAudioFiles } from '../../../features/e2ee/functions';
  3. import { registerRecordingAudioFiles } from '../../../features/recording/functions';
  4. import { IStore } from '../../app/types';
  5. import { AudioSupportedLanguage } from '../media/constants';
  6. import MiddlewareRegistry from '../redux/MiddlewareRegistry';
  7. import StateListenerRegistry from '../redux/StateListenerRegistry';
  8. import { PLAY_SOUND, STOP_SOUND } from './actionTypes';
  9. import logger from './logger';
  10. /**
  11. * Implements the entry point of the middleware of the feature base/sounds.
  12. *
  13. * @param {Store} store - The redux store.
  14. * @returns {Function}
  15. */
  16. MiddlewareRegistry.register(store => next => action => {
  17. switch (action.type) {
  18. case PLAY_SOUND:
  19. _playSound(store, action.soundId);
  20. break;
  21. case STOP_SOUND:
  22. _stopSound(store, action.soundId);
  23. break;
  24. }
  25. return next(action);
  26. });
  27. /**
  28. * Plays sound from audio element registered in the Redux store.
  29. *
  30. * @param {Store} store - The Redux store instance.
  31. * @param {string} soundId - Audio element identifier.
  32. * @private
  33. * @returns {void}
  34. */
  35. function _playSound({ getState }: IStore, soundId: string) {
  36. const sounds = getState()['features/base/sounds'];
  37. const sound = sounds.get(soundId);
  38. if (sound) {
  39. if (sound.audioElement) {
  40. sound.audioElement.play();
  41. } else {
  42. logger.warn(`PLAY_SOUND: sound not loaded yet for id: ${soundId}`);
  43. }
  44. } else {
  45. logger.warn(`PLAY_SOUND: no sound found for id: ${soundId}`);
  46. }
  47. }
  48. /**
  49. * Stop sound from audio element registered in the Redux store.
  50. *
  51. * @param {Store} store - The Redux store instance.
  52. * @param {string} soundId - Audio element identifier.
  53. * @private
  54. * @returns {void}
  55. */
  56. function _stopSound({ getState }: IStore, soundId: string) {
  57. const sounds = getState()['features/base/sounds'];
  58. const sound = sounds.get(soundId);
  59. if (sound) {
  60. const { audioElement } = sound;
  61. if (audioElement) {
  62. audioElement.stop();
  63. } else {
  64. logger.warn(`STOP_SOUND: sound not loaded yet for id: ${soundId}`);
  65. }
  66. } else {
  67. logger.warn(`STOP_SOUND: no sound found for id: ${soundId}`);
  68. }
  69. }
  70. /**
  71. * Returns whether the language is supported for audio messages.
  72. *
  73. * @param {string} language - The requested language.
  74. * @returns {boolean}
  75. */
  76. function isLanguageSupported(language: string): Boolean {
  77. return Boolean(AudioSupportedLanguage[language as keyof typeof AudioSupportedLanguage]);
  78. }
  79. /**
  80. * Checking if it's necessary to reload the translated files.
  81. *
  82. * @param {string} language - The next language.
  83. * @param {string} prevLanguage - The previous language.
  84. * @returns {boolean}
  85. */
  86. function shouldReloadAudioFiles(language: string, prevLanguage: string): Boolean {
  87. const isNextLanguageSupported = isLanguageSupported(language);
  88. const isPrevLanguageSupported = isLanguageSupported(prevLanguage);
  89. return (
  90. // From an unsupported language (which defaulted to English) to a supported language (that isn't English).
  91. isNextLanguageSupported && language !== AudioSupportedLanguage.en && !isPrevLanguageSupported
  92. ) || (
  93. // From a supported language (that wasn't English) to English.
  94. !isNextLanguageSupported && isPrevLanguageSupported && prevLanguage !== AudioSupportedLanguage.en
  95. ) || (
  96. // From a supported language to another.
  97. isNextLanguageSupported && isPrevLanguageSupported
  98. );
  99. }
  100. /**
  101. * Set up state change listener for language.
  102. */
  103. StateListenerRegistry.register(
  104. () => i18next.language,
  105. (language, { dispatch }, prevLanguage): void => {
  106. if (language !== prevLanguage && shouldReloadAudioFiles(language, prevLanguage)) {
  107. registerE2eeAudioFiles(dispatch, true);
  108. registerRecordingAudioFiles(dispatch, true);
  109. }
  110. }
  111. );