diff options
Diffstat (limited to 'app/javascript/flavours/glitch/reducers/notifications.js')
-rw-r--r-- | app/javascript/flavours/glitch/reducers/notifications.js | 66 |
1 files changed, 31 insertions, 35 deletions
diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js index fb2b3f549..dc820b476 100644 --- a/app/javascript/flavours/glitch/reducers/notifications.js +++ b/app/javascript/flavours/glitch/reducers/notifications.js @@ -1,10 +1,7 @@ import { NOTIFICATIONS_UPDATE, - NOTIFICATIONS_REFRESH_SUCCESS, NOTIFICATIONS_EXPAND_SUCCESS, - NOTIFICATIONS_REFRESH_REQUEST, NOTIFICATIONS_EXPAND_REQUEST, - NOTIFICATIONS_REFRESH_FAIL, NOTIFICATIONS_EXPAND_FAIL, NOTIFICATIONS_CLEAR, NOTIFICATIONS_SCROLL_TOP, @@ -19,16 +16,16 @@ import { ACCOUNT_BLOCK_SUCCESS, ACCOUNT_MUTE_SUCCESS, } from 'flavours/glitch/actions/accounts'; -import { TIMELINE_DELETE } from 'flavours/glitch/actions/timelines'; +import { TIMELINE_DELETE, TIMELINE_DISCONNECT } from 'flavours/glitch/actions/timelines'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; +import compareId from 'flavours/glitch/util/compare_id'; const initialState = ImmutableMap({ items: ImmutableList(), - next: null, + hasMore: true, top: true, unread: 0, - loaded: false, - isLoading: true, + isLoading: false, cleaningMode: false, // notification removal mark of new notifs loaded whilst cleaningMode is true. markNewForDelete: false, @@ -58,39 +55,38 @@ const normalizeNotification = (state, notification) => { }); }; -const normalizeNotifications = (state, notifications, next) => { - let items = ImmutableList(); - const loaded = state.get('loaded'); +const expandNormalizedNotifications = (state, notifications, next) => { + let items = ImmutableList(); notifications.forEach((n, i) => { items = items.set(i, notificationToMap(state, n)); }); - if (state.get('next') === null) { - state = state.set('next', next); - } + return state.withMutations(mutable => { + if (!items.isEmpty()) { + mutable.update('items', list => { + const lastIndex = 1 + list.findLastIndex( + item => item !== null && (compareId(item.get('id'), items.last().get('id')) > 0 || item.get('id') === items.last().get('id')) + ); - return state - .update('items', list => loaded ? items.concat(list) : list.concat(items)) - .set('loaded', true) - .set('isLoading', false); -}; + const firstIndex = 1 + list.take(lastIndex).findLastIndex( + item => item !== null && compareId(item.get('id'), items.first().get('id')) > 0 + ); -const appendNormalizedNotifications = (state, notifications, next) => { - let items = ImmutableList(); + return list.take(firstIndex).concat(items, list.skip(lastIndex)); + }); + } - notifications.forEach((n, i) => { - items = items.set(i, notificationToMap(state, n)); - }); + if (!next) { + mutable.set('hasMore', true); + } - return state - .update('items', list => list.concat(items)) - .set('next', next) - .set('isLoading', false); + mutable.set('isLoading', false); + }); }; const filterNotifications = (state, relationship) => { - return state.update('items', list => list.filterNot(item => item.get('account') === relationship.id)); + return state.update('items', list => list.filterNot(item => item !== null && item.get('account') === relationship.id)); }; const updateTop = (state, top) => { @@ -102,7 +98,7 @@ const updateTop = (state, top) => { }; const deleteByStatus = (state, statusId) => { - return state.update('items', list => list.filterNot(item => item.get('status') === statusId)); + return state.update('items', list => list.filterNot(item => item !== null && item.get('status') === statusId)); }; const markForDelete = (state, notificationId, yes) => { @@ -137,29 +133,29 @@ export default function notifications(state = initialState, action) { let st; switch(action.type) { - case NOTIFICATIONS_REFRESH_REQUEST: case NOTIFICATIONS_EXPAND_REQUEST: case NOTIFICATIONS_DELETE_MARKED_REQUEST: return state.set('isLoading', true); case NOTIFICATIONS_DELETE_MARKED_FAIL: - case NOTIFICATIONS_REFRESH_FAIL: case NOTIFICATIONS_EXPAND_FAIL: return state.set('isLoading', false); case NOTIFICATIONS_SCROLL_TOP: return updateTop(state, action.top); case NOTIFICATIONS_UPDATE: return normalizeNotification(state, action.notification); - case NOTIFICATIONS_REFRESH_SUCCESS: - return normalizeNotifications(state, action.notifications, action.next); case NOTIFICATIONS_EXPAND_SUCCESS: - return appendNormalizedNotifications(state, action.notifications, action.next); + return expandNormalizedNotifications(state, action.notifications, action.next); case ACCOUNT_BLOCK_SUCCESS: case ACCOUNT_MUTE_SUCCESS: return filterNotifications(state, action.relationship); case NOTIFICATIONS_CLEAR: - return state.set('items', ImmutableList()).set('next', null); + return state.set('items', ImmutableList()).set('hasMore', false); case TIMELINE_DELETE: return deleteByStatus(state, action.id); + case TIMELINE_DISCONNECT: + return action.timeline === 'home' ? + state.update('items', items => items.first() ? items.unshift(null) : items) : + state; case NOTIFICATION_MARK_FOR_DELETE: return markForDelete(state, action.id, action.yes); |