-import api from '../api'
+import api from '../api'
+import axios from 'axios';
export const ACCOUNT_SET_SELF = 'ACCOUNT_SET_SELF';
export const ACCOUNT_TIMELINE_FETCH_SUCCESS = 'ACCOUNT_TIMELINE_FETCH_SUCCESS';
export const ACCOUNT_TIMELINE_FETCH_FAIL = 'ACCOUNT_TIMELINE_FETCH_FAIL';
+export const ACCOUNT_TIMELINE_EXPAND_REQUEST = 'ACCOUNT_TIMELINE_EXPAND_REQUEST';
+export const ACCOUNT_TIMELINE_EXPAND_SUCCESS = 'ACCOUNT_TIMELINE_EXPAND_SUCCESS';
+export const ACCOUNT_TIMELINE_EXPAND_FAIL = 'ACCOUNT_TIMELINE_EXPAND_FAIL';
+
export function setAccountSelf(account) {
return {
type: ACCOUNT_SET_SELF,
export function fetchAccount(id) {
return (dispatch, getState) => {
+ const boundApi = api(getState);
+
dispatch(fetchAccountRequest(id));
- api(getState).get(`/api/accounts/${id}`).then(response => {
- dispatch(fetchAccountSuccess(response.data));
+ axios.all([boundApi.get(`/api/accounts/${id}`), boundApi.get(`/api/accounts/relationships?id=${id}`)]).then(values => {
+ dispatch(fetchAccountSuccess(values[0].data, values[1].data[0]));
}).catch(error => {
dispatch(fetchAccountFail(id, error));
});
};
};
+export function expandAccountTimeline(id) {
+ return (dispatch, getState) => {
+ const lastId = getState().getIn(['timelines', 'accounts_timelines', id]).last();
+
+ dispatch(expandAccountTimelineRequest(id));
+
+ api(getState).get(`/api/accounts/${id}/statuses?max_id=${lastId}`).then(response => {
+ dispatch(expandAccountTimelineSuccess(id, response.data));
+ }).catch(error => {
+ dispatch(expandAccountTimelineFail(id, error));
+ });
+ };
+};
+
export function fetchAccountRequest(id) {
return {
type: ACCOUNT_FETCH_REQUEST,
};
};
-export function fetchAccountSuccess(account) {
+export function fetchAccountSuccess(account, relationship) {
return {
type: ACCOUNT_FETCH_SUCCESS,
- account: account
+ account: account,
+ relationship: relationship
};
};
error: error
};
};
+
+export function expandAccountTimelineRequest(id) {
+ return {
+ type: ACCOUNT_TIMELINE_EXPAND_REQUEST,
+ id: id
+ };
+};
+
+export function expandAccountTimelineSuccess(id, statuses) {
+ return {
+ type: ACCOUNT_TIMELINE_EXPAND_SUCCESS,
+ id: id,
+ statuses: statuses
+ };
+};
+
+export function expandAccountTimelineFail(id, error) {
+ return {
+ type: ACCOUNT_TIMELINE_EXPAND_FAIL,
+ id: id,
+ error: error
+ };
+};
-import { connect } from 'react-redux';
-import PureRenderMixin from 'react-addons-pure-render-mixin';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import { fetchAccount, followAccount, unfollowAccount, fetchAccountTimeline } from '../../actions/accounts';
-import { replyCompose } from '../../actions/compose';
-import { favourite, reblog } from '../../actions/interactions';
-import Header from './components/header';
-import { selectStatus } from '../../reducers/timelines';
-import StatusList from '../../components/status_list';
-import Immutable from 'immutable';
+import { connect } from 'react-redux';
+import PureRenderMixin from 'react-addons-pure-render-mixin';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import {
+ fetchAccount,
+ followAccount,
+ unfollowAccount,
+ fetchAccountTimeline,
+ expandAccountTimeline
+} from '../../actions/accounts';
+import { replyCompose } from '../../actions/compose';
+import { favourite, reblog } from '../../actions/interactions';
+import Header from './components/header';
+import { selectStatus } from '../../reducers/timelines';
+import StatusList from '../../components/status_list';
+import Immutable from 'immutable';
function selectAccount(state, id) {
return state.getIn(['timelines', 'accounts', id], null);
this.props.dispatch(favourite(status));
},
+ handleScrollToBottom () {
+ this.props.dispatch(expandAccountTimeline(this.props.account.get('id')));
+ },
+
render () {
const { account, statuses } = this.props;
return (
<div style={{ display: 'flex', flexDirection: 'column', 'flex': '0 0 auto', height: '100%' }}>
<Header account={account} onFollow={this.handleFollow} onUnfollow={this.handleUnfollow} />
- <StatusList statuses={statuses} onReply={this.handleReply} onReblog={this.handleReblog} onFavourite={this.handleFavourite} />
+ <StatusList statuses={statuses} onScrollToBottom={this.handleScrollToBottom} onReply={this.handleReply} onReblog={this.handleReblog} onFavourite={this.handleFavourite} />
</div>
);
}
ACCOUNT_FETCH_FAIL,
ACCOUNT_FOLLOW_FAIL,
ACCOUNT_UNFOLLOW_FAIL,
- ACCOUNT_TIMELINE_FETCH_FAIL
+ ACCOUNT_TIMELINE_FETCH_FAIL,
+ ACCOUNT_TIMELINE_EXPAND_FAIL
} from '../actions/accounts';
import { STATUS_FETCH_FAIL } from '../actions/statuses';
import Immutable from 'immutable';
case ACCOUNT_FOLLOW_FAIL:
case ACCOUNT_UNFOLLOW_FAIL:
case ACCOUNT_TIMELINE_FETCH_FAIL:
+ case ACCOUNT_TIMELINE_EXPAND_FAIL:
case STATUS_FETCH_FAIL:
return notificationFromError(state, action.error);
case NOTIFICATION_DISMISS:
ACCOUNT_FETCH_SUCCESS,
ACCOUNT_FOLLOW_SUCCESS,
ACCOUNT_UNFOLLOW_SUCCESS,
- ACCOUNT_TIMELINE_FETCH_SUCCESS
+ ACCOUNT_TIMELINE_FETCH_SUCCESS,
+ ACCOUNT_TIMELINE_EXPAND_SUCCESS
} from '../actions/accounts';
import { STATUS_FETCH_SUCCESS } from '../actions/statuses';
import { FOLLOW_SUBMIT_SUCCESS } from '../actions/follow';
return state;
};
+function appendNormalizedAccountTimeline(state, accountId, statuses) {
+ let moreIds = Immutable.List();
+
+ statuses.forEach((status, i) => {
+ state = normalizeStatus(state, status);
+ moreIds = moreIds.set(i, status.get('id'));
+ });
+
+ return state.updateIn(['accounts_timelines', accountId], Immutable.List(), list => list.push(...moreIds));
+};
+
function updateTimeline(state, timeline, status) {
state = normalizeStatus(state, status);
state = state.update(timeline, list => list.unshift(status.get('id')));
return normalizeContext(state, Immutable.fromJS(action.status), Immutable.fromJS(action.context.ancestors), Immutable.fromJS(action.context.descendants));
case ACCOUNT_TIMELINE_FETCH_SUCCESS:
return normalizeAccountTimeline(state, action.id, Immutable.fromJS(action.statuses));
+ case ACCOUNT_TIMELINE_EXPAND_SUCCESS:
+ return appendNormalizedAccountTimeline(state, action.id, Immutable.fromJS(action.statuses));
default:
return state;
}