diff options
author | Thibaut Girka <thib@sitedethib.com> | 2018-05-27 19:30:52 +0200 |
---|---|---|
committer | ThibG <thib@sitedethib.com> | 2018-05-29 21:25:28 +0200 |
commit | 4eba8c50c31d70f466a68d48445f86d644e4a889 (patch) | |
tree | e9f7f44ef62c4f0c1f8d4de38ca43f4337e8f6ca /app/javascript/flavours/glitch/reducers | |
parent | 0ad3eedd4cf6d1d7f7ceacc2c4412dbd8ee79cef (diff) |
[Glitch] Allow clients to fetch notifications made while they were offline
Port cbf97c03bba35a642e6f1d1a698aad7a69ad13a3 to glitch-soc
Diffstat (limited to 'app/javascript/flavours/glitch/reducers')
-rw-r--r-- | app/javascript/flavours/glitch/reducers/notifications.js | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js index fb2b3f549..1946fc071 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,15 @@ 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'; 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,35 +54,41 @@ const normalizeNotification = (state, notification) => { }); }; -const normalizeNotifications = (state, notifications, next) => { - let items = ImmutableList(); - const loaded = state.get('loaded'); +const newer = (m, n) => { + const mId = m.get('id'); + const nId = n.get('id'); - notifications.forEach((n, i) => { - items = items.set(i, notificationToMap(state, n)); - }); - - if (state.get('next') === null) { - state = state.set('next', next); - } - - return state - .update('items', list => loaded ? items.concat(list) : list.concat(items)) - .set('loaded', true) - .set('isLoading', false); + return mId.length === nId.length ? mId > nId : mId.length > nId.length; }; -const appendNormalizedNotifications = (state, notifications, next) => { +const expandNormalizedNotifications = (state, notifications, next) => { let items = ImmutableList(); notifications.forEach((n, i) => { items = items.set(i, notificationToMap(state, n)); }); - return state - .update('items', list => list.concat(items)) - .set('next', next) - .set('isLoading', false); + return state.withMutations(mutable => { + if (!items.isEmpty()) { + mutable.update('items', list => { + const lastIndex = 1 + list.findLastIndex( + item => item !== null && (newer(item, items.last()) || item.get('id') === items.last().get('id')) + ); + + const firstIndex = 1 + list.take(lastIndex).findLastIndex( + item => item !== null && newer(item, items.first()) + ); + + return list.take(firstIndex).concat(items, list.skip(lastIndex)); + }); + } + + if (!next) { + mutable.set('hasMore', true); + } + + mutable.set('isLoading', false); + }); }; const filterNotifications = (state, relationship) => { @@ -137,29 +139,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); |