Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

reducer.ts 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // @ts-ignore
  2. import type { AudioElement } from '../media';
  3. import ReducerRegistry from '../redux/ReducerRegistry';
  4. import { assign } from '../redux/functions';
  5. import {
  6. REGISTER_SOUND,
  7. UNREGISTER_SOUND,
  8. _ADD_AUDIO_ELEMENT,
  9. _REMOVE_AUDIO_ELEMENT
  10. } from './actionTypes';
  11. import logger from './logger';
  12. /**
  13. * The structure use by this reducer to describe a sound.
  14. */
  15. export type Sound = {
  16. /**
  17. * The HTMLAudioElement which implements the audio playback functionality.
  18. * Becomes available once the sound resource gets loaded and the sound can
  19. * not be played until that happens.
  20. */
  21. audioElement?: AudioElement;
  22. /**
  23. * This field is container for all optional parameters related to the sound.
  24. */
  25. options?: Object;
  26. /**
  27. * This field describes the source of the audio resource to be played. It
  28. * can be either a path to the file or an object depending on the platform
  29. * (native vs web).
  30. */
  31. src?: Object | string;
  32. };
  33. /**
  34. * Initial/default state of the feature {@code base/sounds}. It is a {@code Map}
  35. * of globally stored sounds.
  36. *
  37. * @type {Map<string, Sound>}
  38. */
  39. const DEFAULT_STATE = new Map();
  40. export type ISoundsState = Map<string, Sound>;
  41. /**
  42. * The base/sounds feature's reducer.
  43. */
  44. ReducerRegistry.register<ISoundsState>(
  45. 'features/base/sounds',
  46. (state = DEFAULT_STATE, action): ISoundsState => {
  47. switch (action.type) {
  48. case _ADD_AUDIO_ELEMENT:
  49. case _REMOVE_AUDIO_ELEMENT:
  50. return _addOrRemoveAudioElement(state, action);
  51. case REGISTER_SOUND:
  52. return _registerSound(state, action);
  53. case UNREGISTER_SOUND:
  54. return _unregisterSound(state, action);
  55. default:
  56. return state;
  57. }
  58. });
  59. /**
  60. * Adds or removes {@link AudioElement} associated with a {@link Sound}.
  61. *
  62. * @param {Map<string, Sound>} state - The current Redux state of this feature.
  63. * @param {_ADD_AUDIO_ELEMENT | _REMOVE_AUDIO_ELEMENT} action - The action to be
  64. * handled.
  65. * @private
  66. * @returns {Map<string, Sound>}
  67. */
  68. function _addOrRemoveAudioElement(state: ISoundsState, action: any) {
  69. const isAddAction = action.type === _ADD_AUDIO_ELEMENT;
  70. const nextState = new Map(state);
  71. const { soundId } = action;
  72. const sound = nextState.get(soundId);
  73. if (sound) {
  74. if (isAddAction) {
  75. nextState.set(soundId,
  76. assign(sound, {
  77. audioElement: action.audioElement
  78. }));
  79. } else {
  80. nextState.set(soundId,
  81. assign(sound, {
  82. audioElement: undefined
  83. }));
  84. }
  85. } else {
  86. logger.warn(`${action.type}: no sound for id: ${soundId}`);
  87. }
  88. return nextState;
  89. }
  90. /**
  91. * Registers a new {@link Sound} for given id and source. It will make
  92. * the {@link SoundCollection} component render HTMLAudioElement for given
  93. * source making it available for playback through the redux actions.
  94. *
  95. * @param {Map<string, Sound>} state - The current Redux state of the sounds
  96. * features.
  97. * @param {REGISTER_SOUND} action - The register sound action.
  98. * @private
  99. * @returns {Map<string, Sound>}
  100. */
  101. function _registerSound(state: ISoundsState, action: any) {
  102. const nextState = new Map(state);
  103. nextState.set(action.soundId, {
  104. src: action.src,
  105. options: action.options
  106. });
  107. return nextState;
  108. }
  109. /**
  110. * Unregisters a {@link Sound} which will make the {@link SoundCollection}
  111. * component stop rendering the corresponding HTMLAudioElement. This will
  112. * result further in the audio resource disposal.
  113. *
  114. * @param {Map<string, Sound>} state - The current Redux state of this feature.
  115. * @param {UNREGISTER_SOUND} action - The unregister sound action.
  116. * @private
  117. * @returns {Map<string, Sound>}
  118. */
  119. function _unregisterSound(state: ISoundsState, action: any) {
  120. const nextState = new Map(state);
  121. nextState.delete(action.soundId);
  122. return nextState;
  123. }