86 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { updateInstanceInfo } from '../../_actions/instances'
 | ||
| import { createStream } from '../../_actions/streaming'
 | ||
| import { getTimeline } from '../../_api/timelines'
 | ||
| import { addStatusesOrNotifications } from '../../_actions/addStatusOrNotification'
 | ||
| import { TIMELINE_BATCH_SIZE } from '../../_static/timelines'
 | ||
| 
 | ||
| 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()
 | ||
|     let { accessToken } = store.get()
 | ||
|     await updateInstanceInfo(currentInstance)
 | ||
| 
 | ||
|     let currentTimelineIsUnchanged = () => {
 | ||
|       let {
 | ||
|         currentInstance: newCurrentInstance,
 | ||
|         currentTimeline: newCurrentTimeline
 | ||
|       } = store.get()
 | ||
|       return newCurrentInstance === currentInstance &&
 | ||
|         newCurrentTimeline === 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, TIMELINE_BATCH_SIZE)
 | ||
|       if (newTimelineItems.length) {
 | ||
|         addStatusesOrNotifications(currentInstance, currentTimeline, newTimelineItems)
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     let { currentInstanceInfo } = store.get()
 | ||
|     let streamingApi = currentInstanceInfo.urls.streaming_api
 | ||
|     currentTimelineStream = createStream(streamingApi, currentInstance, accessToken,
 | ||
|       currentTimeline, onOpenStream)
 | ||
| 
 | ||
|     if (process.env.NODE_ENV !== 'production') {
 | ||
|       window.currentTimelineStream = currentTimelineStream
 | ||
|     }
 | ||
|   })
 | ||
| }
 |