81 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
	
		
			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
 | 
						||
    }
 | 
						||
  })
 | 
						||
}
 |