您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

reducer.ts 3.9KB

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