| 
									
										
										
										
											2018-01-18 20:25:34 -08:00
										 |  |  | <:Window bind:online /> | 
					
						
							| 
									
										
										
										
											2018-01-21 14:31:59 -08:00
										 |  |  | <div class="timeline" role="feed" aria-label="{{label}}" on:initialized> | 
					
						
							| 
									
										
										
										
											2018-01-16 21:43:31 -08:00
										 |  |  |   <VirtualList component="{{StatusListItem}}" | 
					
						
							| 
									
										
										
										
											2018-01-23 18:15:14 -08:00
										 |  |  |                :makeProps | 
					
						
							| 
									
										
										
										
											2018-01-23 18:19:03 -08:00
										 |  |  |                items="{{statusIds}}" | 
					
						
							| 
									
										
										
										
											2018-01-21 14:31:59 -08:00
										 |  |  |                on:scrollToBottom="onScrollToBottom()" | 
					
						
							|  |  |  |                shown="{{initialized}}" | 
					
						
							| 
									
										
										
										
											2018-01-21 16:07:11 -08:00
										 |  |  |                footerComponent="{{LoadingFooter}}" | 
					
						
							|  |  |  |                showFooter="{{initialized && runningUpdate}}" | 
					
						
							| 
									
										
										
										
											2018-01-24 09:47:31 -08:00
										 |  |  |                storeKey="{{timeline}}" | 
					
						
							| 
									
										
										
										
											2018-01-24 19:26:08 -08:00
										 |  |  |                on:initializedVisibleItems="initialize()" | 
					
						
							| 
									
										
										
										
											2018-01-21 14:31:59 -08:00
										 |  |  |   /> | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  | <style> | 
					
						
							|  |  |  |   .timeline { | 
					
						
							| 
									
										
										
										
											2018-01-19 00:51:51 -08:00
										 |  |  |     min-height: 60vh; | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | </style> | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  | <script> | 
					
						
							|  |  |  |   import { store } from '../_utils/store' | 
					
						
							| 
									
										
										
										
											2018-01-18 23:37:43 -08:00
										 |  |  |   import { getTimeline } from '../_utils/mastodon/timelines' | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  |   import StatusListItem from './StatusListItem.html' | 
					
						
							| 
									
										
										
										
											2018-01-21 16:07:11 -08:00
										 |  |  |   import LoadingFooter from './LoadingFooter.html' | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  |   import VirtualList from './VirtualList.html' | 
					
						
							| 
									
										
										
										
											2018-01-17 00:06:24 -08:00
										 |  |  |   import { splice, push } from 'svelte-extras' | 
					
						
							| 
									
										
										
										
											2018-01-18 20:25:34 -08:00
										 |  |  |   import { mergeStatuses } from '../_utils/statuses' | 
					
						
							| 
									
										
										
										
											2018-01-17 00:59:15 -08:00
										 |  |  |   import { mark, stop } from '../_utils/marks' | 
					
						
							| 
									
										
										
										
											2018-01-18 23:37:43 -08:00
										 |  |  |   import { timelines } from '../_static/timelines' | 
					
						
							| 
									
										
										
										
											2018-01-19 18:04:31 -08:00
										 |  |  |   import { toast } from '../_utils/toast' | 
					
						
							| 
									
										
										
										
											2018-01-21 17:18:56 -08:00
										 |  |  |   import { database } from '../_utils/database/database' | 
					
						
							| 
									
										
										
										
											2018-01-19 01:32:23 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-24 09:47:31 -08:00
										 |  |  |   const cachedTimelines = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (process.browser && process.env.NODE_ENV !== 'production') { | 
					
						
							|  |  |  |     window.cachedTimelines = cachedTimelines | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 20:25:34 -08:00
										 |  |  |   const FETCH_LIMIT = 20 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |   export default { | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |     async oncreate() { | 
					
						
							| 
									
										
										
										
											2018-01-24 09:47:31 -08:00
										 |  |  |       let timeline = this.get('timeline') | 
					
						
							|  |  |  |       let cachedStatusIds = cachedTimelines[timeline] | 
					
						
							|  |  |  |       if (cachedStatusIds) { | 
					
						
							|  |  |  |         this.set({statusIds: cachedStatusIds}) | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         this.addStatuses(await this.fetchStatusesAndPossiblyFallBack()) | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-01-24 09:47:31 -08:00
										 |  |  |     ondestroy() { | 
					
						
							|  |  |  |       cachedTimelines[this.get('timeline')] = this.get('statusIds') | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |     data: () => ({ | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |       StatusListItem: StatusListItem, | 
					
						
							| 
									
										
										
										
											2018-01-21 16:07:11 -08:00
										 |  |  |       LoadingFooter: LoadingFooter, | 
					
						
							| 
									
										
										
										
											2018-01-23 18:15:14 -08:00
										 |  |  |       statusIds: [], | 
					
						
							| 
									
										
										
										
											2018-01-19 00:29:45 -08:00
										 |  |  |       runningUpdate: false, | 
					
						
							|  |  |  |       initialized: false | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |     }), | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |     computed: { | 
					
						
							| 
									
										
										
										
											2018-01-23 18:15:14 -08:00
										 |  |  |       makeProps: ($currentInstance) => (statusId) => database.getStatus($currentInstance, statusId), | 
					
						
							|  |  |  |       lastStatusId: (statusIds) => statusIds.length && statusIds[statusIds.length - 1], | 
					
						
							| 
									
										
										
										
											2018-01-21 20:02:32 -08:00
										 |  |  |       label: (timeline, $currentInstance) => { | 
					
						
							|  |  |  |         if (timelines[timeline]) { | 
					
						
							|  |  |  |           `${timelines[timeline].label} timeline for ${$currentInstance}` | 
					
						
							|  |  |  |         } else if (timeline.startsWith('tag/')) { | 
					
						
							|  |  |  |           let tag = timeline.split('/').slice(-1)[0] | 
					
						
							|  |  |  |           return `#${tag} timeline for ${$currentInstance}` | 
					
						
							| 
									
										
										
										
											2018-01-22 21:16:27 -08:00
										 |  |  |         } else if (timeline.startsWith('account/')) { | 
					
						
							|  |  |  |           let account = timeline.split('/').slice(-1)[0] | 
					
						
							|  |  |  |           return `Account #${account} on ${$currentInstance}` | 
					
						
							| 
									
										
										
										
											2018-01-21 20:02:32 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-01-10 20:45:02 -08:00
										 |  |  |     store: () => store, | 
					
						
							|  |  |  |     components: { | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  |       VirtualList | 
					
						
							| 
									
										
										
										
											2018-01-15 12:23:28 -08:00
										 |  |  |     }, | 
					
						
							|  |  |  |     methods: { | 
					
						
							|  |  |  |       splice: splice, | 
					
						
							| 
									
										
										
										
											2018-01-17 00:06:24 -08:00
										 |  |  |       push: push, | 
					
						
							| 
									
										
										
										
											2018-01-24 19:26:08 -08:00
										 |  |  |       initialize() { | 
					
						
							|  |  |  |         if (this.get('initialized') || !this.get('statusIds') || !this.get('statusIds').length) { | 
					
						
							|  |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         requestAnimationFrame(() => { | 
					
						
							|  |  |  |           requestAnimationFrame(() => { | 
					
						
							|  |  |  |             this.set({initialized: true}) | 
					
						
							|  |  |  |             this.fire('initialized') | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |       async onScrollToBottom() { | 
					
						
							| 
									
										
										
										
											2018-01-19 00:29:45 -08:00
										 |  |  |         if (!this.get('initialized')) { | 
					
						
							|  |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |         if (this.get('runningUpdate')) { | 
					
						
							|  |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-19 00:29:45 -08:00
										 |  |  |         mark('onScrollToBottom') | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |         this.set({ runningUpdate: true }) | 
					
						
							| 
									
										
										
										
											2018-01-19 18:04:31 -08:00
										 |  |  |         let newStatuses = await this.fetchStatusesAndPossiblyFallBack() | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |         this.set({ runningUpdate: false }) | 
					
						
							| 
									
										
										
										
											2018-01-21 16:07:11 -08:00
										 |  |  |         this.addStatuses(newStatuses) | 
					
						
							| 
									
										
										
										
											2018-01-17 08:20:41 -08:00
										 |  |  |         stop('onScrollToBottom') | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-01-18 20:25:34 -08:00
										 |  |  |       addStatuses(newStatuses) { | 
					
						
							|  |  |  |         if (process.env.NODE_ENV !== 'production') { | 
					
						
							|  |  |  |           console.log('addStatuses()') | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-23 18:15:14 -08:00
										 |  |  |         let instanceName = this.store.get('instanceName') | 
					
						
							|  |  |  |         let timeline = this.get('timeline') | 
					
						
							|  |  |  |         /* no await */ database.insertStatuses(instanceName, timeline, newStatuses) | 
					
						
							|  |  |  |         let statusIds = this.get('statusIds') | 
					
						
							|  |  |  |         if (!statusIds) { | 
					
						
							| 
									
										
										
										
											2018-01-18 20:25:34 -08:00
										 |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-23 18:15:14 -08:00
										 |  |  |         let newStatusIds = newStatuses.map(status => status.id) | 
					
						
							|  |  |  |         let merged = mergeStatuses(statusIds, newStatusIds) | 
					
						
							|  |  |  |         this.set({ statusIds: merged }) | 
					
						
							| 
									
										
										
										
											2018-01-19 18:04:31 -08:00
										 |  |  |       }, | 
					
						
							|  |  |  |       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 | 
					
						
							| 
									
										
										
										
											2018-01-20 13:01:33 -08:00
										 |  |  |         if (!online) { | 
					
						
							| 
									
										
										
										
											2018-01-19 18:04:31 -08:00
										 |  |  |           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 | 
					
						
							| 
									
										
										
										
											2018-01-15 12:23:28 -08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-01-10 20:45:02 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | </script> |