108 lines
		
	
	
		
			No EOL
		
	
	
		
			3.6 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			No EOL
		
	
	
		
			3.6 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <:Window bind:online />
 | |
| <div class="timeline" role="feed" aria-label="{{label}}" on:initialized >
 | |
|   <VirtualList component="{{StatusListItem}}"
 | |
|                items="{{keyedStatuses}}"
 | |
|                on:scrollToBottom="onScrollToBottom()" />
 | |
| </div>
 | |
| <style>
 | |
|   .timeline {
 | |
|     min-height: 60vh;
 | |
|   }
 | |
| </style>
 | |
| <script>
 | |
|   import { store } from '../_utils/store'
 | |
|   import { getTimeline } from '../_utils/mastodon/timelines'
 | |
|   import StatusListItem from './StatusListItem.html'
 | |
|   import VirtualList from './VirtualList.html'
 | |
|   import { splice, push } from 'svelte-extras'
 | |
|   import worker from 'workerize-loader!../_utils/database/database'
 | |
|   import { mergeStatuses } from '../_utils/statuses'
 | |
|   import { mark, stop } from '../_utils/marks'
 | |
|   import { timelines } from '../_static/timelines'
 | |
|   import { toast } from '../_utils/toast'
 | |
| 
 | |
|   const database = worker()
 | |
| 
 | |
|   const FETCH_LIMIT = 20
 | |
| 
 | |
|   export default {
 | |
|     async oncreate() {
 | |
|       let instanceName = this.store.get('currentInstance')
 | |
|       let instanceData = this.store.get('currentInstanceData')
 | |
|       let online = this.get('online')
 | |
|       let timeline = this.get('timeline')
 | |
|       let statuses = await this.fetchStatusesAndPossiblyFallBack()
 | |
|       this.addStatuses(statuses)
 | |
|       this.set({initialized: true})
 | |
|       this.fire('initialized')
 | |
|     },
 | |
|     data: () => ({
 | |
|       StatusListItem: StatusListItem,
 | |
|       statuses: [],
 | |
|       runningUpdate: false,
 | |
|       initialized: false
 | |
|     }),
 | |
|     computed: {
 | |
|       keyedStatuses: (statuses) => statuses.map(status => ({
 | |
|         props: status,
 | |
|         key: status.id
 | |
|       })),
 | |
|       lastStatusId: (statuses) => statuses.length && statuses[statuses.length - 1].id,
 | |
|       label: (timeline, $currentInstance) => `${timelines[timeline].label} timeline for ${$currentInstance}`
 | |
|     },
 | |
|     store: () => store,
 | |
|     components: {
 | |
|       VirtualList
 | |
|     },
 | |
|     methods: {
 | |
|       splice: splice,
 | |
|       push: push,
 | |
|       async onScrollToBottom() {
 | |
|         if (!this.get('initialized')) {
 | |
|           return
 | |
|         }
 | |
|         if (this.get('runningUpdate')) {
 | |
|           return
 | |
|         }
 | |
|         mark('onScrollToBottom')
 | |
|         this.set({ runningUpdate: true })
 | |
|         let newStatuses = await this.fetchStatusesAndPossiblyFallBack()
 | |
|         this.addStatuses(newStatuses)
 | |
|         this.set({ runningUpdate: false })
 | |
|         stop('onScrollToBottom')
 | |
|       },
 | |
|       addStatuses(newStatuses) {
 | |
|         if (process.env.NODE_ENV !== 'production') {
 | |
|           console.log('addStatuses()')
 | |
|         }
 | |
|         let statuses = this.get('statuses')
 | |
|         if (!statuses) {
 | |
|           return
 | |
|         }
 | |
|         let merged = mergeStatuses(statuses, newStatuses)
 | |
|         this.set({ statuses: merged })
 | |
|       },
 | |
|       async fetchStatusesAndPossiblyFallBack() {
 | |
|         let online = this.get('online')
 | |
|         let instanceName = this.store.get('currentInstance')
 | |
|         let instanceData = this.store.get('currentInstanceData')
 | |
|         let timeline = this.get('timeline')
 | |
|         let lastStatusId = this.get('lastStatusId')
 | |
|         let statuses
 | |
|         if (!online) {
 | |
|           statuses = await database.getTimeline(instanceName, timeline, lastStatusId, FETCH_LIMIT)
 | |
|         } else {
 | |
|           try {
 | |
|             statuses = await getTimeline(instanceName, instanceData.access_token, timeline, lastStatusId, FETCH_LIMIT)
 | |
|             /* no await */ database.insertStatuses(instanceName, timeline, statuses)
 | |
|           } catch (e) {
 | |
|             console.error(e)
 | |
|             toast.say('Internet request failed. Showing offline content.')
 | |
|             statuses = await database.getTimeline(instanceName, timeline, lastStatusId, FETCH_LIMIT)
 | |
|           }
 | |
|         }
 | |
|         return statuses
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| </script> |