pinafore/routes/_store/observers/timelineObservers.js

82 wiersze
2.6 KiB
JavaScript

import { updateInstanceInfo } from '../../_actions/instances'
import { createStream } from '../../_actions/streaming'
import { getTimeline } from '../../_api/timelines'
import { addStatusesOrNotifications } from '../../_actions/addStatusOrNotification'
export function timelineObservers (store) {
// stream to watch for local/federated/etc. updates. home and notification
// updates are handled in timelineObservers.js
let currentTimelineStream
function shutdownPreviousStream () {
if (currentTimelineStream) {
currentTimelineStream.close()
currentTimelineStream = null
if (process.env.NODE_ENV !== 'production') {
window.currentTimelineStream = null
}
}
}
function shouldObserveTimeline (timeline) {
return timeline &&
!(
timeline !== 'local' &&
timeline !== 'federated' &&
!timeline.startsWith('list/') &&
!timeline.startsWith('tag/')
)
}
store.observe('currentTimeline', async (currentTimeline) => {
if (!process.browser) {
return
}
shutdownPreviousStream()
if (!shouldObserveTimeline(currentTimeline)) {
return
}
let currentInstance = store.get('currentInstance')
let accessToken = store.get('accessToken')
await updateInstanceInfo(currentInstance)
let currentTimelineIsUnchanged = () => (
store.get('currentInstance') === currentInstance &&
store.get('currentTimeline') === currentTimeline
)
if (!currentTimelineIsUnchanged()) {
return
}
let timelineItemIds = store.getForTimeline(currentInstance,
currentTimeline, 'timelineItemIds')
let firstTimelineItemId = timelineItemIds && timelineItemIds[0]
let onOpenStream = async () => {
if (!firstTimelineItemId || !currentTimelineIsUnchanged()) {
return
}
// fill in the "streaming gap" – i.e. fetch the most recent 20 items so that there isn't
// a big gap in the timeline if you haven't looked at it in awhile
let newTimelineItems = await getTimeline(currentInstance, accessToken,
currentTimeline, null, firstTimelineItemId)
if (newTimelineItems.length) {
addStatusesOrNotifications(currentInstance, currentTimeline, newTimelineItems)
}
}
let instanceInfo = store.get('currentInstanceInfo')
let streamingApi = instanceInfo.urls.streaming_api
currentTimelineStream = createStream(streamingApi, currentInstance, accessToken,
currentTimeline, onOpenStream)
if (process.env.NODE_ENV !== 'production') {
window.currentTimelineStream = currentTimelineStream
}
})
}