Fix #238 - Add "favourites" column
This commit is contained in:
		
					parent
					
						
							
								da5d366230
							
						
					
				
			
			
				commit
				
					
						7d53ee73f3
					
				
			
		
					 15 changed files with 297 additions and 63 deletions
				
			
		
							
								
								
									
										83
									
								
								app/assets/javascripts/components/actions/favourites.jsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								app/assets/javascripts/components/actions/favourites.jsx
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,83 @@ | |||
| import api, { getLinks } from '../api' | ||||
| 
 | ||||
| export const FAVOURITED_STATUSES_FETCH_REQUEST = 'FAVOURITED_STATUSES_FETCH_REQUEST'; | ||||
| export const FAVOURITED_STATUSES_FETCH_SUCCESS = 'FAVOURITED_STATUSES_FETCH_SUCCESS'; | ||||
| export const FAVOURITED_STATUSES_FETCH_FAIL    = 'FAVOURITED_STATUSES_FETCH_FAIL'; | ||||
| 
 | ||||
| export const FAVOURITED_STATUSES_EXPAND_REQUEST = 'FAVOURITED_STATUSES_EXPAND_REQUEST'; | ||||
| export const FAVOURITED_STATUSES_EXPAND_SUCCESS = 'FAVOURITED_STATUSES_EXPAND_SUCCESS'; | ||||
| export const FAVOURITED_STATUSES_EXPAND_FAIL    = 'FAVOURITED_STATUSES_EXPAND_FAIL'; | ||||
| 
 | ||||
