pinafore/routes/_actions/timeline.js

94 lines
3.4 KiB
JavaScript

import { store } from '../_utils/store'
import { database } from '../_utils/database/database'
import { getTimeline } from '../_utils/mastodon/timelines'
import { toast } from '../_utils/toast'
import { StatusStream } from '../_utils/mastodon/StatusStream'
import { getInstanceInfo } from '../_utils/mastodon/instance'
import { mark, stop } from '../_utils/marks'
import { mergeStatuses } from '../_utils/timelines'
const FETCH_LIMIT = 20
let statusStream
async function fetchStatuses(instanceName, accessToken, timelineName, lastStatusId, online) {
mark('fetchStatuses')
let statuses
if (!online) {
statuses = await database.getTimeline(instanceName, timelineName, lastStatusId, FETCH_LIMIT)
} else {
try {
statuses = await getTimeline(instanceName, accessToken, timelineName, lastStatusId, FETCH_LIMIT)
/* no await */ database.insertStatuses(instanceName, timelineName, statuses)
} catch (e) {
console.error(e)
toast.say('Internet request failed. Showing offline content.')
statuses = await database.getTimeline(instanceName, timelineName, lastStatusId, FETCH_LIMIT)
}
}
stop('fetchStatuses')
return statuses
}
async function addStatuses(instanceName, timelineName, newStatuses) {
mark('addStatuses')
let newStatusIds = newStatuses.map(status => status.id)
let oldStatusIds = store.getForTimeline(instanceName, timelineName, 'statusIds') || []
let merged = mergeStatuses(oldStatusIds, newStatusIds)
store.setForTimeline(instanceName, timelineName, { statusIds: merged })
stop('addStatuses')
}
async function fetchStatusesAndPossiblyFallBack() {
mark('fetchStatusesAndPossiblyFallBack')
let timelineName = store.get('currentTimeline')
let instanceName = store.get('currentInstance')
let accessToken = store.get('accessToken')
let lastStatusId = store.get('lastStatusId')
let online = store.get('online')
let newStatuses = await fetchStatuses(instanceName, accessToken, timelineName, lastStatusId, online)
addStatuses(instanceName, timelineName, newStatuses)
stop('fetchStatusesAndPossiblyFallBack')
}
export function initializeTimeline() {
mark('initializeTimeline')
let instanceName = store.get('currentInstance')
let timeline = store.get('currentTimeline')
requestAnimationFrame(() => {
requestAnimationFrame(() => {
store.setForTimeline(instanceName, timeline, {initialized: true})
})
})
stop('initializeTimeline')
}
export async function setupTimeline() {
mark('addStatuses')
let timelineName = store.get('currentTimeline')
let instanceName = store.get('currentInstance')
let accessToken = store.get('accessToken')
if (!store.get('statusIds').length) {
await fetchStatusesAndPossiblyFallBack()
}
/* no await */ getInstanceInfo(instanceName).then(instanceInfo => database.setInstanceInfo(instanceName, instanceInfo))
let instanceInfo = await database.getInstanceInfo(instanceName)
if (statusStream) {
statusStream.close()
}
statusStream = new StatusStream(instanceInfo.urls.streaming_api, accessToken, timelineName, {
onMessage(message) {
console.log('message', message)
}
})
stop('addStatuses')
}
export async function fetchStatusesOnScrollToBottom() {
let timelineName = store.get('currentTimeline')
let instanceName = store.get('currentInstance')
store.setForTimeline(instanceName, timelineName, { runningUpdate: true })
await fetchStatusesAndPossiblyFallBack()
store.setForTimeline(instanceName, timelineName, { runningUpdate: false })
}