diff --git a/app/assets/javascripts/components/actions/compose.jsx b/app/assets/javascripts/components/actions/compose.jsx
index 03aae885e05..8d030fd30b5 100644
--- a/app/assets/javascripts/components/actions/compose.jsx
+++ b/app/assets/javascripts/components/actions/compose.jsx
@@ -85,6 +85,7 @@ export function submitCompose() {
dispatch(updateTimeline('home', { ...response.data }));
if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
+ dispatch(updateTimeline('community', { ...response.data }));
dispatch(updateTimeline('public', { ...response.data }));
}
}).catch(function (error) {
diff --git a/app/assets/javascripts/components/actions/timelines.jsx b/app/assets/javascripts/components/actions/timelines.jsx
index 1531b89a33d..f2680177cd3 100644
--- a/app/assets/javascripts/components/actions/timelines.jsx
+++ b/app/assets/javascripts/components/actions/timelines.jsx
@@ -1,4 +1,4 @@
-import api from '../api'
+import api, { getLinks } from '../api'
import Immutable from 'immutable';
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
@@ -14,12 +14,13 @@ export const TIMELINE_EXPAND_FAIL = 'TIMELINE_EXPAND_FAIL';
export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP';
-export function refreshTimelineSuccess(timeline, statuses, skipLoading) {
+export function refreshTimelineSuccess(timeline, statuses, skipLoading, next) {
return {
type: TIMELINE_REFRESH_SUCCESS,
timeline,
statuses,
- skipLoading
+ skipLoading,
+ next
};
};
@@ -69,25 +70,22 @@ export function refreshTimeline(timeline, id = null) {
const ids = getState().getIn(['timelines', timeline, 'items'], Immutable.List());
const newestId = ids.size > 0 ? ids.first() : null;
+ const params = getState().getIn(['timelines', timeline, 'params'], {});
+ const path = getState().getIn(['timelines', timeline, 'path'])(id);
- let params = '';
- let path = timeline;
let skipLoading = false;
if (newestId !== null && getState().getIn(['timelines', timeline, 'loaded']) && (id === null || getState().getIn(['timelines', timeline, 'id']) === id)) {
- params = `?since_id=${newestId}`;
- skipLoading = true;
- }
-
- if (id) {
- path = `${path}/${id}`
+ params.since_id = newestId;
+ skipLoading = true;
}
dispatch(refreshTimelineRequest(timeline, id, skipLoading));
- api(getState).get(`/api/v1/timelines/${path}${params}`).then(function (response) {
- dispatch(refreshTimelineSuccess(timeline, response.data, skipLoading));
- }).catch(function (error) {
+ api(getState).get(path, { params }).then(response => {
+ const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(refreshTimelineSuccess(timeline, response.data, skipLoading, next ? next.uri : null));
+ }).catch(error => {
dispatch(refreshTimelineFail(timeline, error, skipLoading));
});
};
@@ -102,50 +100,48 @@ export function refreshTimelineFail(timeline, error, skipLoading) {
};
};
-export function expandTimeline(timeline, id = null) {
+export function expandTimeline(timeline) {
return (dispatch, getState) => {
- const lastId = getState().getIn(['timelines', timeline, 'items'], Immutable.List()).last();
-
- if (!lastId || getState().getIn(['timelines', timeline, 'isLoading'])) {
- // If timeline is empty, don't try to load older posts since there are none
- // Also if already loading
+ if (getState().getIn(['timelines', timeline, 'isLoading'])) {
return;
}
- dispatch(expandTimelineRequest(timeline, id));
+ const next = getState().getIn(['timelines', timeline, 'next']);
+ const params = getState().getIn(['timelines', timeline, 'params'], {});
- let path = timeline;
-
- if (id) {
- path = `${path}/${id}`
+ if (next === null) {
+ return;
}
- api(getState).get(`/api/v1/timelines/${path}`, {
+ dispatch(expandTimelineRequest(timeline));
+
+ api(getState).get(next, {
params: {
- limit: 10,
- max_id: lastId
+ ...params,
+ limit: 10
}
}).then(response => {
- dispatch(expandTimelineSuccess(timeline, response.data));
+ const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(expandTimelineSuccess(timeline, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(expandTimelineFail(timeline, error));
});
};
};
-export function expandTimelineRequest(timeline, id) {
+export function expandTimelineRequest(timeline) {
return {
type: TIMELINE_EXPAND_REQUEST,
- timeline,
- id
+ timeline
};
};
-export function expandTimelineSuccess(timeline, statuses) {
+export function expandTimelineSuccess(timeline, statuses, next) {
return {
type: TIMELINE_EXPAND_SUCCESS,
timeline,
- statuses
+ statuses,
+ next
};
};
diff --git a/app/assets/javascripts/components/containers/mastodon.jsx b/app/assets/javascripts/components/containers/mastodon.jsx
index ebef5c81bc3..3e7abda451f 100644
--- a/app/assets/javascripts/components/containers/mastodon.jsx
+++ b/app/assets/javascripts/components/containers/mastodon.jsx
@@ -21,6 +21,7 @@ import UI from '../features/ui';
import Status from '../features/status';
import GettingStarted from '../features/getting_started';
import PublicTimeline from '../features/public_timeline';
+import CommunityTimeline from '../features/community_timeline';
import AccountTimeline from '../features/account_timeline';
import HomeTimeline from '../features/home_timeline';
import Compose from '../features/compose';
@@ -116,6 +117,7 @@ const Mastodon = React.createClass({