| export function fetchFavouritedStatuses() { | ||||
|   return (dispatch, getState) => { | ||||
|     dispatch(fetchFavouritedStatusesRequest()); | ||||
| 
 | ||||
|     api(getState).get('/api/v1/favourites').then(response => { | ||||
|       const next = getLinks(response).refs.find(link => link.rel === 'next'); | ||||
|       dispatch(fetchFavouritedStatusesSuccess(response.data, next ? next.uri : null)); | ||||
|     }).catch(error => { | ||||
|       dispatch(fetchFavouritedStatusesFail(error)); | ||||
|     }); | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function fetchFavouritedStatusesRequest() { | ||||
|   return { | ||||
|     type: FAVOURITED_STATUSES_FETCH_REQUEST | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function fetchFavouritedStatusesSuccess(statuses, next) { | ||||
|   return { | ||||
|     type: FAVOURITED_STATUSES_FETCH_SUCCESS, | ||||
|     statuses, | ||||
|     next | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function fetchFavouritedStatusesFail(error) { | ||||
|   return { | ||||
|     type: FAVOURITED_STATUSES_FETCH_FAIL, | ||||
|     error | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function expandFavouritedStatuses() { | ||||
|   return (dispatch, getState) => { | ||||
|     const url = getState().getIn(['status_lists', 'favourites', 'next'], null); | ||||
| 
 | ||||
|     if (url === null) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     dispatch(expandFavouritedStatusesRequest()); | ||||
| 
 | ||||
|     api(getState).get(url).then(response => { | ||||
|       const next = getLinks(response).refs.find(link => link.rel === 'next'); | ||||
|       dispatch(expandFavouritedStatusesSuccess(response.data, next ? next.uri : null)); | ||||
|     }).catch(error => { | ||||
|       dispatch(expandFavouritedStatusesFail(error)); | ||||
|     }); | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function expandFavouritedStatusesRequest() { | ||||
|   return { | ||||
|     type: FAVOURITED_STATUSES_EXPAND_REQUEST | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function expandFavouritedStatusesSuccess(statuses, next) { | ||||
|   return { | ||||
|     type: FAVOURITED_STATUSES_EXPAND_SUCCESS, | ||||
|     statuses, | ||||
|     next | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function expandFavouritedStatusesFail(error) { | ||||
|   return { | ||||
|     type: FAVOURITED_STATUSES_EXPAND_FAIL, | ||||
|     error | ||||
|   }; | ||||
| }; | ||||
|  | @ -97,6 +97,11 @@ export function expandTimeline(timeline, id = null) { | |||
|   return (dispatch, getState) => { | ||||
|     const lastId = getState().getIn(['timelines', timeline, 'items'], Immutable.List()).last(); | ||||
| 
 | ||||
|     if (!lastId) { | ||||
|       // If timeline is empty, don't try to load older posts since there are none | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     dispatch(expandTimelineRequest(timeline)); | ||||
| 
 | ||||
|     let path = timeline; | ||||
|  |  | |||
|  | @ -34,6 +34,7 @@ import HashtagTimeline from '../features/hashtag_timeline'; | |||
| import Notifications from '../features/notifications'; | ||||
| import FollowRequests from '../features/follow_requests'; | ||||
| import GenericNotFound from '../features/generic_not_found'; | ||||
| import FavouritedStatuses from '../features/favourited_statuses'; | ||||
| import { IntlProvider, addLocaleData } from 'react-intl'; | ||||
| import en from 'react-intl/locale-data/en'; | ||||
| import de from 'react-intl/locale-data/de'; | ||||
|  | @ -113,6 +114,7 @@ const Mastodon = React.createClass({ | |||
|               <Route path='timelines/tag/:id' component={HashtagTimeline} /> | ||||
| 
 | ||||
|               <Route path='notifications' component={Notifications} /> | ||||
|               <Route path='favourites' component={FavouritedStatuses} /> | ||||
| 
 | ||||
|               <Route path='statuses/new' component={Compose} /> | ||||
|               <Route path='statuses/:statusId' component={Status} /> | ||||
|  |  | |||
|  | @ -18,7 +18,8 @@ const AccountTimeline = React.createClass({ | |||
|   propTypes: { | ||||
|     params: React.PropTypes.object.isRequired, | ||||
|     dispatch: React.PropTypes.func.isRequired, | ||||
|     statusIds: ImmutablePropTypes.list | ||||
|     statusIds: ImmutablePropTypes.list, | ||||
|     me: React.PropTypes.number.isRequired | ||||
|   }, | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
|  |  | |||
|  | @ -0,0 +1,63 @@ | |||
| import { connect } from 'react-redux'; | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import LoadingIndicator from '../../components/loading_indicator'; | ||||
| import { fetchFavouritedStatuses, expandFavouritedStatuses } from '../../actions/favourites'; | ||||
| import Column from '../ui/components/column'; | ||||
| import StatusList from '../../components/status_list'; | ||||
| import ColumnBackButton from '../public_timeline/components/column_back_button'; | ||||
| import { defineMessages, injectIntl } from 'react-intl'; | ||||
| 
 | ||||
| const messages = defineMessages({ | ||||
|   heading: { id: 'column.favourites', defaultMessage: 'Favourites' } | ||||
| }); | ||||
| 
 | ||||
| const mapStateToProps = state => ({ | ||||
|   statusIds: state.getIn(['status_lists', 'favourites', 'items']), | ||||
|   loaded: state.getIn(['status_lists', 'favourites', 'loaded']), | ||||
|   me: state.getIn(['meta', 'me']) | ||||
| }); | ||||
| 
 | ||||
| const Favourites = React.createClass({ | ||||
| 
 | ||||
|   propTypes: { | ||||
|     params: React.PropTypes.object.isRequired, | ||||
|     dispatch: React.PropTypes.func.isRequired, | ||||
|     statusIds: ImmutablePropTypes.list.isRequired, | ||||
|     loaded: React.PropTypes.bool, | ||||
|     intl: React.PropTypes.object.isRequired, | ||||
|     me: React.PropTypes.number.isRequired | ||||
|   }, | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
| 
 | ||||
|   componentWillMount () { | ||||
|     this.props.dispatch(fetchFavouritedStatuses()); | ||||
|   }, | ||||
| 
 | ||||
|   handleScrollToBottom () { | ||||
|     this.props.dispatch(expandFavouritedStatuses()); | ||||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|     const { statusIds, loaded, intl, me } = this.props; | ||||
| 
 | ||||
|     if (!loaded) { | ||||
|       return ( | ||||
|         <Column> | ||||
|           <LoadingIndicator /> | ||||
|         </Column> | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|       <Column icon='star' heading={intl.formatMessage(messages.heading)}> | ||||
|         <ColumnBackButton /> | ||||
|         <StatusList statusIds={statusIds} me={me} onScrollToBottom={this.handleScrollToBottom} /> | ||||
|       </Column> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| }); | ||||
| 
 | ||||
| export default connect(mapStateToProps)(injectIntl(Favourites)); | ||||
|  | @ -10,7 +10,8 @@ const messages = defineMessages({ | |||
|   public_timeline: { id: 'navigation_bar.public_timeline', defaultMessage: 'Public timeline' }, | ||||
|   preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, | ||||
|   follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, | ||||
|   sign_out: { id: 'navigation_bar.logout', defaultMessage: 'Sign out' } | ||||
|   sign_out: { id: 'navigation_bar.logout', defaultMessage: 'Sign out' }, | ||||
|   favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' } | ||||
| }); | ||||
| 
 | ||||
| const mapStateToProps = state => ({ | ||||
|  | @ -29,6 +30,7 @@ const GettingStarted = ({ intl, me }) => { | |||
|       <div style={{ position: 'relative' }}> | ||||
|         <ColumnLink icon='globe' text={intl.formatMessage(messages.public_timeline)} to='/timelines/public' /> | ||||
|         <ColumnLink icon='cog' text={intl.formatMessage(messages.preferences)} href='/settings/preferences' /> | ||||
|         <ColumnLink icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' /> | ||||
|         {followRequests} | ||||
|         <ColumnLink icon='sign-out' text={intl.formatMessage(messages.sign_out)} href='/auth/sign_out' method='delete' /> | ||||
|       </div> | ||||
|  |  | |||
							
								
								
									
										25
									
								
								app/assets/javascripts/components/middleware/loading_bar.jsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/assets/javascripts/components/middleware/loading_bar.jsx
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| import { showLoading, hideLoading } from 'react-redux-loading-bar'; | ||||
| 
 | ||||
| const defaultTypeSuffixes = ['PENDING', 'FULFILLED', 'REJECTED']; | ||||
| 
 | ||||
| export default function loadingBarMiddleware(config = {}) { | ||||
|   const promiseTypeSuffixes = config.promiseTypeSuffixes || defaultTypeSuffixes; | ||||
| 
 | ||||
|   return ({ dispatch }) => next => (action) => { | ||||
|     if (action.type && !action.skipLoading) { | ||||
|       const [PENDING, FULFILLED, REJECTED] = promiseTypeSuffixes; | ||||
| 
 | ||||
|       const isPending = new RegExp(`${PENDING}$`, 'g'); | ||||
|       const isFulfilled = new RegExp(`${FULFILLED}$`, 'g'); | ||||
|       const isRejected = new RegExp(`${REJECTED}$`, 'g'); | ||||
| 
 | ||||
|       if (action.type.match(isPending)) { | ||||
|         dispatch(showLoading()); | ||||
|       } else if (action.type.match(isFulfilled) || action.type.match(isRejected)) { | ||||
|         dispatch(hideLoading()); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return next(action); | ||||
|   }; | ||||
| }; | ||||
|  | @ -32,6 +32,10 @@ import { | |||
|   NOTIFICATIONS_REFRESH_SUCCESS, | ||||
|   NOTIFICATIONS_EXPAND_SUCCESS | ||||
| } from '../actions/notifications'; | ||||
| import { | ||||
|   FAVOURITED_STATUSES_FETCH_SUCCESS, | ||||
|   FAVOURITED_STATUSES_EXPAND_SUCCESS | ||||
| } from '../actions/favourites'; | ||||
| import { STORE_HYDRATE } from '../actions/store'; | ||||
| import Immutable from 'immutable'; | ||||
| 
 | ||||
|  | @ -90,6 +94,8 @@ export default function accounts(state = initialState, action) { | |||
|   case ACCOUNT_TIMELINE_FETCH_SUCCESS: | ||||
|   case ACCOUNT_TIMELINE_EXPAND_SUCCESS: | ||||
|   case CONTEXT_FETCH_SUCCESS: | ||||
|   case FAVOURITED_STATUSES_FETCH_SUCCESS: | ||||
|   case FAVOURITED_STATUSES_EXPAND_SUCCESS: | ||||
|     return normalizeAccountsFromStatuses(state, action.statuses); | ||||
|   case REBLOG_SUCCESS: | ||||
|   case FAVOURITE_SUCCESS: | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ import relationships from './relationships'; | |||
| import search from './search'; | ||||
| import notifications from './notifications'; | ||||
| import settings from './settings'; | ||||
| import status_lists from './status_lists'; | ||||
| 
 | ||||
| export default combineReducers({ | ||||
|   timelines, | ||||
|  | @ -21,6 +22,7 @@ export default combineReducers({ | |||
|   loadingBar: loadingBarReducer, | ||||
|   modal, | ||||
|   user_lists, | ||||
|   status_lists, | ||||
|   accounts, | ||||
|   statuses, | ||||
|   relationships, | ||||
|  |  | |||
|  | @ -8,14 +8,14 @@ const initialState = Immutable.Map({ | |||
| 
 | ||||
| export default function modal(state = initialState, action) { | ||||
|   switch(action.type) { | ||||
|     case MEDIA_OPEN: | ||||
|       return state.withMutations(map => { | ||||
|         map.set('url', action.url); | ||||
|         map.set('open', true); | ||||
|       }); | ||||
|     case MODAL_CLOSE: | ||||
|       return state.set('open', false); | ||||
|     default: | ||||
|       return state; | ||||
|   case MEDIA_OPEN: | ||||
|     return state.withMutations(map => { | ||||
|       map.set('url', action.url); | ||||
|       map.set('open', true); | ||||
|     }); | ||||
|   case MODAL_CLOSE: | ||||
|     return state.set('open', false); | ||||
|   default: | ||||
|     return state; | ||||
|   } | ||||
| }; | ||||
|  |  | |||
							
								
								
									
										39
									
								
								app/assets/javascripts/components/reducers/status_lists.jsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/assets/javascripts/components/reducers/status_lists.jsx
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| import { | ||||
|   FAVOURITED_STATUSES_FETCH_SUCCESS, | ||||
|   FAVOURITED_STATUSES_EXPAND_SUCCESS | ||||
| } from '../actions/favourites'; | ||||
| import Immutable from 'immutable'; | ||||
| 
 | ||||
| const initialState = Immutable.Map({ | ||||
|   favourites: Immutable.Map({ | ||||
|     next: null, | ||||
|     loaded: false, | ||||
|     items: Immutable.List() | ||||
|   }) | ||||
| }); | ||||
| 
 | ||||
| const normalizeList = (state, listType, statuses, next) => { | ||||
|   return state.update(listType, listMap => listMap.withMutations(map => { | ||||
|     map.set('next', next); | ||||
|     map.set('loaded', true); | ||||
|     map.set('items', Immutable.List(statuses.map(item => item.id))); | ||||
|   })); | ||||
| }; | ||||
| 
 | ||||
| const appendToList = (state, listType, statuses, next) => { | ||||
|   return state.update(listType, listMap => listMap.withMutations(map => { | ||||
|     map.set('next', next); | ||||
|     map.set('items', map.get('items').push(...statuses.map(item => item.id))); | ||||
|   })); | ||||
| }; | ||||
| 
 | ||||
| export default function statusLists(state = initialState, action) { | ||||
|   switch(action.type) { | ||||
|   case FAVOURITED_STATUSES_FETCH_SUCCESS: | ||||
|     return normalizeList(state, 'favourites', action.statuses, action.next); | ||||
|   case FAVOURITED_STATUSES_EXPAND_SUCCESS: | ||||
|     return appendToList(state, 'favourites', action.statuses, action.next); | ||||
|   default: | ||||
|     return state; | ||||
|   } | ||||
| }; | ||||
|  | @ -28,6 +28,10 @@ import { | |||
|   NOTIFICATIONS_REFRESH_SUCCESS, | ||||
|   NOTIFICATIONS_EXPAND_SUCCESS | ||||
| } from '../actions/notifications'; | ||||
| import { | ||||
|   FAVOURITED_STATUSES_FETCH_SUCCESS, | ||||
|   FAVOURITED_STATUSES_EXPAND_SUCCESS | ||||
| } from '../actions/favourites'; | ||||
| import Immutable from 'immutable'; | ||||
| 
 | ||||
| const normalizeStatus = (state, status) => { | ||||
|  | @ -77,36 +81,38 @@ const initialState = Immutable.Map(); | |||
| 
 | ||||
| export default function statuses(state = initialState, action) { | ||||
|   switch(action.type) { | ||||
|     case TIMELINE_UPDATE: | ||||
|     case STATUS_FETCH_SUCCESS: | ||||
|     case NOTIFICATIONS_UPDATE: | ||||
|       return normalizeStatus(state, action.status); | ||||
|     case REBLOG_SUCCESS: | ||||
|     case UNREBLOG_SUCCESS: | ||||
|     case FAVOURITE_SUCCESS: | ||||
|     case UNFAVOURITE_SUCCESS: | ||||
|       return normalizeStatus(state, action.response); | ||||
|     case FAVOURITE_REQUEST: | ||||
|       return state.setIn([action.status.get('id'), 'favourited'], true); | ||||
|     case FAVOURITE_FAIL: | ||||
|       return state.setIn([action.status.get('id'), 'favourited'], false); | ||||
|     case REBLOG_REQUEST: | ||||
|       return state.setIn([action.status.get('id'), 'reblogged'], true); | ||||
|     case REBLOG_FAIL: | ||||
|       return state.setIn([action.status.get('id'), 'reblogged'], false); | ||||
|     case TIMELINE_REFRESH_SUCCESS: | ||||
|     case TIMELINE_EXPAND_SUCCESS: | ||||
|     case ACCOUNT_TIMELINE_FETCH_SUCCESS: | ||||
|     case ACCOUNT_TIMELINE_EXPAND_SUCCESS: | ||||
|     case CONTEXT_FETCH_SUCCESS: | ||||
|     case NOTIFICATIONS_REFRESH_SUCCESS: | ||||
|     case NOTIFICATIONS_EXPAND_SUCCESS: | ||||
|       return normalizeStatuses(state, action.statuses); | ||||
|     case TIMELINE_DELETE: | ||||
|       return deleteStatus(state, action.id, action.references); | ||||
|     case ACCOUNT_BLOCK_SUCCESS: | ||||
|       return filterStatuses(state, action.relationship); | ||||
|     default: | ||||
|       return state; | ||||
|   case TIMELINE_UPDATE: | ||||
|   case STATUS_FETCH_SUCCESS: | ||||
|   case NOTIFICATIONS_UPDATE: | ||||
|     return normalizeStatus(state, action.status); | ||||
|   case REBLOG_SUCCESS: | ||||
|   case UNREBLOG_SUCCESS: | ||||
|   case FAVOURITE_SUCCESS: | ||||
|   case UNFAVOURITE_SUCCESS: | ||||
|     return normalizeStatus(state, action.response); | ||||
|   case FAVOURITE_REQUEST: | ||||
|     return state.setIn([action.status.get('id'), 'favourited'], true); | ||||
|   case FAVOURITE_FAIL: | ||||
|     return state.setIn([action.status.get('id'), 'favourited'], false); | ||||
|   case REBLOG_REQUEST: | ||||
|     return state.setIn([action.status.get('id'), 'reblogged'], true); | ||||
|   case REBLOG_FAIL: | ||||
|     return state.setIn([action.status.get('id'), 'reblogged'], false); | ||||
|   case TIMELINE_REFRESH_SUCCESS: | ||||
|   case TIMELINE_EXPAND_SUCCESS: | ||||
|   case ACCOUNT_TIMELINE_FETCH_SUCCESS: | ||||
|   case ACCOUNT_TIMELINE_EXPAND_SUCCESS: | ||||
|   case CONTEXT_FETCH_SUCCESS: | ||||
|   case NOTIFICATIONS_REFRESH_SUCCESS: | ||||
|   case NOTIFICATIONS_EXPAND_SUCCESS: | ||||
|   case FAVOURITED_STATUSES_FETCH_SUCCESS: | ||||
|   case FAVOURITED_STATUSES_EXPAND_SUCCESS: | ||||
|     return normalizeStatuses(state, action.statuses); | ||||
|   case TIMELINE_DELETE: | ||||
|     return deleteStatus(state, action.id, action.references); | ||||
|   case ACCOUNT_BLOCK_SUCCESS: | ||||
|     return filterStatuses(state, action.relationship); | ||||
|   default: | ||||
|     return state; | ||||
|   } | ||||
| }; | ||||
|  |  | |||
|  | @ -36,24 +36,24 @@ const appendToList = (state, type, id, accounts, next) => { | |||
| 
 | ||||
| export default function userLists(state = initialState, action) { | ||||
|   switch(action.type) { | ||||
|     case FOLLOWERS_FETCH_SUCCESS: | ||||
|       return normalizeList(state, 'followers', action.id, action.accounts, action.next); | ||||
|     case FOLLOWERS_EXPAND_SUCCESS: | ||||
|       return appendToList(state, 'followers', action.id, action.accounts, action.next); | ||||
|     case FOLLOWING_FETCH_SUCCESS: | ||||
|       return normalizeList(state, 'following', action.id, action.accounts, action.next); | ||||
|     case FOLLOWING_EXPAND_SUCCESS: | ||||
|       return appendToList(state, 'following', action.id, action.accounts, action.next); | ||||
|     case REBLOGS_FETCH_SUCCESS: | ||||
|       return state.setIn(['reblogged_by', action.id], Immutable.List(action.accounts.map(item => item.id))); | ||||
|     case FAVOURITES_FETCH_SUCCESS: | ||||
|       return state.setIn(['favourited_by', action.id], Immutable.List(action.accounts.map(item => item.id))); | ||||
|     case FOLLOW_REQUESTS_FETCH_SUCCESS: | ||||
|       return state.setIn(['follow_requests', 'items'], Immutable.List(action.accounts.map(item => item.id))).setIn(['follow_requests', 'next'], action.next); | ||||
|     case FOLLOW_REQUEST_AUTHORIZE_SUCCESS: | ||||
|     case FOLLOW_REQUEST_REJECT_SUCCESS: | ||||
|       return state.updateIn(['follow_requests', 'items'], list => list.filterNot(item => item === action.id)); | ||||
|     default: | ||||
|       return state; | ||||
|   case FOLLOWERS_FETCH_SUCCESS: | ||||
|     return normalizeList(state, 'followers', action.id, action.accounts, action.next); | ||||
|   case FOLLOWERS_EXPAND_SUCCESS: | ||||
|     return appendToList(state, 'followers', action.id, action.accounts, action.next); | ||||
|   case FOLLOWING_FETCH_SUCCESS: | ||||
|     return normalizeList(state, 'following', action.id, action.accounts, action.next); | ||||
|   case FOLLOWING_EXPAND_SUCCESS: | ||||
|     return appendToList(state, 'following', action.id, action.accounts, action.next); | ||||
|   case REBLOGS_FETCH_SUCCESS: | ||||
|     return state.setIn(['reblogged_by', action.id], Immutable.List(action.accounts.map(item => item.id))); | ||||
|   case FAVOURITES_FETCH_SUCCESS: | ||||
|     return state.setIn(['favourited_by', action.id], Immutable.List(action.accounts.map(item => item.id))); | ||||
|   case FOLLOW_REQUESTS_FETCH_SUCCESS: | ||||
|     return state.setIn(['follow_requests', 'items'], Immutable.List(action.accounts.map(item => item.id))).setIn(['follow_requests', 'next'], action.next); | ||||
|   case FOLLOW_REQUEST_AUTHORIZE_SUCCESS: | ||||
|   case FOLLOW_REQUEST_REJECT_SUCCESS: | ||||
|     return state.updateIn(['follow_requests', 'items'], list => list.filterNot(item => item === action.id)); | ||||
|   default: | ||||
|     return state; | ||||
|   } | ||||
| }; | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { createStore, applyMiddleware, compose } from 'redux'; | ||||
| import thunk from 'redux-thunk'; | ||||
| import appReducer from '../reducers'; | ||||
| import { loadingBarMiddleware } from 'react-redux-loading-bar'; | ||||
| import loadingBarMiddleware from '../middleware/loading_bar'; | ||||
| import errorsMiddleware from '../middleware/errors'; | ||||
| import Immutable from 'immutable'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ class Api::V1::FavouritesController < ApiController | |||
|     set_maps(@statuses) | ||||
|     set_counters_maps(@statuses) | ||||
| 
 | ||||
|     next_path = api_v1_favourites_url(max_id: results.last.id)    if results.size == DEFAULT_ACCOUNTS_LIMIT | ||||
|     next_path = api_v1_favourites_url(max_id: results.last.id)    if results.size == DEFAULT_STATUSES_LIMIT | ||||
|     prev_path = api_v1_favourites_url(since_id: results.first.id) unless results.empty? | ||||
| 
 | ||||
|     set_pagination_headers(next_path, prev_path) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue