diff --git a/routes/_actions/timeline.js b/routes/_actions/timeline.js index c2d322c0d..fd877af2b 100644 --- a/routes/_actions/timeline.js +++ b/routes/_actions/timeline.js @@ -2,7 +2,7 @@ import { store } from '../_store/store' import { getTimeline } from '../_api/timelines' import { toast } from '../_utils/toast' import { mark, stop } from '../_utils/marks' -import { mergeArrays } from '../_utils/arrays' +import { concat, mergeArrays } from '../_utils/arrays' import { byItemIds } from '../_utils/sorting' import isEqual from 'lodash-es/isEqual' import { @@ -11,9 +11,22 @@ import { import { getTimeline as getTimelineFromDatabase } from '../_database/timelines/pagination' +import { getStatus, getStatusContext } from '../_api/statuses' const FETCH_LIMIT = 20 +async function fetchTimelineItemsFromNetwork (instanceName, accessToken, timelineName, lastTimelineItemId) { + if (timelineName.startsWith('status/')) { // special case - this is a list of descendents and ancestors + let statusId = timelineName.split('/').slice(-1)[0] + let statusRequest = getStatus(instanceName, accessToken, statusId) + let contextRequest = getStatusContext(instanceName, accessToken, statusId) + let [ status, context ] = await Promise.all([statusRequest, contextRequest]) + return concat(context.ancestors, status, context.descendants) + } else { // normal timeline + return getTimeline(instanceName, accessToken, timelineName, lastTimelineItemId, FETCH_LIMIT) + } +} + async function fetchTimelineItems (instanceName, accessToken, timelineName, lastTimelineItemId, online) { mark('fetchTimelineItems') let items @@ -23,7 +36,7 @@ async function fetchTimelineItems (instanceName, accessToken, timelineName, last stale = true } else { try { - items = await getTimeline(instanceName, accessToken, timelineName, lastTimelineItemId, FETCH_LIMIT) + items = await fetchTimelineItemsFromNetwork(instanceName, accessToken, timelineName, lastTimelineItemId) /* no await */ insertTimelineItemsInDatabase(instanceName, timelineName, items) } catch (e) { console.error(e) diff --git a/routes/_api/statuses.js b/routes/_api/statuses.js index 430df44ae..12f6ea9b0 100644 --- a/routes/_api/statuses.js +++ b/routes/_api/statuses.js @@ -1,5 +1,5 @@ import { auth, basename } from './utils' -import { post, WRITE_TIMEOUT } from '../_utils/ajax' +import { DEFAULT_TIMEOUT, get, post, WRITE_TIMEOUT } from '../_utils/ajax' export async function postStatus (instanceName, accessToken, text, inReplyToId, mediaIds, sensitive, spoilerText, visibility) { @@ -23,3 +23,13 @@ export async function postStatus (instanceName, accessToken, text, inReplyToId, return post(url, body, auth(accessToken), {timeout: WRITE_TIMEOUT}) } + +export async function getStatusContext (instanceName, accessToken, statusId) { + let url = `${basename(instanceName)}/api/v1/statuses/${statusId}/context` + return get(url, auth(accessToken), {timeout: DEFAULT_TIMEOUT}) +} + +export async function getStatus (instanceName, accessToken, statusId) { + let url = `${basename(instanceName)}/api/v1/statuses/${statusId}` + return get(url, auth(accessToken), {timeout: DEFAULT_TIMEOUT}) +} diff --git a/routes/_api/timelines.js b/routes/_api/timelines.js index dfc5a6f4a..6ac5ca1f3 100644 --- a/routes/_api/timelines.js +++ b/routes/_api/timelines.js @@ -15,8 +15,6 @@ function getTimelineUrlPath (timeline) { } if (timeline.startsWith('tag/')) { return 'timelines/tag' - } else if (timeline.startsWith('status/')) { - return 'statuses' } else if (timeline.startsWith('account/')) { return 'accounts' } else if (timeline.startsWith('list/')) { @@ -30,8 +28,6 @@ export function getTimeline (instanceName, accessToken, timeline, maxId, since) if (timeline.startsWith('tag/')) { url += '/' + timeline.split('/').slice(-1)[0] - } else if (timeline.startsWith('status/')) { - url += '/' + timeline.split('/').slice(-1)[0] + '/context' } else if (timeline.startsWith('account/')) { url += '/' + timeline.split('/').slice(-1)[0] + '/statuses' } else if (timeline.startsWith('list/')) { @@ -53,16 +49,5 @@ export function getTimeline (instanceName, accessToken, timeline, maxId, since) url += '?' + paramsString(params) - if (timeline.startsWith('status/')) { - // special case - this is a list of descendents and ancestors - let statusUrl = `${basename(instanceName)}/api/v1/statuses/${timeline.split('/').slice(-1)[0]}` - return Promise.all([ - get(url, auth(accessToken), {timeout: DEFAULT_TIMEOUT}), - get(statusUrl, auth(accessToken), {timeout: DEFAULT_TIMEOUT}) - ]).then(res => { - return [].concat(res[0].ancestors).concat([res[1]]).concat(res[0].descendants) - }) - } - return get(url, auth(accessToken), {timeout: DEFAULT_TIMEOUT}) } diff --git a/routes/_utils/arrays.js b/routes/_utils/arrays.js index d25250e9a..7de1c4e1e 100644 --- a/routes/_utils/arrays.js +++ b/routes/_utils/arrays.js @@ -31,3 +31,16 @@ export function mergeArrays (leftArray, rightArray) { } return merged } + +export function concat () { + let res = [] + for (let i = 0, len = arguments.length; i < len; i++) { + let arg = arguments[i] + if (Array.isArray(arg)) { + res = res.concat(arguments[i]) + } else { + res.push(arguments[i]) + } + } + return res +}