@ -8,6 +8,7 @@ import {
TIMELINE _SCROLL _TOP ,
TIMELINE _CONNECT ,
TIMELINE _DISCONNECT ,
TIMELINE _LOAD _PENDING ,
} from '../actions/timelines' ;
import {
ACCOUNT _BLOCK _SUCCESS ,
@ -25,10 +26,11 @@ const initialTimeline = ImmutableMap({
top : true ,
isLoading : false ,
hasMore : true ,
pendingItems : ImmutableList ( ) ,
items : ImmutableList ( ) ,
} ) ;
const expandNormalizedTimeline = ( state , timeline , statuses , next , isPartial , isLoadingRecent ) => {
const expandNormalizedTimeline = ( state , timeline , statuses , next , isPartial , isLoadingRecent , usePendingItems ) => {
return state . update ( timeline , initialTimeline , map => map . withMutations ( mMap => {
mMap . set ( 'isLoading' , false ) ;
mMap . set ( 'isPartial' , isPartial ) ;
@ -38,7 +40,7 @@ const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, is
if ( timeline . endsWith ( ':pinned' ) ) {
mMap . set ( 'items' , statuses . map ( status => status . get ( 'id' ) ) ) ;
} else if ( ! statuses . isEmpty ( ) ) {
mMap . update ( 'items' , ImmutableList ( ) , oldIds => {
mMap . update ( usePendingItems ? 'pendingItems' : 'items' , ImmutableList ( ) , oldIds => {
const newIds = statuses . map ( status => status . get ( 'id' ) ) ;
const lastIndex = oldIds . findLastIndex ( id => id !== null && compareId ( id , newIds . last ( ) ) >= 0 ) + 1 ;
@ -57,7 +59,15 @@ const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, is
} ) ) ;
} ;
const updateTimeline = ( state , timeline , status ) => {
const updateTimeline = ( state , timeline , status , usePendingItems ) => {
if ( usePendingItems ) {
if ( state . getIn ( [ timeline , 'pendingItems' ] , ImmutableList ( ) ) . includes ( status . get ( 'id' ) ) || state . getIn ( [ timeline , 'items' ] , ImmutableList ( ) ) . includes ( status . get ( 'id' ) ) ) {
return state ;
}
return state . update ( timeline , initialTimeline , map => map . update ( 'pendingItems' , list => list . unshift ( status . get ( 'id' ) ) ) ) ;
}
const top = state . getIn ( [ timeline , 'top' ] ) ;
const ids = state . getIn ( [ timeline , 'items' ] , ImmutableList ( ) ) ;
const includesId = ids . includes ( status . get ( 'id' ) ) ;
@ -78,8 +88,10 @@ const updateTimeline = (state, timeline, status) => {
const deleteStatus = ( state , id , accountId , references , exclude _account = null ) => {
state . keySeq ( ) . forEach ( timeline => {
if ( exclude _account === null || ( timeline !== ` account: ${ exclude _account } ` && ! timeline . startsWith ( ` account: ${ exclude _account } : ` ) ) )
state = state . updateIn ( [ timeline , 'items' ] , list => list . filterNot ( item => item === id ) ) ;
if ( exclude _account === null || ( timeline !== ` account: ${ exclude _account } ` && ! timeline . startsWith ( ` account: ${ exclude _account } : ` ) ) ) {
const helper = list => list . filterNot ( item => item === id ) ;
state = state . updateIn ( [ timeline , 'items' ] , helper ) . updateIn ( [ timeline , 'pendingItems' ] , helper ) ;
}
} ) ;
// Remove reblogs of deleted status
@ -109,11 +121,10 @@ const filterTimelines = (state, relationship, statuses) => {
return state ;
} ;
const filterTimeline = ( timeline , state , relationship , statuses ) =>
state . updateIn ( [ timeline , 'items' ] , ImmutableList ( ) , list =>
list . filterNot ( statusId =>
statuses . getIn ( [ statusId , 'account' ] ) === relationship . id
) ) ;
const filterTimeline = ( timeline , state , relationship , statuses ) => {
const helper = list => list . filterNot ( statusId => statuses . getIn ( [ statusId , 'account' ] ) === relationship . id ) ;
return state . updateIn ( [ timeline , 'items' ] , ImmutableList ( ) , helper ) . updateIn ( [ timeline , 'pendingItems' ] , ImmutableList ( ) , helper ) ;
} ;
const updateTop = ( state , timeline , top ) => {
return state . update ( timeline , initialTimeline , map => map . withMutations ( mMap => {
@ -124,14 +135,17 @@ const updateTop = (state, timeline, top) => {
export default function timelines ( state = initialState , action ) {
switch ( action . type ) {
case TIMELINE _LOAD _PENDING :
return state . update ( action . timeline , initialTimeline , map =>
map . update ( 'items' , list => map . get ( 'pendingItems' ) . concat ( list . take ( 40 ) ) ) . set ( 'pendingItems' , ImmutableList ( ) ) . set ( 'unread' , 0 ) ) ;
case TIMELINE _EXPAND _REQUEST :
return state . update ( action . timeline , initialTimeline , map => map . set ( 'isLoading' , true ) ) ;
case TIMELINE _EXPAND _FAIL :
return state . update ( action . timeline , initialTimeline , map => map . set ( 'isLoading' , false ) ) ;
case TIMELINE _EXPAND _SUCCESS :
return expandNormalizedTimeline ( state , action . timeline , fromJS ( action . statuses ) , action . next , action . partial , action . isLoadingRecent );
return expandNormalizedTimeline ( state , action . timeline , fromJS ( action . statuses ) , action . next , action . partial , action . isLoadingRecent , action . usePendingItems );
case TIMELINE _UPDATE :
return updateTimeline ( state , action . timeline , fromJS ( action . status ) );
return updateTimeline ( state , action . timeline , fromJS ( action . status ) , action . usePendingItems );
case TIMELINE _DELETE :
return deleteStatus ( state , action . id , action . accountId , action . references , action . reblogOf ) ;
case TIMELINE _CLEAR :
@ -149,7 +163,7 @@ export default function timelines(state = initialState, action) {
return state . update (
action . timeline ,
initialTimeline ,
map => map . set ( 'online' , false ) . update ( 'items' , items => items . first ( ) ? items . unshift ( null ) : items )
map => map . set ( 'online' , false ) . update ( action . usePendingItems ? 'pendingItems' : 'items' , items => items . first ( ) ? items . unshift ( null ) : items )
) ;
default :
return state ;