]>
cat aescling's git repositories - mastodon.git/blob - app/javascript/mastodon/reducers/timelines.js
2 TIMELINE_REFRESH_REQUEST
,
3 TIMELINE_REFRESH_SUCCESS
,
7 TIMELINE_EXPAND_SUCCESS
,
8 TIMELINE_EXPAND_REQUEST
,
13 } from '../actions/timelines';
15 ACCOUNT_BLOCK_SUCCESS
,
17 ACCOUNT_UNFOLLOW_SUCCESS
,
18 } from '../actions/accounts';
19 import { Map as ImmutableMap
, List as ImmutableList
, fromJS
} from 'immutable';
21 const initialState
= ImmutableMap();
23 const initialTimeline
= ImmutableMap({
30 items: ImmutableList(),
33 const normalizeTimeline
= (state
, timeline
, statuses
, next
) => {
34 const oldIds
= state
.getIn([timeline
, 'items'], ImmutableList());
35 const ids
= ImmutableList(statuses
.map(status
=> status
.get('id'))).filter(newId
=> !oldIds
.includes(newId
));
36 const wasLoaded
= state
.getIn([timeline
, 'loaded']);
37 const hadNext
= state
.getIn([timeline
, 'next']);
39 return state
.update(timeline
, initialTimeline
, map
=> map
.withMutations(mMap
=> {
40 mMap
.set('loaded', true);
41 mMap
.set('isLoading', false);
42 if (!hadNext
) mMap
.set('next', next
);
43 mMap
.set('items', wasLoaded
? ids
.concat(oldIds
) : ids
);
47 const appendNormalizedTimeline
= (state
, timeline
, statuses
, next
) => {
48 const oldIds
= state
.getIn([timeline
, 'items'], ImmutableList());
49 const ids
= ImmutableList(statuses
.map(status
=> status
.get('id'))).filter(newId
=> !oldIds
.includes(newId
));
51 return state
.update(timeline
, initialTimeline
, map
=> map
.withMutations(mMap
=> {
52 mMap
.set('isLoading', false);
53 mMap
.set('next', next
);
54 mMap
.set('items', oldIds
.concat(ids
));
58 const updateTimeline
= (state
, timeline
, status
) => {
59 const top
= state
.getIn([timeline
, 'top']);
60 const ids
= state
.getIn([timeline
, 'items'], ImmutableList());
61 const includesId
= ids
.includes(status
.get('id'));
62 const unread
= state
.getIn([timeline
, 'unread'], 0);
70 return state
.update(timeline
, initialTimeline
, map
=> map
.withMutations(mMap
=> {
71 if (!top
) mMap
.set('unread', unread
+ 1);
72 if (top
&& ids
.size
> 40) newIds
= newIds
.take(20);
73 mMap
.set('items', newIds
.unshift(status
.get('id')));
77 const deleteStatus
= (state
, id
, accountId
, references
) => {
78 state
.keySeq().forEach(timeline
=> {
79 state
= state
.updateIn([timeline
, 'items'], list
=> list
.filterNot(item
=> item
=== id
));
82 // Remove reblogs of deleted status
83 references
.forEach(ref
=> {
84 state
= deleteStatus(state
, ref
[0], ref
[1], []);
90 const filterTimelines
= (state
, relationship
, statuses
) => {
93 statuses
.forEach(status
=> {
94 if (status
.get('account') !== relationship
.id
) {
98 references
= statuses
.filter(item
=> item
.get('reblog') === status
.get('id')).map(item
=> [item
.get('id'), item
.get('account')]);
99 state
= deleteStatus(state
, status
.get('id'), status
.get('account'), references
);
105 const filterTimeline
= (timeline
, state
, relationship
, statuses
) =>
106 state
.updateIn([timeline
, 'items'], ImmutableList(), list
=>
107 list
.filterNot(statusId
=>
108 statuses
.getIn([statusId
, 'account']) === relationship
.id
111 const updateTop
= (state
, timeline
, top
) => {
112 return state
.update(timeline
, initialTimeline
, map
=> map
.withMutations(mMap
=> {
113 if (top
) mMap
.set('unread', 0);
114 mMap
.set('top', top
);
118 export default function timelines(state
= initialState
, action
) {
119 switch(action
.type
) {
120 case TIMELINE_REFRESH_REQUEST:
121 case TIMELINE_EXPAND_REQUEST:
122 return state
.update(action
.timeline
, initialTimeline
, map
=> map
.set('isLoading', true));
123 case TIMELINE_REFRESH_FAIL:
124 case TIMELINE_EXPAND_FAIL:
125 return state
.update(action
.timeline
, initialTimeline
, map
=> map
.set('isLoading', false));
126 case TIMELINE_REFRESH_SUCCESS:
127 return normalizeTimeline(state
, action
.timeline
, fromJS(action
.statuses
), action
.next
);
128 case TIMELINE_EXPAND_SUCCESS:
129 return appendNormalizedTimeline(state
, action
.timeline
, fromJS(action
.statuses
), action
.next
);
130 case TIMELINE_UPDATE:
131 return updateTimeline(state
, action
.timeline
, fromJS(action
.status
));
132 case TIMELINE_DELETE:
133 return deleteStatus(state
, action
.id
, action
.accountId
, action
.references
, action
.reblogOf
);
134 case ACCOUNT_BLOCK_SUCCESS:
135 case ACCOUNT_MUTE_SUCCESS:
136 return filterTimelines(state
, action
.relationship
, action
.statuses
);
137 case ACCOUNT_UNFOLLOW_SUCCESS:
138 return filterTimeline('home', state
, action
.relationship
, action
.statuses
);
139 case TIMELINE_SCROLL_TOP:
140 return updateTop(state
, action
.timeline
, action
.top
);
141 case TIMELINE_CONNECT:
142 return state
.update(action
.timeline
, initialTimeline
, map
=> map
.set('online', true));
143 case TIMELINE_DISCONNECT:
144 return state
.update(action
.timeline
, initialTimeline
, map
=> map
.set('online', false));
This page took 0.094424 seconds and 4 git commands to generate.