0
0
Fork 0

Allow clients to fetch statuses made while they were offline (#6876)

This commit is contained in:
Akihiko Odaki 2018-03-24 23:25:15 +09:00 committed by Eugen Rochko
parent 59657e24b9
commit 9a1a55ce52
22 changed files with 191 additions and 259 deletions

View file

@ -1,14 +1,10 @@
import {
TIMELINE_REFRESH_REQUEST,
TIMELINE_REFRESH_SUCCESS,
TIMELINE_REFRESH_FAIL,
TIMELINE_UPDATE,
TIMELINE_DELETE,
TIMELINE_EXPAND_SUCCESS,
TIMELINE_EXPAND_REQUEST,
TIMELINE_EXPAND_FAIL,
TIMELINE_SCROLL_TOP,
TIMELINE_CONNECT,
TIMELINE_DISCONNECT,
} from '../actions/timelines';
import {
@ -22,37 +18,33 @@ const initialState = ImmutableMap();
const initialTimeline = ImmutableMap({
unread: 0,
online: false,
top: true,
loaded: false,
isLoading: false,
next: false,
hasMore: true,
items: ImmutableList(),
});
const normalizeTimeline = (state, timeline, statuses, next, isPartial) => {
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
const ids = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
const wasLoaded = state.getIn([timeline, 'loaded']);
const hadNext = state.getIn([timeline, 'next']);
return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
mMap.set('loaded', true);
mMap.set('isLoading', false);
if (!hadNext) mMap.set('next', next);
mMap.set('items', wasLoaded ? ids.concat(oldIds) : oldIds.concat(ids));
mMap.set('isPartial', isPartial);
}));
};
const appendNormalizedTimeline = (state, timeline, statuses, next) => {
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
const ids = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial) => {
return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
mMap.set('isLoading', false);
mMap.set('next', next);
mMap.set('items', oldIds.concat(ids));
if (!next) mMap.set('hasMore', false);
if (!statuses.isEmpty()) {
mMap.update('items', ImmutableList(), oldIds => {
const newIds = statuses.map(status => status.get('id'));
const lastIndex = oldIds.findLastIndex(id => id !== null && id >= newIds.last()) + 1;
const firstIndex = oldIds.take(lastIndex).findLastIndex(id => id !== null && id > newIds.first());
if (firstIndex < 0) {
return (isPartial ? newIds.unshift(null) : newIds).concat(oldIds.skip(lastIndex));
}
return oldIds.take(firstIndex + 1).concat(
isPartial && oldIds.get(firstIndex) !== null ? newIds.unshift(null) : newIds,
oldIds.skip(lastIndex)
);
});
}
}));
};
@ -118,16 +110,12 @@ const updateTop = (state, timeline, top) => {
export default function timelines(state = initialState, action) {
switch(action.type) {
case TIMELINE_REFRESH_REQUEST:
case TIMELINE_EXPAND_REQUEST:
return state.update(action.timeline, initialTimeline, map => map.set('isLoading', true));
case TIMELINE_REFRESH_FAIL:
case TIMELINE_EXPAND_FAIL:
return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
case TIMELINE_REFRESH_SUCCESS:
return normalizeTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial);
case TIMELINE_EXPAND_SUCCESS:
return appendNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next);
return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial);
case TIMELINE_UPDATE:
return updateTimeline(state, action.timeline, fromJS(action.status));
case TIMELINE_DELETE:
@ -139,10 +127,15 @@ export default function timelines(state = initialState, action) {
return filterTimeline('home', state, action.relationship, action.statuses);
case TIMELINE_SCROLL_TOP:
return updateTop(state, action.timeline, action.top);
case TIMELINE_CONNECT:
return state.update(action.timeline, initialTimeline, map => map.set('online', true));
case TIMELINE_DISCONNECT:
return state.update(action.timeline, initialTimeline, map => map.set('online', false));
return state.update(
action.timeline,
initialTimeline,
map => map.update(
'items',
items => items.first() ? items : items.unshift(null)
)
);
default:
return state;
}