forked from cybrespace/pinafore
125 lines
4.7 KiB
JavaScript
125 lines
4.7 KiB
JavaScript
import { store } from '../_store/store'
|
|
import { database } from '../_database/database'
|
|
import { getTimeline } from '../_api/timelines'
|
|
import { toast } from '../_utils/toast'
|
|
import { mark, stop } from '../_utils/marks'
|
|
import { mergeArrays } from '../_utils/arrays'
|
|
import { byItemIds } from '../_utils/sorting'
|
|
import isEqual from 'lodash-es/isEqual'
|
|
|
|
const FETCH_LIMIT = 20
|
|
|
|
async function fetchTimelineItems (instanceName, accessToken, timelineName, lastTimelineItemId, online) {
|
|
mark('fetchTimelineItems')
|
|
let items
|
|
let stale = false
|
|
if (!online) {
|
|
items = await database.getTimeline(instanceName, timelineName, lastTimelineItemId, FETCH_LIMIT)
|
|
stale = true
|
|
} else {
|
|
try {
|
|
items = await getTimeline(instanceName, accessToken, timelineName, lastTimelineItemId, FETCH_LIMIT)
|
|
/* no await */ database.insertTimelineItems(instanceName, timelineName, items)
|
|
} catch (e) {
|
|
console.error(e)
|
|
toast.say('Internet request failed. Showing offline content.')
|
|
items = await database.getTimeline(instanceName, timelineName, lastTimelineItemId, FETCH_LIMIT)
|
|
stale = true
|
|
}
|
|
}
|
|
stop('fetchTimelineItems')
|
|
return { items, stale }
|
|
}
|
|
|
|
async function addTimelineItems (instanceName, timelineName, items, stale) {
|
|
console.log('addTimelineItems, length:', items.length)
|
|
mark('addTimelineItems')
|
|
let newIds = items.map(item => item.id)
|
|
addTimelineItemIds(instanceName, timelineName, newIds, stale)
|
|
stop('addTimelineItems')
|
|
}
|
|
|
|
export async function addTimelineItemIds (instanceName, timelineName, newIds, newStale) {
|
|
let oldIds = store.getForTimeline(instanceName, timelineName, 'timelineItemIds')
|
|
let oldStale = store.getForTimeline(instanceName, timelineName, 'timelineItemIdsAreStale')
|
|
|
|
let mergedIds = mergeArrays(oldIds || [], newIds)
|
|
|
|
if (!isEqual(oldIds, mergedIds)) {
|
|
store.setForTimeline(instanceName, timelineName, {timelineItemIds: mergedIds})
|
|
}
|
|
if (oldStale !== newStale) {
|
|
store.setForTimeline(instanceName, timelineName, {timelineItemIdsAreStale: newStale})
|
|
}
|
|
}
|
|
|
|
async function fetchTimelineItemsAndPossiblyFallBack () {
|
|
mark('fetchTimelineItemsAndPossiblyFallBack')
|
|
let timelineName = store.get('currentTimeline')
|
|
let instanceName = store.get('currentInstance')
|
|
let accessToken = store.get('accessToken')
|
|
let lastTimelineItemId = store.get('lastTimelineItemId')
|
|
let online = store.get('online')
|
|
|
|
let { items, stale } = await fetchTimelineItems(instanceName, accessToken, timelineName, lastTimelineItemId, online)
|
|
addTimelineItems(instanceName, timelineName, items, stale)
|
|
stop('fetchTimelineItemsAndPossiblyFallBack')
|
|
}
|
|
|
|
export async function setupTimeline () {
|
|
mark('setupTimeline')
|
|
// If we don't have any item ids, or if the current item ids are stale
|
|
// (i.e. via offline mode), then we need to re-fetch
|
|
// Also do this if it's a thread, because threads change pretty frequently and
|
|
// we don't have a good way to update them.
|
|
|
|
let timelineItemIds = store.get('timelineItemIds')
|
|
let timelineItemIdsAreStale = store.get('timelineItemIdsAreStale')
|
|
let currentTimeline = store.get('currentTimeline')
|
|
if (!timelineItemIds ||
|
|
timelineItemIdsAreStale ||
|
|
currentTimeline.startsWith('status/')) {
|
|
await fetchTimelineItemsAndPossiblyFallBack()
|
|
}
|
|
stop('setupTimeline')
|
|
}
|
|
|
|
export async function fetchTimelineItemsOnScrollToBottom (instanceName, timelineName) {
|
|
store.setForTimeline(instanceName, timelineName, { runningUpdate: true })
|
|
await fetchTimelineItemsAndPossiblyFallBack()
|
|
store.setForTimeline(instanceName, timelineName, { runningUpdate: false })
|
|
}
|
|
|
|
export async function showMoreItemsForTimeline (instanceName, timelineName) {
|
|
mark('showMoreItemsForTimeline')
|
|
let itemIdsToAdd = store.getForTimeline(instanceName, timelineName, 'itemIdsToAdd')
|
|
itemIdsToAdd = itemIdsToAdd.sort(byItemIds).reverse()
|
|
addTimelineItemIds(instanceName, timelineName, itemIdsToAdd, false)
|
|
store.setForTimeline(instanceName, timelineName, {
|
|
itemIdsToAdd: [],
|
|
shouldShowHeader: false,
|
|
showHeader: false
|
|
})
|
|
stop('showMoreItemsForTimeline')
|
|
}
|
|
|
|
export async function showMoreItemsForCurrentTimeline () {
|
|
return showMoreItemsForTimeline(
|
|
store.get('currentInstance'),
|
|
store.get('currentTimeline')
|
|
)
|
|
}
|
|
|
|
export async function showMoreItemsForThread (instanceName, timelineName) {
|
|
mark('showMoreItemsForThread')
|
|
let itemIdsToAdd = store.getForTimeline(instanceName, timelineName, 'itemIdsToAdd')
|
|
let timelineItemIds = store.getForTimeline(instanceName, timelineName, 'timelineItemIds')
|
|
// TODO: update database and do the thread merge correctly
|
|
timelineItemIds = timelineItemIds.concat(itemIdsToAdd)
|
|
store.setForTimeline(instanceName, timelineName, {
|
|
itemIdsToAdd: [],
|
|
timelineItemIds: timelineItemIds
|
|
})
|
|
stop('showMoreItemsForThread')
|
|
}
|