forked from treehouse/mastodon
Refactoring redux state into different reducers
parent
7060bdf04b
commit
e8ff4c8e56
|
@ -1,5 +1,4 @@
|
||||||
import api from '../api'
|
import api from '../api'
|
||||||
import axios from 'axios';
|
|
||||||
import Immutable from 'immutable';
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
export const ACCOUNT_SET_SELF = 'ACCOUNT_SET_SELF';
|
export const ACCOUNT_SET_SELF = 'ACCOUNT_SET_SELF';
|
||||||
|
@ -53,12 +52,11 @@ export function setAccountSelf(account) {
|
||||||
|
|
||||||
export function fetchAccount(id) {
|
export function fetchAccount(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const boundApi = api(getState);
|
|
||||||
|
|
||||||
dispatch(fetchAccountRequest(id));
|
dispatch(fetchAccountRequest(id));
|
||||||
|
|
||||||
axios.all([boundApi.get(`/api/v1/accounts/${id}`), boundApi.get(`/api/v1/accounts/relationships?id=${id}`)]).then(values => {
|
api(getState).get(`/api/v1/accounts/${id}`).then(response => {
|
||||||
dispatch(fetchAccountSuccess(values[0].data, values[1].data[0]));
|
dispatch(fetchAccountSuccess(response.data));
|
||||||
|
dispatch(fetchRelationships([id]));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(fetchAccountFail(id, error));
|
dispatch(fetchAccountFail(id, error));
|
||||||
});
|
});
|
||||||
|
@ -107,11 +105,10 @@ export function fetchAccountRequest(id) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fetchAccountSuccess(account, relationship) {
|
export function fetchAccountSuccess(account) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_FETCH_SUCCESS,
|
type: ACCOUNT_FETCH_SUCCESS,
|
||||||
account: account,
|
account: account
|
||||||
relationship: relationship
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import api from '../api';
|
import api from '../api';
|
||||||
import axios from 'axios';
|
|
||||||
|
import { deleteFromTimelines } from './timelines';
|
||||||
|
|
||||||
export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
|
export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
|
||||||
export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS';
|
export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS';
|
||||||
|
@ -9,6 +10,10 @@ export const STATUS_DELETE_REQUEST = 'STATUS_DELETE_REQUEST';
|
||||||
export const STATUS_DELETE_SUCCESS = 'STATUS_DELETE_SUCCESS';
|
export const STATUS_DELETE_SUCCESS = 'STATUS_DELETE_SUCCESS';
|
||||||
export const STATUS_DELETE_FAIL = 'STATUS_DELETE_FAIL';
|
export const STATUS_DELETE_FAIL = 'STATUS_DELETE_FAIL';
|
||||||
|
|
||||||
|
export const CONTEXT_FETCH_REQUEST = 'CONTEXT_FETCH_REQUEST';
|
||||||
|
export const CONTEXT_FETCH_SUCCESS = 'CONTEXT_FETCH_SUCCESS';
|
||||||
|
export const CONTEXT_FETCH_FAIL = 'CONTEXT_FETCH_FAIL';
|
||||||
|
|
||||||
export function fetchStatusRequest(id) {
|
export function fetchStatusRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_FETCH_REQUEST,
|
type: STATUS_FETCH_REQUEST,
|
||||||
|
@ -18,12 +23,11 @@ export function fetchStatusRequest(id) {
|
||||||
|
|
||||||
export function fetchStatus(id) {
|
export function fetchStatus(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const boundApi = api(getState);
|
|
||||||
|
|
||||||
dispatch(fetchStatusRequest(id));
|
dispatch(fetchStatusRequest(id));
|
||||||
|
|
||||||
axios.all([boundApi.get(`/api/v1/statuses/${id}`), boundApi.get(`/api/v1/statuses/${id}/context`)]).then(values => {
|
api(getState).get(`/api/v1/statuses/${id}`).then(response => {
|
||||||
dispatch(fetchStatusSuccess(values[0].data, values[1].data));
|
dispatch(fetchStatusSuccess(response.data));
|
||||||
|
dispatch(fetchContext(id));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(fetchStatusFail(id, error));
|
dispatch(fetchStatusFail(id, error));
|
||||||
});
|
});
|
||||||
|
@ -52,6 +56,7 @@ export function deleteStatus(id) {
|
||||||
|
|
||||||
api(getState).delete(`/api/v1/statuses/${id}`).then(response => {
|
api(getState).delete(`/api/v1/statuses/${id}`).then(response => {
|
||||||
dispatch(deleteStatusSuccess(id));
|
dispatch(deleteStatusSuccess(id));
|
||||||
|
dispatch(deleteFromTimelines(id));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(deleteStatusFail(id, error));
|
dispatch(deleteStatusFail(id, error));
|
||||||
});
|
});
|
||||||
|
@ -79,3 +84,40 @@ export function deleteStatusFail(id, error) {
|
||||||
error: error
|
error: error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function fetchContext(id) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
dispatch(fetchContextRequest(id));
|
||||||
|
|
||||||
|
api(getState).get(`/api/v1/statuses/${id}/context`).then(response => {
|
||||||
|
dispatch(fetchContextSuccess(id, response.data.ancestors, response.data.descendants));
|
||||||
|
}).catch(error => {
|
||||||
|
dispatch(fetchContextFail(id, error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function fetchContextRequest(id) {
|
||||||
|
return {
|
||||||
|
type: CONTEXT_FETCH_REQUEST,
|
||||||
|
id
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function fetchContextSuccess(id, ancestors, descendants) {
|
||||||
|
return {
|
||||||
|
type: CONTEXT_FETCH_SUCCESS,
|
||||||
|
id,
|
||||||
|
ancestors,
|
||||||
|
descendants,
|
||||||
|
statuses: ancestors.concat(descendants)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function fetchContextFail(id, error) {
|
||||||
|
return {
|
||||||
|
type: CONTEXT_FETCH_FAIL,
|
||||||
|
id,
|
||||||
|
error
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -21,17 +21,29 @@ export function refreshTimelineSuccess(timeline, statuses, replace) {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function updateTimeline(timeline, status) {
|
export function updateTimeline(timeline, status) {
|
||||||
return {
|
return (dispatch, getState) => {
|
||||||
type: TIMELINE_UPDATE,
|
const references = status.reblog ? getState().get('statuses').filter((item, itemId) => (itemId === status.reblog.id || item.get('reblog') === status.reblog.id)).map((_, itemId) => itemId) : [];
|
||||||
timeline: timeline,
|
|
||||||
status: status
|
dispatch({
|
||||||
|
type: TIMELINE_UPDATE,
|
||||||
|
timeline,
|
||||||
|
status,
|
||||||
|
references
|
||||||
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function deleteFromTimelines(id) {
|
export function deleteFromTimelines(id) {
|
||||||
return {
|
return (dispatch, getState) => {
|
||||||
type: TIMELINE_DELETE,
|
const accountId = getState().getIn(['statuses', id, 'account']);
|
||||||
id: id
|
const references = getState().get('statuses').filter(status => status.get('reblog') === id).map(status => [status.get('id'), status.get('account')]);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: TIMELINE_DELETE,
|
||||||
|
id,
|
||||||
|
accountId,
|
||||||
|
references
|
||||||
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ const Status = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map,
|
||||||
wrapped: React.PropTypes.bool,
|
wrapped: React.PropTypes.bool,
|
||||||
onReply: React.PropTypes.func,
|
onReply: React.PropTypes.func,
|
||||||
onFavourite: React.PropTypes.func,
|
onFavourite: React.PropTypes.func,
|
||||||
|
|
|
@ -19,7 +19,7 @@ const makeMapStateToProps = () => {
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
status: getStatus(state, props.id),
|
status: getStatus(state, props.id),
|
||||||
me: state.getIn(['timelines', 'me'])
|
me: state.getIn(['meta', 'me'])
|
||||||
});
|
});
|
||||||
|
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
|
|
|
@ -26,7 +26,7 @@ const makeMapStateToProps = () => {
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
account: getAccount(state, Number(props.params.accountId)),
|
account: getAccount(state, Number(props.params.accountId)),
|
||||||
me: state.getIn(['timelines', 'me'])
|
me: state.getIn(['meta', 'me'])
|
||||||
});
|
});
|
||||||
|
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
|
|
|
@ -10,7 +10,7 @@ import LoadingIndicator from '../../components/loading_indicator';
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
statusIds: state.getIn(['timelines', 'accounts_timelines', Number(props.params.accountId)]),
|
statusIds: state.getIn(['timelines', 'accounts_timelines', Number(props.params.accountId)]),
|
||||||
me: state.getIn(['timelines', 'me'])
|
me: state.getIn(['meta', 'me'])
|
||||||
});
|
});
|
||||||
|
|
||||||
const AccountTimeline = React.createClass({
|
const AccountTimeline = React.createClass({
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { connect } from 'react-redux';
|
||||||
import SuggestionsBox from '../components/suggestions_box';
|
import SuggestionsBox from '../components/suggestions_box';
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
accountIds: state.get('suggestions')
|
accountIds: state.getIn(['user_lists', 'suggestions'])
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(SuggestionsBox);
|
export default connect(mapStateToProps)(SuggestionsBox);
|
||||||
|
|
|
@ -11,7 +11,7 @@ const makeMapStateToProps = () => {
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
account: getAccount(state, props.id),
|
account: getAccount(state, props.id),
|
||||||
me: state.getIn(['timelines', 'me'])
|
me: state.getIn(['meta', 'me'])
|
||||||
});
|
});
|
||||||
|
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
|
|
|
@ -31,7 +31,7 @@ const makeMapStateToProps = () => {
|
||||||
status: getStatus(state, Number(props.params.statusId)),
|
status: getStatus(state, Number(props.params.statusId)),
|
||||||
ancestorsIds: state.getIn(['timelines', 'ancestors', Number(props.params.statusId)]),
|
ancestorsIds: state.getIn(['timelines', 'ancestors', Number(props.params.statusId)]),
|
||||||
descendantsIds: state.getIn(['timelines', 'descendants', Number(props.params.statusId)]),
|
descendantsIds: state.getIn(['timelines', 'descendants', Number(props.params.statusId)]),
|
||||||
me: state.getIn(['timelines', 'me'])
|
me: state.getIn(['meta', 'me'])
|
||||||
});
|
});
|
||||||
|
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
|
@ -43,8 +43,8 @@ const Status = React.createClass({
|
||||||
params: React.PropTypes.object.isRequired,
|
params: React.PropTypes.object.isRequired,
|
||||||
dispatch: React.PropTypes.func.isRequired,
|
dispatch: React.PropTypes.func.isRequired,
|
||||||
status: ImmutablePropTypes.map,
|
status: ImmutablePropTypes.map,
|
||||||
ancestorsIds: ImmutablePropTypes.orderedSet,
|
ancestorsIds: ImmutablePropTypes.list,
|
||||||
descendantsIds: ImmutablePropTypes.orderedSet
|
descendantsIds: ImmutablePropTypes.list
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [PureRenderMixin],
|
mixins: [PureRenderMixin],
|
||||||
|
@ -101,11 +101,11 @@ const Status = React.createClass({
|
||||||
|
|
||||||
const account = status.get('account');
|
const account = status.get('account');
|
||||||
|
|
||||||
if (ancestorsIds) {
|
if (ancestorsIds && ancestorsIds.size > 0) {
|
||||||
ancestors = <div>{this.renderChildren(ancestorsIds)}</div>;
|
ancestors = <div>{this.renderChildren(ancestorsIds)}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descendantsIds) {
|
if (descendantsIds && descendantsIds.size > 0) {
|
||||||
descendants = <div>{this.renderChildren(descendantsIds)}</div>;
|
descendants = <div>{this.renderChildren(descendantsIds)}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { connect } from 'react-redux';
|
||||||
import NavigationBar from '../components/navigation_bar';
|
import NavigationBar from '../components/navigation_bar';
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
account: state.getIn(['timelines', 'accounts', state.getIn(['timelines', 'me'])])
|
account: state.getIn(['accounts', state.getIn(['meta', 'me'])])
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(NavigationBar);
|
export default connect(mapStateToProps)(NavigationBar);
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
import {
|
||||||
|
ACCOUNT_SET_SELF,
|
||||||
|
ACCOUNT_FETCH_SUCCESS,
|
||||||
|
FOLLOWERS_FETCH_SUCCESS,
|
||||||
|
FOLLOWING_FETCH_SUCCESS,
|
||||||
|
ACCOUNT_TIMELINE_FETCH_SUCCESS,
|
||||||
|
ACCOUNT_TIMELINE_EXPAND_SUCCESS
|
||||||
|
} from '../actions/accounts';
|
||||||
|
import { FOLLOW_SUBMIT_SUCCESS } from '../actions/follow';
|
||||||
|
import { SUGGESTIONS_FETCH_SUCCESS } from '../actions/suggestions';
|
||||||
|
import {
|
||||||
|
REBLOG_SUCCESS,
|
||||||
|
UNREBLOG_SUCCESS,
|
||||||
|
FAVOURITE_SUCCESS,
|
||||||
|
UNFAVOURITE_SUCCESS
|
||||||
|
} from '../actions/interactions';
|
||||||
|
import {
|
||||||
|
TIMELINE_REFRESH_SUCCESS,
|
||||||
|
TIMELINE_UPDATE,
|
||||||
|
TIMELINE_EXPAND_SUCCESS
|
||||||
|
} from '../actions/timelines';
|
||||||
|
import { STATUS_FETCH_SUCCESS } from '../actions/statuses';
|
||||||
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
|
const normalizeAccount = (state, account) => state.set(account.get('id'), account);
|
||||||
|
|
||||||
|
const normalizeAccounts = (state, accounts) => {
|
||||||
|
accounts.forEach(account => {
|
||||||
|
state = normalizeAccount(state, account);
|
||||||
|
});
|
||||||
|
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalizeAccountFromStatus = (state, status) => {
|
||||||
|
state = normalizeAccount(state, status.get('account'));
|
||||||
|
|
||||||
|
if (status.getIn(['reblog', 'account'])) {
|
||||||
|
state = normalizeAccount(state, status.getIn(['reblog', 'account']));
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalizeAccountsFromStatuses = (state, statuses) => {
|
||||||
|
statuses.forEach(status => {
|
||||||
|
state = normalizeAccountFromStatus(state, status);
|
||||||
|
});
|
||||||
|
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialState = Immutable.Map();
|
||||||
|
|
||||||
|
export default function accounts(state = initialState, action) {
|
||||||
|
switch(action.type) {
|
||||||
|
case ACCOUNT_SET_SELF:
|
||||||
|
case ACCOUNT_FETCH_SUCCESS:
|
||||||
|
case FOLLOW_SUBMIT_SUCCESS:
|
||||||
|
return normalizeAccount(state, Immutable.fromJS(action.account));
|
||||||
|
case SUGGESTIONS_FETCH_SUCCESS:
|
||||||
|
case FOLLOWERS_FETCH_SUCCESS:
|
||||||
|
case FOLLOWING_FETCH_SUCCESS:
|
||||||
|
return normalizeAccounts(state, Immutable.fromJS(action.accounts));
|
||||||
|
case TIMELINE_REFRESH_SUCCESS:
|
||||||
|
case TIMELINE_EXPAND_SUCCESS:
|
||||||
|
case ACCOUNT_TIMELINE_FETCH_SUCCESS:
|
||||||
|
case ACCOUNT_TIMELINE_EXPAND_SUCCESS:
|
||||||
|
return normalizeAccountsFromStatuses(state, Immutable.fromJS(action.statuses));
|
||||||
|
case TIMELINE_UPDATE:
|
||||||
|
case REBLOG_SUCCESS:
|
||||||
|
case FAVOURITE_SUCCESS:
|
||||||
|
case UNREBLOG_SUCCESS:
|
||||||
|
case UNFAVOURITE_SUCCESS:
|
||||||
|
case STATUS_FETCH_SUCCESS:
|
||||||
|
return normalizeAccountFromStatus(state, Immutable.fromJS(action.status));
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
|
@ -11,10 +11,10 @@ import {
|
||||||
COMPOSE_UPLOAD_FAIL,
|
COMPOSE_UPLOAD_FAIL,
|
||||||
COMPOSE_UPLOAD_UNDO,
|
COMPOSE_UPLOAD_UNDO,
|
||||||
COMPOSE_UPLOAD_PROGRESS
|
COMPOSE_UPLOAD_PROGRESS
|
||||||
} from '../actions/compose';
|
} from '../actions/compose';
|
||||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
import { TIMELINE_DELETE } from '../actions/timelines';
|
||||||
import { ACCOUNT_SET_SELF } from '../actions/accounts';
|
import { ACCOUNT_SET_SELF } from '../actions/accounts';
|
||||||
import Immutable from 'immutable';
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
const initialState = Immutable.Map({
|
const initialState = Immutable.Map({
|
||||||
text: '',
|
text: '',
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
FOLLOW_SUBMIT_REQUEST,
|
FOLLOW_SUBMIT_REQUEST,
|
||||||
FOLLOW_SUBMIT_SUCCESS,
|
FOLLOW_SUBMIT_SUCCESS,
|
||||||
FOLLOW_SUBMIT_FAIL
|
FOLLOW_SUBMIT_FAIL
|
||||||
} from '../actions/follow';
|
} from '../actions/follow';
|
||||||
import Immutable from 'immutable';
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
const initialState = Immutable.Map({
|
const initialState = Immutable.Map({
|
||||||
|
|
|
@ -7,7 +7,9 @@ import notifications from './notifications';
|
||||||
import { loadingBarReducer } from 'react-redux-loading-bar';
|
import { loadingBarReducer } from 'react-redux-loading-bar';
|
||||||
import modal from './modal';
|
import modal from './modal';
|
||||||
import user_lists from './user_lists';
|
import user_lists from './user_lists';
|
||||||
import suggestions from './suggestions';
|
import accounts from './accounts';
|
||||||
|
import statuses from './statuses';
|
||||||
|
import relationships from './relationships';
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
timelines,
|
timelines,
|
||||||
|
@ -18,5 +20,7 @@ export default combineReducers({
|
||||||
loadingBar: loadingBarReducer,
|
loadingBar: loadingBarReducer,
|
||||||
modal,
|
modal,
|
||||||
user_lists,
|
user_lists,
|
||||||
suggestions
|
accounts,
|
||||||
|
statuses,
|
||||||
|
relationships
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { ACCESS_TOKEN_SET } from '../actions/meta';
|
import { ACCESS_TOKEN_SET } from '../actions/meta';
|
||||||
import Immutable from 'immutable';
|
import { ACCOUNT_SET_SELF } from '../actions/accounts';
|
||||||
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
const initialState = Immutable.Map();
|
const initialState = Immutable.Map();
|
||||||
|
|
||||||
|
@ -7,6 +8,8 @@ export default function meta(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case ACCESS_TOKEN_SET:
|
case ACCESS_TOKEN_SET:
|
||||||
return state.set('access_token', action.token);
|
return state.set('access_token', action.token);
|
||||||
|
case ACCOUNT_SET_SELF:
|
||||||
|
return state.set('me', action.account.id);
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ import {
|
||||||
NOTIFICATION_SHOW,
|
NOTIFICATION_SHOW,
|
||||||
NOTIFICATION_DISMISS,
|
NOTIFICATION_DISMISS,
|
||||||
NOTIFICATION_CLEAR
|
NOTIFICATION_CLEAR
|
||||||
} from '../actions/notifications';
|
} from '../actions/notifications';
|
||||||
import Immutable from 'immutable';
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
const initialState = Immutable.List([]);
|
const initialState = Immutable.List([]);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
import {
|
||||||
|
ACCOUNT_FOLLOW_SUCCESS,
|
||||||
|
ACCOUNT_UNFOLLOW_SUCCESS,
|
||||||
|
ACCOUNT_BLOCK_SUCCESS,
|
||||||
|
ACCOUNT_UNBLOCK_SUCCESS,
|
||||||
|
RELATIONSHIPS_FETCH_SUCCESS
|
||||||
|
} from '../actions/accounts';
|
||||||
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
|
const normalizeRelationship = (state, relationship) => state.set(relationship.get('id'), relationship);
|
||||||
|
|
||||||
|
const normalizeRelationships = (state, relationships) => {
|
||||||
|
relationships.forEach(relationship => {
|
||||||
|
state = normalizeRelationship(state, relationship);
|
||||||
|
});
|
||||||
|
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialState = Immutable.Map();
|
||||||
|
|
||||||
|
export default function relationships(state = initialState, action) {
|
||||||
|
switch(action.type) {
|
||||||
|
case ACCOUNT_FOLLOW_SUCCESS:
|
||||||
|
case ACCOUNT_UNFOLLOW_SUCCESS:
|
||||||
|
case ACCOUNT_BLOCK_SUCCESS:
|
||||||
|
case ACCOUNT_UNBLOCK_SUCCESS:
|
||||||
|
return normalizeRelationship(state, Immutable.fromJS(action.relationship));
|
||||||
|
case RELATIONSHIPS_FETCH_SUCCESS:
|
||||||
|
return normalizeRelationships(state, Immutable.fromJS(action.relationships));
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,68 @@
|
||||||
|
import {
|
||||||
|
REBLOG_SUCCESS,
|
||||||
|
UNREBLOG_SUCCESS,
|
||||||
|
FAVOURITE_SUCCESS,
|
||||||
|
UNFAVOURITE_SUCCESS
|
||||||
|
} from '../actions/interactions';
|
||||||
|
import {
|
||||||
|
STATUS_FETCH_SUCCESS,
|
||||||
|
CONTEXT_FETCH_SUCCESS
|
||||||
|
} from '../actions/statuses';
|
||||||
|
import {
|
||||||
|
TIMELINE_REFRESH_SUCCESS,
|
||||||
|
TIMELINE_UPDATE,
|
||||||
|
TIMELINE_DELETE,
|
||||||
|
TIMELINE_EXPAND_SUCCESS
|
||||||
|
} from '../actions/timelines';
|
||||||
|
import {
|
||||||
|
ACCOUNT_TIMELINE_FETCH_SUCCESS,
|
||||||
|
ACCOUNT_TIMELINE_EXPAND_SUCCESS
|
||||||
|
} from '../actions/accounts';
|
||||||
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
|
const normalizeStatus = (state, status) => {
|
||||||
|
status = status.set('account', status.getIn(['account', 'id']));
|
||||||
|
|
||||||
|
if (status.getIn(['reblog', 'id'])) {
|
||||||
|
state = normalizeStatus(state, status.get('reblog'));
|
||||||
|
status = status.set('reblog', status.getIn(['reblog', 'id']));
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.set(status.get('id'), status);
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalizeStatuses = (state, statuses) => {
|
||||||
|
statuses.forEach(status => {
|
||||||
|
state = normalizeStatus(state, status);
|
||||||
|
});
|
||||||
|
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteStatus = (state, id, references) => {
|
||||||
|
references.forEach(ref => {
|
||||||
|
state = deleteStatus(state, ref[0], []);
|
||||||
|
});
|
||||||
|
|
||||||
|
return state.delete(id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialState = Immutable.Map();
|
||||||
|
|
||||||
|
export default function statuses(state = initialState, action) {
|
||||||
|
switch(action.type) {
|
||||||
|
case TIMELINE_UPDATE:
|
||||||
|
case STATUS_FETCH_SUCCESS:
|
||||||
|
return normalizeStatus(state, Immutable.fromJS(action.status));
|
||||||
|
case TIMELINE_REFRESH_SUCCESS:
|
||||||
|
case TIMELINE_EXPAND_SUCCESS:
|
||||||
|
case ACCOUNT_TIMELINE_FETCH_SUCCESS:
|
||||||
|
case ACCOUNT_TIMELINE_EXPAND_SUCCESS:
|
||||||
|
case CONTEXT_FETCH_SUCCESS:
|
||||||
|
return normalizeStatuses(state, Immutable.fromJS(action.statuses));
|
||||||
|
case TIMELINE_DELETE:
|
||||||
|
return deleteStatus(state, action.id, action.references);
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,13 +0,0 @@
|
||||||
import { SUGGESTIONS_FETCH_SUCCESS } from '../actions/suggestions';
|
|
||||||
import Immutable from 'immutable';
|
|
||||||
|
|
||||||
const initialState = Immutable.List();
|
|
||||||
|
|
||||||
export default function suggestions(state = initialState, action) {
|
|
||||||
switch(action.type) {
|
|
||||||
case SUGGESTIONS_FETCH_SUCCESS:
|
|
||||||
return Immutable.List(action.accounts.map(item => item.id));
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,85 +3,52 @@ import {
|
||||||
TIMELINE_UPDATE,
|
TIMELINE_UPDATE,
|
||||||
TIMELINE_DELETE,
|
TIMELINE_DELETE,
|
||||||
TIMELINE_EXPAND_SUCCESS
|
TIMELINE_EXPAND_SUCCESS
|
||||||
} from '../actions/timelines';
|
} from '../actions/timelines';
|
||||||
import {
|
import {
|
||||||
REBLOG_SUCCESS,
|
REBLOG_SUCCESS,
|
||||||
UNREBLOG_SUCCESS,
|
UNREBLOG_SUCCESS,
|
||||||
FAVOURITE_SUCCESS,
|
FAVOURITE_SUCCESS,
|
||||||
UNFAVOURITE_SUCCESS
|
UNFAVOURITE_SUCCESS
|
||||||
} from '../actions/interactions';
|
} from '../actions/interactions';
|
||||||
import {
|
import {
|
||||||
ACCOUNT_SET_SELF,
|
|
||||||
ACCOUNT_FETCH_SUCCESS,
|
ACCOUNT_FETCH_SUCCESS,
|
||||||
ACCOUNT_FOLLOW_SUCCESS,
|
|
||||||
ACCOUNT_UNFOLLOW_SUCCESS,
|
|
||||||
ACCOUNT_BLOCK_SUCCESS,
|
|
||||||
ACCOUNT_UNBLOCK_SUCCESS,
|
|
||||||
ACCOUNT_TIMELINE_FETCH_SUCCESS,
|
ACCOUNT_TIMELINE_FETCH_SUCCESS,
|
||||||
ACCOUNT_TIMELINE_EXPAND_SUCCESS,
|
ACCOUNT_TIMELINE_EXPAND_SUCCESS
|
||||||
FOLLOWERS_FETCH_SUCCESS,
|
} from '../actions/accounts';
|
||||||
FOLLOWING_FETCH_SUCCESS,
|
|
||||||
RELATIONSHIPS_FETCH_SUCCESS
|
|
||||||
} from '../actions/accounts';
|
|
||||||
import {
|
import {
|
||||||
STATUS_FETCH_SUCCESS,
|
STATUS_FETCH_SUCCESS,
|
||||||
STATUS_DELETE_SUCCESS
|
CONTEXT_FETCH_SUCCESS
|
||||||
} from '../actions/statuses';
|
} from '../actions/statuses';
|
||||||
import { FOLLOW_SUBMIT_SUCCESS } from '../actions/follow';
|
import Immutable from 'immutable';
|
||||||
import { SUGGESTIONS_FETCH_SUCCESS } from '../actions/suggestions';
|
|
||||||
import Immutable from 'immutable';
|
|
||||||
|
|
||||||
const initialState = Immutable.Map({
|
const initialState = Immutable.Map({
|
||||||
home: Immutable.List([]),
|
home: Immutable.List(),
|
||||||
mentions: Immutable.List([]),
|
mentions: Immutable.List(),
|
||||||
public: Immutable.List([]),
|
public: Immutable.List(),
|
||||||
statuses: Immutable.Map(),
|
|
||||||
accounts: Immutable.Map(),
|
|
||||||
accounts_timelines: Immutable.Map(),
|
accounts_timelines: Immutable.Map(),
|
||||||
me: null,
|
|
||||||
ancestors: Immutable.Map(),
|
ancestors: Immutable.Map(),
|
||||||
descendants: Immutable.Map(),
|
descendants: Immutable.Map()
|
||||||
relationships: Immutable.Map(),
|
|
||||||
suggestions: Immutable.List([])
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function normalizeStatus(state, status) {
|
const normalizeStatus = (state, status) => {
|
||||||
// Separate account
|
const replyToId = status.get('in_reply_to_id');
|
||||||
let account = status.get('account');
|
const id = status.get('id');
|
||||||
status = status.set('account', account.get('id'));
|
|
||||||
|
|
||||||
// Separate reblog, repeat for reblog
|
if (replyToId) {
|
||||||
let reblog = status.get('reblog', null);
|
if (!state.getIn(['descendants', replyToId], Immutable.List()).includes(id)) {
|
||||||
|
state = state.updateIn(['descendants', replyToId], Immutable.List(), set => set.push(id));
|
||||||
if (reblog !== null) {
|
|
||||||
status = status.set('reblog', reblog.get('id'));
|
|
||||||
state = normalizeStatus(state, reblog);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replies
|
|
||||||
if (status.get('in_reply_to_id')) {
|
|
||||||
state = state.updateIn(['descendants', status.get('in_reply_to_id')], set => {
|
|
||||||
if (!Immutable.OrderedSet.isOrderedSet(set)) {
|
|
||||||
return Immutable.OrderedSet([status.get('id')]);
|
|
||||||
} else {
|
|
||||||
return set.add(status.get('id'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return state.withMutations(map => {
|
|
||||||
if (status.get('in_reply_to_id')) {
|
|
||||||
map.updateIn(['descendants', status.get('in_reply_to_id')], Immutable.OrderedSet(), set => set.add(status.get('id')));
|
|
||||||
map.updateIn(['ancestors', status.get('id')], Immutable.OrderedSet(), set => set.add(status.get('in_reply_to_id')));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map.setIn(['accounts', account.get('id')], account);
|
if (!state.getIn(['ancestors', id], Immutable.List()).includes(replyToId)) {
|
||||||
map.setIn(['statuses', status.get('id')], status);
|
state = state.updateIn(['ancestors', id], Immutable.List(), set => set.push(replyToId));
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
};
|
};
|
||||||
|
|
||||||
function normalizeTimeline(state, timeline, statuses, replace = false) {
|
const normalizeTimeline = (state, timeline, statuses, replace = false) => {
|
||||||
let ids = Immutable.List([]);
|
let ids = Immutable.List();
|
||||||
|
|
||||||
statuses.forEach((status, i) => {
|
statuses.forEach((status, i) => {
|
||||||
state = normalizeStatus(state, status);
|
state = normalizeStatus(state, status);
|
||||||
|
@ -91,8 +58,8 @@ function normalizeTimeline(state, timeline, statuses, replace = false) {
|
||||||
return state.update(timeline, list => (replace ? ids : list.unshift(...ids)));
|
return state.update(timeline, list => (replace ? ids : list.unshift(...ids)));
|
||||||
};
|
};
|
||||||
|
|
||||||
function appendNormalizedTimeline(state, timeline, statuses) {
|
const appendNormalizedTimeline = (state, timeline, statuses) => {
|
||||||
let moreIds = Immutable.List([]);
|
let moreIds = Immutable.List();
|
||||||
|
|
||||||
statuses.forEach((status, i) => {
|
statuses.forEach((status, i) => {
|
||||||
state = normalizeStatus(state, status);
|
state = normalizeStatus(state, status);
|
||||||
|
@ -102,8 +69,8 @@ function appendNormalizedTimeline(state, timeline, statuses) {
|
||||||
return state.update(timeline, list => list.push(...moreIds));
|
return state.update(timeline, list => list.push(...moreIds));
|
||||||
};
|
};
|
||||||
|
|
||||||
function normalizeAccountTimeline(state, accountId, statuses, replace = false) {
|
const normalizeAccountTimeline = (state, accountId, statuses, replace = false) => {
|
||||||
let ids = Immutable.List([]);
|
let ids = Immutable.List();
|
||||||
|
|
||||||
statuses.forEach((status, i) => {
|
statuses.forEach((status, i) => {
|
||||||
state = normalizeStatus(state, status);
|
state = normalizeStatus(state, status);
|
||||||
|
@ -113,7 +80,7 @@ function normalizeAccountTimeline(state, accountId, statuses, replace = false) {
|
||||||
return state.updateIn(['accounts_timelines', accountId], Immutable.List([]), list => (replace ? ids : list.unshift(...ids)));
|
return state.updateIn(['accounts_timelines', accountId], Immutable.List([]), list => (replace ? ids : list.unshift(...ids)));
|
||||||
};
|
};
|
||||||
|
|
||||||
function appendNormalizedAccountTimeline(state, accountId, statuses) {
|
const appendNormalizedAccountTimeline = (state, accountId, statuses) => {
|
||||||
let moreIds = Immutable.List([]);
|
let moreIds = Immutable.List([]);
|
||||||
|
|
||||||
statuses.forEach((status, i) => {
|
statuses.forEach((status, i) => {
|
||||||
|
@ -124,107 +91,60 @@ function appendNormalizedAccountTimeline(state, accountId, statuses) {
|
||||||
return state.updateIn(['accounts_timelines', accountId], Immutable.List([]), list => list.push(...moreIds));
|
return state.updateIn(['accounts_timelines', accountId], Immutable.List([]), list => list.push(...moreIds));
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateTimeline(state, timeline, status) {
|
const updateTimeline = (state, timeline, status, references) => {
|
||||||
state = normalizeStatus(state, status);
|
state = normalizeStatus(state, status);
|
||||||
|
|
||||||
state = state.update(timeline, list => {
|
state = state.update(timeline, list => {
|
||||||
const reblogOfId = status.getIn(['reblog', 'id'], null);
|
const reblogOfId = status.getIn(['reblog', 'id'], null);
|
||||||
|
|
||||||
if (reblogOfId !== null) {
|
if (reblogOfId !== null) {
|
||||||
const otherReblogs = state.get('statuses').filter(item => item.get('reblog') === reblogOfId).map((_, itemId) => itemId);
|
list = list.filterNot(itemId => references.includes(itemId));
|
||||||
list = list.filterNot(itemId => (itemId === reblogOfId || otherReblogs.includes(itemId)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return list.unshift(status.get('id'));
|
return list.unshift(status.get('id'));
|
||||||
});
|
});
|
||||||
|
|
||||||
//state = state.updateIn(['accounts_timelines', status.getIn(['account', 'id'])], Immutable.List([]), list => (list.includes(status.get('id')) ? list : list.unshift(status.get('id'))));
|
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
|
||||||
function deleteStatus(state, id) {
|
const deleteStatus = (state, id, accountId, references) => {
|
||||||
const status = state.getIn(['statuses', id]);
|
|
||||||
|
|
||||||
if (!status) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove references from timelines
|
// Remove references from timelines
|
||||||
['home', 'mentions'].forEach(function (timeline) {
|
['home', 'mentions', 'public'].forEach(function (timeline) {
|
||||||
state = state.update(timeline, list => list.filterNot(item => item === id));
|
state = state.update(timeline, list => list.filterNot(item => item === id));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove references from account timelines
|
// Remove references from account timelines
|
||||||
state = state.updateIn(['accounts_timelines', status.get('account')], Immutable.List([]), list => list.filterNot(item => item === id));
|
state = state.updateIn(['accounts_timelines', accountId], Immutable.List([]), list => list.filterNot(item => item === id));
|
||||||
|
|
||||||
|
// Remove references from context
|
||||||
|
state.getIn(['descendants', id], Immutable.List()).forEach(descendantId => {
|
||||||
|
state = state.updateIn(['ancestors', descendantId], Immutable.List(), list => list.filterNot(itemId => itemId === id));
|
||||||
|
});
|
||||||
|
|
||||||
|
state.getIn(['ancestors', id], Immutable.List()).forEach(ancestorId => {
|
||||||
|
state = state.updateIn(['descendants', ancestorId], Immutable.List(), list => list.filterNot(itemId => itemId === id));
|
||||||
|
});
|
||||||
|
|
||||||
|
state = state.deleteIn(['descendants', id]).deleteIn(['ancestors', id]);
|
||||||
|
|
||||||
// Remove reblogs of deleted status
|
// Remove reblogs of deleted status
|
||||||
const references = state.get('statuses').filter(item => item.get('reblog') === id);
|
references.forEach(ref => {
|
||||||
|
state = deleteStatus(state, ref[0], ref[1], []);
|
||||||
references.forEach(referencingId => {
|
|
||||||
state = deleteStatus(state, referencingId);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove normalized status
|
|
||||||
return state.deleteIn(['statuses', id]);
|
|
||||||
};
|
|
||||||
|
|
||||||
function normalizeAccount(state, account, relationship) {
|
|
||||||
if (relationship) {
|
|
||||||
state = normalizeRelationship(state, relationship);
|
|
||||||
}
|
|
||||||
|
|
||||||
return state.setIn(['accounts', account.get('id')], account);
|
|
||||||
};
|
|
||||||
|
|
||||||
function normalizeRelationship(state, relationship) {
|
|
||||||
if (state.get('suggestions').includes(relationship.get('id')) && (relationship.get('following') || relationship.get('blocking'))) {
|
|
||||||
state = state.update('suggestions', list => list.filterNot(id => id === relationship.get('id')));
|
|
||||||
}
|
|
||||||
|
|
||||||
return state.setIn(['relationships', relationship.get('id')], relationship);
|
|
||||||
};
|
|
||||||
|
|
||||||
function normalizeRelationships(state, relationships) {
|
|
||||||
relationships.forEach(relationship => {
|
|
||||||
state = normalizeRelationship(state, relationship);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
|
||||||
function setSelf(state, account) {
|
const normalizeContext = (state, id, ancestors, descendants) => {
|
||||||
state = normalizeAccount(state, account);
|
const ancestorsIds = ancestors.map(ancestor => ancestor.get('id'));
|
||||||
return state.set('me', account.get('id'));
|
const descendantsIds = descendants.map(descendant => descendant.get('id'));
|
||||||
};
|
|
||||||
|
|
||||||
function normalizeContext(state, status, ancestors, descendants) {
|
|
||||||
state = normalizeStatus(state, status);
|
|
||||||
|
|
||||||
let ancestorsIds = ancestors.map(ancestor => {
|
|
||||||
state = normalizeStatus(state, ancestor);
|
|
||||||
return ancestor.get('id');
|
|
||||||
}).toOrderedSet();
|
|
||||||
|
|
||||||
let descendantsIds = descendants.map(descendant => {
|
|
||||||
state = normalizeStatus(state, descendant);
|
|
||||||
return descendant.get('id');
|
|
||||||
}).toOrderedSet();
|
|
||||||
|
|
||||||
return state.withMutations(map => {
|
return state.withMutations(map => {
|
||||||
map.setIn(['ancestors', status.get('id')], ancestorsIds);
|
map.setIn(['ancestors', id], ancestorsIds);
|
||||||
map.setIn(['descendants', status.get('id')], descendantsIds);
|
map.setIn(['descendants', id], descendantsIds);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function normalizeAccounts(state, accounts) {
|
|
||||||
accounts.forEach(account => {
|
|
||||||
state = state.setIn(['accounts', account.get('id')], account);
|
|
||||||
});
|
|
||||||
|
|
||||||
return state;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function timelines(state = initialState, action) {
|
export default function timelines(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case TIMELINE_REFRESH_SUCCESS:
|
case TIMELINE_REFRESH_SUCCESS:
|
||||||
|
@ -232,37 +152,15 @@ export default function timelines(state = initialState, action) {
|
||||||
case TIMELINE_EXPAND_SUCCESS:
|
case TIMELINE_EXPAND_SUCCESS:
|
||||||
return appendNormalizedTimeline(state, action.timeline, Immutable.fromJS(action.statuses));
|
return appendNormalizedTimeline(state, action.timeline, Immutable.fromJS(action.statuses));
|
||||||
case TIMELINE_UPDATE:
|
case TIMELINE_UPDATE:
|
||||||
return updateTimeline(state, action.timeline, Immutable.fromJS(action.status));
|
return updateTimeline(state, action.timeline, Immutable.fromJS(action.status), action.references);
|
||||||
case TIMELINE_DELETE:
|
case TIMELINE_DELETE:
|
||||||
case STATUS_DELETE_SUCCESS:
|
return deleteStatus(state, action.id, action.accountId, action.references);
|
||||||
return deleteStatus(state, action.id);
|
case CONTEXT_FETCH_SUCCESS:
|
||||||
case REBLOG_SUCCESS:
|
return normalizeContext(state, action.id, Immutable.fromJS(action.ancestors), Immutable.fromJS(action.descendants));
|
||||||
case FAVOURITE_SUCCESS:
|
|
||||||
case UNREBLOG_SUCCESS:
|
|
||||||
case UNFAVOURITE_SUCCESS:
|
|
||||||
return normalizeStatus(state, Immutable.fromJS(action.response));
|
|
||||||
case ACCOUNT_SET_SELF:
|
|
||||||
return setSelf(state, Immutable.fromJS(action.account));
|
|
||||||
case ACCOUNT_FETCH_SUCCESS:
|
|
||||||
case FOLLOW_SUBMIT_SUCCESS:
|
|
||||||
return normalizeAccount(state, Immutable.fromJS(action.account), Immutable.fromJS(action.relationship));
|
|
||||||
case ACCOUNT_FOLLOW_SUCCESS:
|
|
||||||
case ACCOUNT_UNFOLLOW_SUCCESS:
|
|
||||||
case ACCOUNT_UNBLOCK_SUCCESS:
|
|
||||||
case ACCOUNT_BLOCK_SUCCESS:
|
|
||||||
return normalizeRelationship(state, Immutable.fromJS(action.relationship));
|
|
||||||
case STATUS_FETCH_SUCCESS:
|
|
||||||
return normalizeContext(state, Immutable.fromJS(action.status), Immutable.fromJS(action.context.ancestors), Immutable.fromJS(action.context.descendants));
|
|
||||||
case ACCOUNT_TIMELINE_FETCH_SUCCESS:
|
case ACCOUNT_TIMELINE_FETCH_SUCCESS:
|
||||||
return normalizeAccountTimeline(state, action.id, Immutable.fromJS(action.statuses), action.replace);
|
return normalizeAccountTimeline(state, action.id, Immutable.fromJS(action.statuses), action.replace);
|
||||||
case ACCOUNT_TIMELINE_EXPAND_SUCCESS:
|
case ACCOUNT_TIMELINE_EXPAND_SUCCESS:
|
||||||
return appendNormalizedAccountTimeline(state, action.id, Immutable.fromJS(action.statuses));
|
return appendNormalizedAccountTimeline(state, action.id, Immutable.fromJS(action.statuses));
|
||||||
case SUGGESTIONS_FETCH_SUCCESS:
|
|
||||||
case FOLLOWERS_FETCH_SUCCESS:
|
|
||||||
case FOLLOWING_FETCH_SUCCESS:
|
|
||||||
return normalizeAccounts(state, Immutable.fromJS(action.accounts));
|
|
||||||
case RELATIONSHIPS_FETCH_SUCCESS:
|
|
||||||
return normalizeRelationships(state, Immutable.fromJS(action.relationships));
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import {
|
import {
|
||||||
FOLLOWERS_FETCH_SUCCESS,
|
FOLLOWERS_FETCH_SUCCESS,
|
||||||
FOLLOWING_FETCH_SUCCESS
|
FOLLOWING_FETCH_SUCCESS
|
||||||
} from '../actions/accounts';
|
} from '../actions/accounts';
|
||||||
import Immutable from 'immutable';
|
import { SUGGESTIONS_FETCH_SUCCESS } from '../actions/suggestions';
|
||||||
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
const initialState = Immutable.Map({
|
const initialState = Immutable.Map({
|
||||||
followers: Immutable.Map(),
|
followers: Immutable.Map(),
|
||||||
following: Immutable.Map()
|
following: Immutable.Map(),
|
||||||
|
suggestions: Immutable.List()
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function userLists(state = initialState, action) {
|
export default function userLists(state = initialState, action) {
|
||||||
|
@ -15,6 +17,8 @@ export default function userLists(state = initialState, action) {
|
||||||
return state.setIn(['followers', action.id], Immutable.List(action.accounts.map(item => item.id)));
|
return state.setIn(['followers', action.id], Immutable.List(action.accounts.map(item => item.id)));
|
||||||
case FOLLOWING_FETCH_SUCCESS:
|
case FOLLOWING_FETCH_SUCCESS:
|
||||||
return state.setIn(['following', action.id], Immutable.List(action.accounts.map(item => item.id)));
|
return state.setIn(['following', action.id], Immutable.List(action.accounts.map(item => item.id)));
|
||||||
|
case SUGGESTIONS_FETCH_SUCCESS:
|
||||||
|
return state.set('suggestions', Immutable.List(action.accounts.map(item => item.id)));
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { createSelector } from 'reselect'
|
import { createSelector } from 'reselect'
|
||||||
import Immutable from 'immutable';
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
const getStatuses = state => state.getIn(['timelines', 'statuses']);
|
const getStatuses = state => state.get('statuses');
|
||||||
const getAccounts = state => state.getIn(['timelines', 'accounts']);
|
const getAccounts = state => state.get('accounts');
|
||||||
|
|
||||||
const getAccountBase = (state, id) => state.getIn(['timelines', 'accounts', id], null);
|
const getAccountBase = (state, id) => state.getIn(['accounts', id], null);
|
||||||
const getAccountRelationship = (state, id) => state.getIn(['timelines', 'relationships', id]);
|
const getAccountRelationship = (state, id) => state.getIn(['relationships', id]);
|
||||||
|
|
||||||
export const makeGetAccount = () => {
|
export const makeGetAccount = () => {
|
||||||
return createSelector([getAccountBase, getAccountRelationship], (base, relationship) => {
|
return createSelector([getAccountBase, getAccountRelationship], (base, relationship) => {
|
||||||
|
@ -17,7 +17,7 @@ export const makeGetAccount = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getStatusBase = (state, id) => state.getIn(['timelines', 'statuses', id], null);
|
const getStatusBase = (state, id) => state.getIn(['statuses', id], null);
|
||||||
|
|
||||||
export const makeGetStatus = () => {
|
export const makeGetStatus = () => {
|
||||||
return createSelector([getStatusBase, getStatuses, getAccounts], (base, statuses, accounts) => {
|
return createSelector([getStatusBase, getStatuses, getAccounts], (base, statuses, accounts) => {
|
||||||
|
|
Loading…
Reference in New Issue