| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  | <h1 class="sr-only">{label}</h1> | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  | <div class="timeline" | 
					
						
							|  |  |  |      role="feed" | 
					
						
							|  |  |  |      on:focusWithCapture="saveFocus(event)" | 
					
						
							|  |  |  |      on:blurWithCapture="clearFocus(event)" | 
					
						
							|  |  |  | > | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |   {#await componentsPromise} | 
					
						
							| 
									
										
										
										
											2018-04-29 22:13:41 -07:00
										 |  |  |     <!-- awaiting promise --> | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |   {:then result} | 
					
						
							|  |  |  |     <svelte:component this={result.listComponent} | 
					
						
							|  |  |  |                 component={result.listItemComponent} | 
					
						
							|  |  |  |                 realm="{$currentInstance + '/' + timeline}" | 
					
						
							| 
									
										
										
										
											2018-04-21 08:45:41 -07:00
										 |  |  |                 containerQuery=".container" | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |                 {makeProps} | 
					
						
							|  |  |  |                 items={$timelineItemIds} | 
					
						
							|  |  |  |                 showFooter={$timelineInitialized && $runningUpdate} | 
					
						
							|  |  |  |                 footerComponent={LoadingFooter} | 
					
						
							|  |  |  |                 showHeader={$showHeader} | 
					
						
							|  |  |  |                 headerComponent={MoreHeaderVirtualWrapper} | 
					
						
							|  |  |  |                 {headerProps} | 
					
						
							|  |  |  |                 {scrollToItem} | 
					
						
							| 
									
										
										
										
											2018-04-21 08:45:41 -07:00
										 |  |  |                 on:scrollToBottom="onScrollToBottom()" | 
					
						
							|  |  |  |                 on:scrollToTop="onScrollToTop()" | 
					
						
							|  |  |  |                 on:scrollTopChanged="onScrollTopChanged(event)" | 
					
						
							|  |  |  |                 on:initialized="initialize()" | 
					
						
							|  |  |  |                 on:noNeedToScroll="onNoNeedToScroll()" | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |     /> | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |   {:catch error} | 
					
						
							|  |  |  |     <div>Error: component failed to load! Try reloading. {error}</div> | 
					
						
							|  |  |  |   {/await} | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  | <script> | 
					
						
							| 
									
										
										
										
											2018-01-28 13:09:39 -08:00
										 |  |  |   import { store } from '../../_store/store' | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |   import Status from '../status/Status.html' | 
					
						
							| 
									
										
										
										
											2018-01-21 16:07:11 -08:00
										 |  |  |   import LoadingFooter from './LoadingFooter.html' | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |   import MoreHeaderVirtualWrapper from './MoreHeaderVirtualWrapper.html' | 
					
						
							| 
									
										
										
										
											2018-04-21 08:45:41 -07:00
										 |  |  |   import { | 
					
						
							|  |  |  |     importVirtualList, | 
					
						
							|  |  |  |     importPseudoVirtualList, | 
					
						
							|  |  |  |     importStatusVirtualListItem, | 
					
						
							|  |  |  |     importNotificationVirtualListItem | 
					
						
							|  |  |  |   } from '../../_utils/asyncModules' | 
					
						
							| 
									
										
										
										
											2018-01-27 16:35:44 -08:00
										 |  |  |   import { timelines } from '../../_static/timelines' | 
					
						
							| 
									
										
										
										
											2018-04-16 20:56:21 -07:00
										 |  |  |   import { | 
					
						
							|  |  |  |     getStatus as getStatusFromDatabase, | 
					
						
							|  |  |  |     getNotification as getNotificationFromDatabase | 
					
						
							|  |  |  |   } from '../../_database/timelines/getStatusOrNotification' | 
					
						
							| 
									
										
										
										
											2018-03-09 22:31:26 -08:00
										 |  |  |   import { | 
					
						
							|  |  |  |     fetchTimelineItemsOnScrollToBottom, | 
					
						
							|  |  |  |     setupTimeline, | 
					
						
							| 
									
										
										
										
											2018-03-10 10:54:16 -08:00
										 |  |  |     showMoreItemsForTimeline, | 
					
						
							|  |  |  |     showMoreItemsForThread, | 
					
						
							|  |  |  |     showMoreItemsForCurrentTimeline | 
					
						
							| 
									
										
										
										
											2018-03-09 22:31:26 -08:00
										 |  |  |   } from '../../_actions/timeline' | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |   import { focusWithCapture, blurWithCapture } from '../../_utils/events' | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |   import { scheduleIdleTask } from '../../_utils/scheduleIdleTask' | 
					
						
							| 
									
										
										
										
											2018-02-11 22:40:56 -08:00
										 |  |  |   import { mark, stop } from '../../_utils/marks' | 
					
						
							| 
									
										
										
										
											2018-04-05 17:57:36 -07:00
										 |  |  |   import isEqual from 'lodash-es/isEqual' | 
					
						
							| 
									
										
										
										
											2018-03-29 23:16:53 -07:00
										 |  |  |   import { doubleRAF } from '../../_utils/doubleRAF' | 
					
						
							| 
									
										
										
										
											2018-04-30 08:29:04 -07:00
										 |  |  |   import { observe } from 'svelte-extras' | 
					
						
							| 
									
										
										
										
											2018-01-18 20:25:34 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |   export default { | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |     oncreate () { | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |       console.log('timeline oncreate()') | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |       this.setupFocus() | 
					
						
							| 
									
										
										
										
											2018-01-27 17:34:08 -08:00
										 |  |  |       setupTimeline() | 
					
						
							| 
									
										
										
										
											2018-03-22 21:59:02 -07:00
										 |  |  |       this.restoreFocus() | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |       this.setupStreaming() | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |     ondestroy () { | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |       console.log('ondestroy') | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |       this.teardownFocus() | 
					
						
							| 
									
										
										
										
											2018-01-24 09:47:31 -08:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |     data: () => ({ | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |       LoadingFooter, | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |       MoreHeaderVirtualWrapper, | 
					
						
							| 
									
										
										
										
											2018-02-13 09:15:10 -08:00
										 |  |  |       Status, | 
					
						
							|  |  |  |       scrollTop: 0 | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |     }), | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |     computed: { | 
					
						
							| 
									
										
										
										
											2018-04-21 08:45:41 -07:00
										 |  |  |       // For threads, it's simpler to just render all items as a pseudo-virtual list | 
					
						
							|  |  |  |       // due to need to scroll to the right item and thus calculate all item heights up-front. | 
					
						
							|  |  |  |       // Here we lazy-load both the virtual list component itself as well as the component | 
					
						
							|  |  |  |       // it renders. | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |       componentsPromise: ({ timelineType }) => { | 
					
						
							| 
									
										
										
										
											2018-04-21 08:45:41 -07:00
										 |  |  |         return Promise.all([ | 
					
						
							|  |  |  |           timelineType === 'status' | 
					
						
							|  |  |  |             ? importPseudoVirtualList() | 
					
						
							|  |  |  |             : importVirtualList(), | 
					
						
							|  |  |  |           timelineType === 'notifications' | 
					
						
							|  |  |  |             ? importNotificationVirtualListItem() | 
					
						
							|  |  |  |             : importStatusVirtualListItem() | 
					
						
							|  |  |  |         ]).then(results => ({ | 
					
						
							|  |  |  |           listComponent: results[0], | 
					
						
							|  |  |  |           listItemComponent: results[1] | 
					
						
							|  |  |  |         })) | 
					
						
							| 
									
										
										
										
											2018-02-12 22:32:56 -08:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |       makeProps: ({ $currentInstance, timelineType, timelineValue }) => async (itemId) => { | 
					
						
							| 
									
										
										
										
											2018-03-20 20:28:53 -07:00
										 |  |  |         let res = { | 
					
						
							|  |  |  |           timelineType, | 
					
						
							|  |  |  |           timelineValue | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |         if (timelineType === 'notifications') { | 
					
						
							| 
									
										
										
										
											2018-04-16 20:56:21 -07:00
										 |  |  |           res.notification = await getNotificationFromDatabase($currentInstance, itemId) | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2018-04-16 20:56:21 -07:00
										 |  |  |           res.status = await getStatusFromDatabase($currentInstance, itemId) | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |         return res | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |       label: ({ timeline, $currentInstance, timelineType, timelineValue }) => { | 
					
						
							| 
									
										
										
										
											2018-01-21 20:02:32 -08:00
										 |  |  |         if (timelines[timeline]) { | 
					
						
							| 
									
										
										
										
											2018-01-28 15:44:33 -08:00
										 |  |  |           return `${timelines[timeline].label} timeline for ${$currentInstance}` | 
					
						
							| 
									
										
										
										
											2018-01-21 20:02:32 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-28 15:44:33 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         switch (timelineType) { | 
					
						
							|  |  |  |           case 'tag': | 
					
						
							|  |  |  |             return `#${timelineValue} timeline for ${$currentInstance}` | 
					
						
							|  |  |  |           case 'status': | 
					
						
							|  |  |  |             return 'Status context' | 
					
						
							|  |  |  |           case 'account': | 
					
						
							|  |  |  |             return `Account #${timelineValue} on ${$currentInstance}` | 
					
						
							| 
									
										
										
										
											2018-02-08 09:15:25 -08:00
										 |  |  |           case 'list': | 
					
						
							|  |  |  |             return `List #${timelineValue} on ${$currentInstance}` | 
					
						
							| 
									
										
										
										
											2018-04-10 22:08:14 -07:00
										 |  |  |           case 'notifications': | 
					
						
							|  |  |  |             return `Notifications for ${$currentInstance}` | 
					
						
							| 
									
										
										
										
											2018-01-28 15:44:33 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |       timelineType: ({ timeline }) => { | 
					
						
							| 
									
										
										
										
											2018-01-28 15:44:33 -08:00
										 |  |  |         return timeline.split('/')[0] | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |       timelineValue: ({ timeline }) => { | 
					
						
							| 
									
										
										
										
											2018-01-28 15:44:33 -08:00
										 |  |  |         return timeline.split('/').slice(-1)[0] | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       // Scroll to the first item if this is a "status in own thread" timeline. | 
					
						
							|  |  |  |       // Don't scroll to the first item because it obscures the "back" button. | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |       scrollToItem: ({ timelineType, timelineValue, $firstTimelineItemId }) => ( | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |         timelineType === 'status' && $firstTimelineItemId && | 
					
						
							|  |  |  |         timelineValue !== $firstTimelineItemId && timelineValue | 
					
						
							|  |  |  |       ), | 
					
						
							| 
									
										
										
										
											2018-05-01 17:05:36 -07:00
										 |  |  |       itemIdsToAdd: ({ $itemIdsToAdd }) => $itemIdsToAdd, | 
					
						
							|  |  |  |       headerProps: ({ itemIdsToAdd }) => { | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |         return { | 
					
						
							| 
									
										
										
										
											2018-02-25 10:50:04 -08:00
										 |  |  |           count: itemIdsToAdd ? itemIdsToAdd.length : 0, | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |           onClick: showMoreItemsForCurrentTimeline | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-10 14:19:10 -08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-01-10 20:45:02 -08:00
										 |  |  |     store: () => store, | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |     events: { | 
					
						
							|  |  |  |       focusWithCapture, | 
					
						
							|  |  |  |       blurWithCapture | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-01-15 12:23:28 -08:00
										 |  |  |     methods: { | 
					
						
							| 
									
										
										
										
											2018-04-30 08:29:04 -07:00
										 |  |  |       observe, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       initialize () { | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |         let { initializeStarted } = this.get() | 
					
						
							|  |  |  |         if (initializeStarted) { | 
					
						
							| 
									
										
										
										
											2018-01-24 19:26:08 -08:00
										 |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-11 16:10:39 -08:00
										 |  |  |         this.set({initializeStarted: true}) | 
					
						
							| 
									
										
										
										
											2018-03-29 23:16:53 -07:00
										 |  |  |         mark('initializeTimeline') | 
					
						
							|  |  |  |         doubleRAF(() => { | 
					
						
							|  |  |  |           console.log('timeline initialized') | 
					
						
							|  |  |  |           this.store.set({timelineInitialized: true}) | 
					
						
							|  |  |  |           stop('initializeTimeline') | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2018-01-24 19:26:08 -08:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       onScrollTopChanged (scrollTop) { | 
					
						
							| 
									
										
										
										
											2018-02-13 09:15:10 -08:00
										 |  |  |         this.set({scrollTop: scrollTop}) | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       onScrollToBottom () { | 
					
						
							| 
									
										
										
										
											2018-04-21 09:56:45 -07:00
										 |  |  |         let state = this.store.get() | 
					
						
							|  |  |  |         if (!state) { | 
					
						
							|  |  |  |           return // https://github.com/sveltejs/svelte/issues/1354 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         let { timelineType } = state | 
					
						
							|  |  |  |         let { timelineInitialized, runningUpdate } = this.store.get() | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |         if (!timelineInitialized || | 
					
						
							|  |  |  |             runningUpdate || | 
					
						
							|  |  |  |             timelineType === 'status') { // for status contexts, we've already fetched the whole thread | 
					
						
							| 
									
										
										
										
											2018-01-18 20:25:34 -08:00
										 |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |         let { currentInstance } = this.store.get() | 
					
						
							|  |  |  |         let { timeline } = this.get() | 
					
						
							| 
									
										
										
										
											2018-03-10 10:54:16 -08:00
										 |  |  |         fetchTimelineItemsOnScrollToBottom( | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |           currentInstance, | 
					
						
							|  |  |  |           timeline | 
					
						
							| 
									
										
										
										
											2018-03-10 10:54:16 -08:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       onScrollToTop () { | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |         let { shouldShowHeader } = this.store.get() | 
					
						
							|  |  |  |         if (shouldShowHeader) { | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |           this.store.setForCurrentTimeline({ | 
					
						
							|  |  |  |             showHeader: true, | 
					
						
							|  |  |  |             shouldShowHeader: false | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       setupStreaming () { | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |         let { currentInstance } = this.store.get() | 
					
						
							|  |  |  |         let { timeline } = this.get() | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |         let handleItemIdsToAdd = () => { | 
					
						
							| 
									
										
										
										
											2018-04-29 17:33:58 -07:00
										 |  |  |           let { itemIdsToAdd } = this.get() || {} // https://github.com/sveltejs/svelte/issues/1354 | 
					
						
							| 
									
										
										
										
											2018-02-25 11:20:40 -08:00
										 |  |  |           if (!itemIdsToAdd || !itemIdsToAdd.length) { | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-02-11 22:40:56 -08:00
										 |  |  |           mark('handleItemIdsToAdd') | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |           let { scrollTop } = this.get() | 
					
						
							|  |  |  |           let { | 
					
						
							|  |  |  |             shouldShowHeader, | 
					
						
							|  |  |  |             showHeader | 
					
						
							|  |  |  |           } = this.store.get() | 
					
						
							|  |  |  |           if (timeline.startsWith('status/')) { | 
					
						
							| 
									
										
										
										
											2018-03-09 22:31:26 -08:00
										 |  |  |             // this is a thread, just insert the statuses already | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |             showMoreItemsForThread(currentInstance, timeline) | 
					
						
							| 
									
										
										
										
											2018-03-09 22:31:26 -08:00
										 |  |  |           } else if (scrollTop === 0 && !shouldShowHeader && !showHeader) { | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |             // if the user is scrolled to the top and we're not showing the header, then | 
					
						
							|  |  |  |             // just insert the statuses. this is "chat room mode" | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |             showMoreItemsForTimeline(currentInstance, timeline) | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |           } else { | 
					
						
							|  |  |  |             // user hasn't scrolled to the top, show a header instead | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |             this.store.setForTimeline(currentInstance, timeline, {shouldShowHeader: true}) | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-02-11 22:40:56 -08:00
										 |  |  |           stop('handleItemIdsToAdd') | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-25 10:50:04 -08:00
										 |  |  |         this.observe('itemIdsToAdd', (newItemIdsToAdd, oldItemIdsToAdd) => { | 
					
						
							|  |  |  |           if (!newItemIdsToAdd || | 
					
						
							|  |  |  |               !newItemIdsToAdd.length || | 
					
						
							|  |  |  |               isEqual(newItemIdsToAdd, oldItemIdsToAdd)) { | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2018-02-20 21:29:59 -08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-02-25 10:50:04 -08:00
										 |  |  |           scheduleIdleTask(handleItemIdsToAdd) | 
					
						
							| 
									
										
										
										
											2018-02-11 19:15:21 -08:00
										 |  |  |         }) | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       setupFocus () { | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |         this.onPushState = this.onPushState.bind(this) | 
					
						
							| 
									
										
										
										
											2018-03-21 00:53:52 -07:00
										 |  |  |         this.store.setForCurrentTimeline({ | 
					
						
							| 
									
										
										
										
											2018-03-22 21:59:02 -07:00
										 |  |  |           ignoreBlurEvents: false | 
					
						
							| 
									
										
										
										
											2018-03-21 00:53:52 -07:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |         window.addEventListener('pushState', this.onPushState) | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       teardownFocus () { | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |         window.removeEventListener('pushState', this.onPushState) | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       onPushState () { | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |         this.store.setForCurrentTimeline({ ignoreBlurEvents: true }) | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       saveFocus (e) { | 
					
						
							| 
									
										
										
										
											2018-03-22 19:56:08 -07:00
										 |  |  |         try { | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |           let { currentInstance } = this.store.get() | 
					
						
							|  |  |  |           let { timeline } = this.get() | 
					
						
							| 
									
										
										
										
											2018-03-22 19:56:08 -07:00
										 |  |  |           let lastFocusedElementSelector | 
					
						
							|  |  |  |           let activeElement = e.target | 
					
						
							|  |  |  |           if (activeElement) { | 
					
						
							|  |  |  |             let focusKey = activeElement.getAttribute('focus-key') | 
					
						
							|  |  |  |             if (focusKey) { | 
					
						
							|  |  |  |               lastFocusedElementSelector = `[focus-key=${JSON.stringify(focusKey)}]` | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-03-22 19:56:08 -07:00
										 |  |  |           console.log('saving focus to ', lastFocusedElementSelector) | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |           this.store.setForTimeline(currentInstance, timeline, { | 
					
						
							| 
									
										
										
										
											2018-03-22 19:56:08 -07:00
										 |  |  |             lastFocusedElementSelector | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         } catch (err) { | 
					
						
							|  |  |  |           console.error('unable to save focus', err) | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       clearFocus () { | 
					
						
							| 
									
										
										
										
											2018-03-22 19:56:08 -07:00
										 |  |  |         try { | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |           let { ignoreBlurEvents } = this.store.get() | 
					
						
							|  |  |  |           if (ignoreBlurEvents) { | 
					
						
							| 
									
										
										
										
											2018-03-22 19:56:08 -07:00
										 |  |  |             return | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           console.log('clearing focus') | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |           let { currentInstance } = this.store.get() | 
					
						
							|  |  |  |           let { timeline } = this.get() | 
					
						
							|  |  |  |           this.store.setForTimeline(currentInstance, timeline, { | 
					
						
							| 
									
										
										
										
											2018-03-22 19:56:08 -07:00
										 |  |  |             lastFocusedElementSelector: null | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         } catch (err) { | 
					
						
							|  |  |  |           console.error('unable to clear focus', err) | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-22 21:59:02 -07:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       restoreFocus () { | 
					
						
							| 
									
										
										
										
											2018-04-19 09:37:05 -07:00
										 |  |  |         let { lastFocusedElementSelector } = this.store.get() | 
					
						
							| 
									
										
										
										
											2018-03-22 21:59:02 -07:00
										 |  |  |         if (!lastFocusedElementSelector) { | 
					
						
							|  |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         console.log('restoreFocus', lastFocusedElementSelector) | 
					
						
							|  |  |  |         requestAnimationFrame(() => { | 
					
						
							|  |  |  |           requestAnimationFrame(() => { | 
					
						
							|  |  |  |             let element = document.querySelector(lastFocusedElementSelector) | 
					
						
							|  |  |  |             if (element) { | 
					
						
							|  |  |  |               element.focus() | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-04-19 21:38:01 -07:00
										 |  |  |       onNoNeedToScroll () { | 
					
						
							| 
									
										
										
										
											2018-03-29 23:16:53 -07:00
										 |  |  |         // If the timeline doesn't need to scroll, then we can safely "preinitialize," | 
					
						
							|  |  |  |         // i.e. render anything above the fold of the timeline. This avoids the affect | 
					
						
							|  |  |  |         // where the scrollable content appears to jump around if we need to scroll it. | 
					
						
							|  |  |  |         console.log('timeline preinitialized') | 
					
						
							|  |  |  |         this.store.set({timelinePreinitialized: true}) | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-01-10 20:45:02 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | </script> |