The code powering m.abunchtell.com https://m.abunchtell.com
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.
 
 
 
 

122 lines
3.5 KiB

  1. import {
  2. NOTIFICATIONS_UPDATE,
  3. NOTIFICATIONS_EXPAND_SUCCESS,
  4. NOTIFICATIONS_EXPAND_REQUEST,
  5. NOTIFICATIONS_EXPAND_FAIL,
  6. NOTIFICATIONS_CLEAR,
  7. NOTIFICATIONS_SCROLL_TOP,
  8. } from '../actions/notifications';
  9. import {
  10. ACCOUNT_BLOCK_SUCCESS,
  11. ACCOUNT_MUTE_SUCCESS,
  12. } from '../actions/accounts';
  13. import { TIMELINE_DELETE, TIMELINE_DISCONNECT } from '../actions/timelines';
  14. import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
  15. import compareId from '../compare_id';
  16. const initialState = ImmutableMap({
  17. items: ImmutableList(),
  18. hasMore: true,
  19. top: true,
  20. unread: 0,
  21. isLoading: false,
  22. });
  23. const notificationToMap = notification => ImmutableMap({
  24. id: notification.id,
  25. type: notification.type,
  26. account: notification.account.id,
  27. created_at: notification.created_at,
  28. status: notification.status ? notification.status.id : null,
  29. });
  30. const normalizeNotification = (state, notification) => {
  31. const top = state.get('top');
  32. if (!top) {
  33. state = state.update('unread', unread => unread + 1);
  34. }
  35. return state.update('items', list => {
  36. if (top && list.size > 40) {
  37. list = list.take(20);
  38. }
  39. return list.unshift(notificationToMap(notification));
  40. });
  41. };
  42. const expandNormalizedNotifications = (state, notifications, next) => {
  43. let items = ImmutableList();
  44. notifications.forEach((n, i) => {
  45. items = items.set(i, notificationToMap(n));
  46. });
  47. return state.withMutations(mutable => {
  48. if (!items.isEmpty()) {
  49. mutable.update('items', list => {
  50. const lastIndex = 1 + list.findLastIndex(
  51. item => item !== null && (compareId(item.get('id'), items.last().get('id')) > 0 || item.get('id') === items.last().get('id'))
  52. );
  53. const firstIndex = 1 + list.take(lastIndex).findLastIndex(
  54. item => item !== null && compareId(item.get('id'), items.first().get('id')) > 0
  55. );
  56. return list.take(firstIndex).concat(items, list.skip(lastIndex));
  57. });
  58. }
  59. if (!next) {
  60. mutable.set('hasMore', false);
  61. }
  62. mutable.set('isLoading', false);
  63. });
  64. };
  65. const filterNotifications = (state, relationship) => {
  66. return state.update('items', list => list.filterNot(item => item !== null && item.get('account') === relationship.id));
  67. };
  68. const updateTop = (state, top) => {
  69. if (top) {
  70. state = state.set('unread', 0);
  71. }
  72. return state.set('top', top);
  73. };
  74. const deleteByStatus = (state, statusId) => {
  75. return state.update('items', list => list.filterNot(item => item !== null && item.get('status') === statusId));
  76. };
  77. export default function notifications(state = initialState, action) {
  78. switch(action.type) {
  79. case NOTIFICATIONS_EXPAND_REQUEST:
  80. return state.set('isLoading', true);
  81. case NOTIFICATIONS_EXPAND_FAIL:
  82. return state.set('isLoading', false);
  83. case NOTIFICATIONS_SCROLL_TOP:
  84. return updateTop(state, action.top);
  85. case NOTIFICATIONS_UPDATE:
  86. return normalizeNotification(state, action.notification);
  87. case NOTIFICATIONS_EXPAND_SUCCESS:
  88. return expandNormalizedNotifications(state, action.notifications, action.next);
  89. case ACCOUNT_BLOCK_SUCCESS:
  90. case ACCOUNT_MUTE_SUCCESS:
  91. return action.relationship.muting_notifications ? filterNotifications(state, action.relationship) : state;
  92. case NOTIFICATIONS_CLEAR:
  93. return state.set('items', ImmutableList()).set('hasMore', false);
  94. case TIMELINE_DELETE:
  95. return deleteByStatus(state, action.id);
  96. case TIMELINE_DISCONNECT:
  97. return action.timeline === 'home' ?
  98. state.update('items', items => items.first() ? items.unshift(null) : items) :
  99. state;
  100. default:
  101. return state;
  102. }
  103. };