notifications.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import {
  2. NOTIFICATIONS_UPDATE,
  3. NOTIFICATIONS_REFRESH_SUCCESS,
  4. NOTIFICATIONS_EXPAND_SUCCESS,
  5. NOTIFICATIONS_REFRESH_REQUEST,
  6. NOTIFICATIONS_EXPAND_REQUEST,
  7. NOTIFICATIONS_REFRESH_FAIL,
  8. NOTIFICATIONS_EXPAND_FAIL,
  9. NOTIFICATIONS_CLEAR,
  10. NOTIFICATIONS_SCROLL_TOP
  11. } from '../actions/notifications';
  12. import { ACCOUNT_BLOCK_SUCCESS } from '../actions/accounts';
  13. import Immutable from 'immutable';
  14. const initialState = Immutable.Map({
  15. items: Immutable.List(),
  16. next: null,
  17. top: true,
  18. unread: 0,
  19. loaded: false,
  20. isLoading: true
  21. });
  22. const notificationToMap = notification => Immutable.Map({
  23. id: notification.id,
  24. type: notification.type,
  25. account: notification.account.id,
  26. status: notification.status ? notification.status.id : null
  27. });
  28. const normalizeNotification = (state, notification) => {
  29. const top = state.get('top');
  30. if (!top) {
  31. state = state.update('unread', unread => unread + 1);
  32. }
  33. return state.update('items', list => {
  34. if (top && list.size > 40) {
  35. list = list.take(20);
  36. }
  37. return list.unshift(notificationToMap(notification));
  38. });
  39. };
  40. const normalizeNotifications = (state, notifications, next) => {
  41. let items = Immutable.List();
  42. const loaded = state.get('loaded');
  43. notifications.forEach((n, i) => {
  44. items = items.set(i, notificationToMap(n));
  45. });
  46. if (state.get('next') === null) {
  47. state = state.set('next', next);
  48. }
  49. return state
  50. .update('items', list => loaded ? items.concat(list) : list.concat(items))
  51. .set('loaded', true)
  52. .set('isLoading', false);
  53. };
  54. const appendNormalizedNotifications = (state, notifications, next) => {
  55. let items = Immutable.List();
  56. notifications.forEach((n, i) => {
  57. items = items.set(i, notificationToMap(n));
  58. });
  59. return state
  60. .update('items', list => list.concat(items))
  61. .set('next', next)
  62. .set('isLoading', false);
  63. };
  64. const filterNotifications = (state, relationship) => {
  65. return state.update('items', list => list.filterNot(item => item.get('account') === relationship.id));
  66. };
  67. const updateTop = (state, top) => {
  68. if (top) {
  69. state = state.set('unread', 0);
  70. }
  71. return state.set('top', top);
  72. };
  73. export default function notifications(state = initialState, action) {
  74. switch(action.type) {
  75. case NOTIFICATIONS_REFRESH_REQUEST:
  76. case NOTIFICATIONS_EXPAND_REQUEST:
  77. case NOTIFICATIONS_REFRESH_FAIL:
  78. case NOTIFICATIONS_EXPAND_FAIL:
  79. return state.set('isLoading', true);
  80. case NOTIFICATIONS_SCROLL_TOP:
  81. return updateTop(state, action.top);
  82. case NOTIFICATIONS_UPDATE:
  83. return normalizeNotification(state, action.notification);
  84. case NOTIFICATIONS_REFRESH_SUCCESS:
  85. return normalizeNotifications(state, action.notifications, action.next);
  86. case NOTIFICATIONS_EXPAND_SUCCESS:
  87. return appendNormalizedNotifications(state, action.notifications, action.next);
  88. case ACCOUNT_BLOCK_SUCCESS:
  89. return filterNotifications(state, action.relationship);
  90. case NOTIFICATIONS_CLEAR:
  91. return state.set('items', Immutable.List()).set('next', null);
  92. default:
  93. return state;
  94. }
  95. };