選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

reducer.js 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import { ReducerRegistry } from '../base/redux';
  2. import {
  3. CLEAR_NOTIFICATIONS,
  4. HIDE_NOTIFICATION,
  5. SET_NOTIFICATIONS_ENABLED,
  6. SHOW_NOTIFICATION
  7. } from './actionTypes';
  8. import { NOTIFICATION_TYPE_PRIORITIES } from './constants';
  9. /**
  10. * The initial state of the feature notifications.
  11. *
  12. * @type {array}
  13. */
  14. const DEFAULT_STATE = {
  15. enabled: true,
  16. notifications: []
  17. };
  18. /**
  19. * Reduces redux actions which affect the display of notifications.
  20. *
  21. * @param {Object} state - The current redux state.
  22. * @param {Object} action - The redux action to reduce.
  23. * @returns {Object} The next redux state which is the result of reducing the
  24. * specified {@code action}.
  25. */
  26. ReducerRegistry.register('features/notifications',
  27. (state = DEFAULT_STATE, action) => {
  28. switch (action.type) {
  29. case CLEAR_NOTIFICATIONS:
  30. return {
  31. ...state,
  32. notifications: []
  33. };
  34. case HIDE_NOTIFICATION:
  35. return {
  36. ...state,
  37. notifications: state.notifications.filter(
  38. notification => notification.uid !== action.uid)
  39. };
  40. case SET_NOTIFICATIONS_ENABLED:
  41. return {
  42. ...state,
  43. enabled: action.enabled
  44. };
  45. case SHOW_NOTIFICATION:
  46. return {
  47. ...state,
  48. notifications:
  49. _insertNotificationByPriority(state.notifications, {
  50. component: action.component,
  51. props: action.props,
  52. timeout: action.timeout,
  53. uid: action.uid
  54. })
  55. };
  56. }
  57. return state;
  58. });
  59. /**
  60. * Creates a new notification queue with the passed in notification placed at
  61. * the end of other notifications with higher or the same priority.
  62. *
  63. * @param {Object[]} notifications - The queue of notifications to be displayed.
  64. * @param {Object} notification - The new notification to add to the queue.
  65. * @private
  66. * @returns {Object[]} A new array with an updated order of the notification
  67. * queue.
  68. */
  69. function _insertNotificationByPriority(notifications, notification) {
  70. const newNotificationPriority
  71. = NOTIFICATION_TYPE_PRIORITIES[notification.props.appearance] || 0;
  72. // Default to putting the new notification at the end of the queue.
  73. let insertAtLocation = notifications.length;
  74. // Find where to insert the new notification based on priority. Do not
  75. // insert at the front of the queue so that the user can finish acting on
  76. // any notification currently being read.
  77. for (let i = 1; i < notifications.length; i++) {
  78. const queuedNotification = notifications[i];
  79. const queuedNotificationPriority
  80. = NOTIFICATION_TYPE_PRIORITIES[queuedNotification.props.appearance]
  81. || 0;
  82. if (queuedNotificationPriority < newNotificationPriority) {
  83. insertAtLocation = i;
  84. break;
  85. }
  86. }
  87. // Create a copy to avoid mutation and insert the notification.
  88. const copyOfNotifications = notifications.slice();
  89. copyOfNotifications.splice(insertAtLocation, 0, notification);
  90. return copyOfNotifications;
  91. }