logo

mastofe

My custom branche(s) on git.pleroma.social/pleroma/mastofe git clone https://hacktivis.me/git/mastofe.git

notifications.js (3600B)


  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. const initialState = ImmutableMap({
  16. items: ImmutableList(),
  17. hasMore: true,
  18. top: true,
  19. unread: 0,
  20. isLoading: false,
  21. });
  22. const notificationToMap = notification => ImmutableMap({
  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 newer = (m, n) => {
  41. const mId = m.get('id');
  42. const nId = n.get('id');
  43. return mId.length === nId.length ? mId > nId : mId.length > nId.length;
  44. };
  45. const expandNormalizedNotifications = (state, notifications, next) => {
  46. let items = ImmutableList();
  47. notifications.forEach((n, i) => {
  48. items = items.set(i, notificationToMap(n));
  49. });
  50. return state.withMutations(mutable => {
  51. if (!items.isEmpty()) {
  52. mutable.update('items', list => {
  53. const lastIndex = 1 + list.findLastIndex(
  54. item => item !== null && (newer(item, items.last()) || item.get('id') === items.last().get('id'))
  55. );
  56. const firstIndex = 1 + list.take(lastIndex).findLastIndex(
  57. item => item !== null && newer(item, items.first())
  58. );
  59. return list.take(firstIndex).concat(items, list.skip(lastIndex));
  60. });
  61. }
  62. if (!next) {
  63. mutable.set('hasMore', true);
  64. }
  65. mutable.set('isLoading', false);
  66. });
  67. };
  68. const filterNotifications = (state, relationship) => {
  69. return state.update('items', list => list.filterNot(item => item !== null && item.get('account') === relationship.id));
  70. };
  71. const updateTop = (state, top) => {
  72. if (top) {
  73. state = state.set('unread', 0);
  74. }
  75. return state.set('top', top);
  76. };
  77. const deleteByStatus = (state, statusId) => {
  78. return state.update('items', list => list.filterNot(item => item !== null && item.get('status') === statusId));
  79. };
  80. export default function notifications(state = initialState, action) {
  81. switch(action.type) {
  82. case NOTIFICATIONS_EXPAND_REQUEST:
  83. return state.set('isLoading', true);
  84. case NOTIFICATIONS_EXPAND_FAIL:
  85. return state.set('isLoading', false);
  86. case NOTIFICATIONS_SCROLL_TOP:
  87. return updateTop(state, action.top);
  88. case NOTIFICATIONS_UPDATE:
  89. return normalizeNotification(state, action.notification);
  90. case NOTIFICATIONS_EXPAND_SUCCESS:
  91. return expandNormalizedNotifications(state, action.notifications, action.next);
  92. case ACCOUNT_BLOCK_SUCCESS:
  93. case ACCOUNT_MUTE_SUCCESS:
  94. return filterNotifications(state, action.relationship);
  95. case NOTIFICATIONS_CLEAR:
  96. return state.set('items', ImmutableList()).set('hasMore', false);
  97. case TIMELINE_DELETE:
  98. return deleteByStatus(state, action.id);
  99. case TIMELINE_DISCONNECT:
  100. return action.timeline === 'home' ?
  101. state.update('items', items => items.first() ? items.unshift(null) : items) :
  102. state;
  103. default:
  104. return state;
  105. }
  106. };