137 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
	
		
			5.1 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/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 function initializeTimeline () {
 | 
						|
  mark('initializeTimeline')
 | 
						|
  let instanceName = store.get('currentInstance')
 | 
						|
  let timeline = store.get('currentTimeline')
 | 
						|
  requestAnimationFrame(() => {
 | 
						|
    requestAnimationFrame(() => {
 | 
						|
      console.log('initialized')
 | 
						|
      store.setForTimeline(instanceName, timeline, {initialized: true})
 | 
						|
    })
 | 
						|
  })
 | 
						|
  stop('initializeTimeline')
 | 
						|
}
 | 
						|
 | 
						|
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')
 | 
						|
}
 |