| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  | <div class="timeline" | 
					
						
							|  |  |  |      role="feed" | 
					
						
							|  |  |  |      aria-label="{{label}}" | 
					
						
							|  |  |  |      on:focusWithCapture="saveFocus(event)" | 
					
						
							|  |  |  |      on:blurWithCapture="clearFocus(event)" | 
					
						
							|  |  |  | > | 
					
						
							| 
									
										
										
										
											2018-01-30 22:21:31 -08:00
										 |  |  |   {{#if !$initialized}} | 
					
						
							| 
									
										
										
										
											2018-02-06 20:54:49 -08:00
										 |  |  |     <LoadingPage /> | 
					
						
							| 
									
										
										
										
											2018-01-30 22:21:31 -08:00
										 |  |  |   {{/if}} | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |   {{#if timelineType === 'notifications'}} | 
					
						
							|  |  |  |     <VirtualList component="{{NotificationVirtualListItem}}" | 
					
						
							|  |  |  |                  :makeProps | 
					
						
							|  |  |  |                  items="{{$timelineItemIds}}" | 
					
						
							|  |  |  |                  on:scrollToBottom="onScrollToBottom()" | 
					
						
							|  |  |  |                  shown="{{$initialized}}" | 
					
						
							|  |  |  |                  footerComponent="{{LoadingFooter}}" | 
					
						
							|  |  |  |                  showFooter="{{$initialized && $runningUpdate}}" | 
					
						
							|  |  |  |                  realm="{{$currentInstance + '/' + timeline}}" | 
					
						
							|  |  |  |                  on:initializedVisibleItems="initialize()" | 
					
						
							|  |  |  |   /> | 
					
						
							|  |  |  |   {{elseif virtual}} | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |     <VirtualList component="{{StatusVirtualListItem}}" | 
					
						
							|  |  |  |                  :makeProps | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |                  items="{{$timelineItemIds}}" | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |                  on:scrollToBottom="onScrollToBottom()" | 
					
						
							|  |  |  |                  shown="{{$initialized}}" | 
					
						
							|  |  |  |                  footerComponent="{{LoadingFooter}}" | 
					
						
							|  |  |  |                  showFooter="{{$initialized && $runningUpdate}}" | 
					
						
							|  |  |  |                  realm="{{$currentInstance + '/' + timeline}}" | 
					
						
							|  |  |  |                  on:initializedVisibleItems="initialize()" | 
					
						
							|  |  |  |     /> | 
					
						
							|  |  |  |   {{else}} | 
					
						
							|  |  |  |     <!-- if this is a status thread, it's easier to just render the
 | 
					
						
							|  |  |  |          whole thing rather than use a virtual list --> | 
					
						
							|  |  |  |     <PseudoVirtualList component="{{StatusVirtualListItem}}" | 
					
						
							|  |  |  |                        :makeProps | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |                        items="{{$timelineItemIds}}" | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |                        shown="{{$initialized}}" | 
					
						
							|  |  |  |                        on:initializedVisibleItems="initialize()" | 
					
						
							| 
									
										
										
										
											2018-02-10 14:19:10 -08:00
										 |  |  |                        scrollToItem="{{scrollToItem}}" | 
					
						
							| 
									
										
										
										
											2018-01-30 18:26:13 -08:00
										 |  |  |                        realm="{{$currentInstance + '/' + timeline}}" | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |     /> | 
					
						
							|  |  |  |   {{/if}} | 
					
						
							| 
									
										
										
										
											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-30 22:21:31 -08:00
										 |  |  |     position: relative; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  | </style> | 
					
						
							| 
									
										
										
										
											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 StatusVirtualListItem from './StatusVirtualListItem.html' | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |   import NotificationVirtualListItem from './NotificationVirtualListItem.html' | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |   import Status from '../status/Status.html' | 
					
						
							|  |  |  |   import PseudoVirtualList from '../pseudoVirtualList/PseudoVirtualList.html' | 
					
						
							| 
									
										
										
										
											2018-01-21 16:07:11 -08:00
										 |  |  |   import LoadingFooter from './LoadingFooter.html' | 
					
						
							| 
									
										
										
										
											2018-01-27 16:35:44 -08:00
										 |  |  |   import VirtualList from '../virtualList/VirtualList.html' | 
					
						
							|  |  |  |   import { timelines } from '../../_static/timelines' | 
					
						
							| 
									
										
										
										
											2018-02-08 08:22:14 -08:00
										 |  |  |   import { database } from '../../_database/database' | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |   import { initializeTimeline, fetchTimelineItemsOnScrollToBottom, setupTimeline } from '../../_actions/timeline' | 
					
						
							| 
									
										
										
										
											2018-02-06 20:54:49 -08:00
										 |  |  |   import LoadingPage from '../LoadingPage.html' | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |   import { focusWithCapture, blurWithCapture } from '../../_utils/events' | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |   import { addTimelineItemIds } from '../../_actions/timeline' | 
					
						
							| 
									
										
										
										
											2018-01-18 20:25:34 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |   export default { | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08: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-02-10 13:57:04 -08:00
										 |  |  |       if (this.store.get('initialized')) { | 
					
						
							|  |  |  |         this.restoreFocus() | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |       let instanceName = this.store.get('currentInstance') | 
					
						
							|  |  |  |       let timelineName = this.get('timeline') | 
					
						
							|  |  |  |       this.observe('itemIdsToAdd', itemIdsToAdd => { | 
					
						
							|  |  |  |         console.log('itemIdsToAdd', itemIdsToAdd) | 
					
						
							| 
									
										
										
										
											2018-02-11 16:10:39 -08:00
										 |  |  |         if (itemIdsToAdd && itemIdsToAdd.length) { | 
					
						
							|  |  |  |           addTimelineItemIds(instanceName, timelineName, itemIdsToAdd) | 
					
						
							|  |  |  |           this.store.setForTimeline(instanceName, timelineName, {itemIdsToAdd: []}) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |     }, | 
					
						
							|  |  |  |     ondestroy() { | 
					
						
							|  |  |  |       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
										 |  |  |       StatusVirtualListItem, | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |       NotificationVirtualListItem, | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |       LoadingFooter, | 
					
						
							|  |  |  |       Status | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |     }), | 
					
						
							| 
									
										
										
										
											2018-01-17 18:35:27 -08:00
										 |  |  |     computed: { | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |       makeProps: ($currentInstance, timelineType, timelineValue) => async (itemId) => { | 
					
						
							|  |  |  |         let res = { timelineType, timelineValue } | 
					
						
							|  |  |  |         if (timelineType === 'notifications') { | 
					
						
							|  |  |  |           res.notification = await database.getNotification($currentInstance, itemId) | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           res.status = await database.getStatus($currentInstance, itemId) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return res | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-01-28 15:44:33 -08: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-01-28 15:44:33 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       timelineType: (timeline) => { | 
					
						
							|  |  |  |         return timeline.split('/')[0] | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       timelineValue: (timeline) => { | 
					
						
							|  |  |  |         return timeline.split('/').slice(-1)[0] | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-02-10 14:19:10 -08: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 | 
					
						
							|  |  |  |       virtual: (timelineType) => timelineType !=='status', | 
					
						
							|  |  |  |       scrollToItem: (timelineType, timelineValue, $firstTimelineItemId) => { | 
					
						
							|  |  |  |         // 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. | 
					
						
							|  |  |  |         return timelineType === 'status' | 
					
						
							|  |  |  |           && $firstTimelineItemId | 
					
						
							|  |  |  |           && timelineValue !== $firstTimelineItemId | 
					
						
							|  |  |  |           && timelineValue | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |       }, | 
					
						
							|  |  |  |       itemIdsToAdd: (timeline, $currentInstance, $timelines) => { | 
					
						
							|  |  |  |         return ($timelines && | 
					
						
							|  |  |  |           $timelines[$currentInstance] && | 
					
						
							|  |  |  |           $timelines[$currentInstance][timeline] && | 
					
						
							|  |  |  |           $timelines[$currentInstance][timeline].itemIdsToAdd) || [] | 
					
						
							| 
									
										
										
										
											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, | 
					
						
							|  |  |  |     components: { | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |       VirtualList, | 
					
						
							| 
									
										
										
										
											2018-01-30 22:21:31 -08:00
										 |  |  |       PseudoVirtualList, | 
					
						
							| 
									
										
										
										
											2018-02-06 20:54:49 -08:00
										 |  |  |       LoadingPage | 
					
						
							| 
									
										
										
										
											2018-01-15 12:23:28 -08:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |     events: { | 
					
						
							|  |  |  |       focusWithCapture, | 
					
						
							|  |  |  |       blurWithCapture | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-01-15 12:23:28 -08:00
										 |  |  |     methods: { | 
					
						
							| 
									
										
										
										
											2018-01-24 19:26:08 -08:00
										 |  |  |       initialize() { | 
					
						
							| 
									
										
										
										
											2018-02-11 16:10:39 -08:00
										 |  |  |         if (this.get('initializeStarted')) { | 
					
						
							| 
									
										
										
										
											2018-01-24 19:26:08 -08:00
										 |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-11 16:10:39 -08:00
										 |  |  |         this.set({initializeStarted: true}) | 
					
						
							| 
									
										
										
										
											2018-01-29 19:22:28 -08:00
										 |  |  |         console.log('timeline initialize()') | 
					
						
							| 
									
										
										
										
											2018-01-27 17:34:08 -08:00
										 |  |  |         initializeTimeline() | 
					
						
							| 
									
										
										
										
											2018-01-24 19:26:08 -08:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-01-27 17:34:42 -08:00
										 |  |  |       onScrollToBottom() { | 
					
						
							| 
									
										
										
										
											2018-01-28 15:44:33 -08:00
										 |  |  |         if (!this.store.get('initialized') || | 
					
						
							|  |  |  |             this.store.get('runningUpdate') || | 
					
						
							|  |  |  |             this.get('timelineType') === 'status') { // for status contexts, we've already fetched the whole thread | 
					
						
							| 
									
										
										
										
											2018-01-18 20:25:34 -08:00
										 |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-03 18:06:02 -08:00
										 |  |  |         fetchTimelineItemsOnScrollToBottom() | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-02-11 13:46:57 -08:00
										 |  |  |       setupFocus() { | 
					
						
							|  |  |  |         this.onPushState = this.onPushState.bind(this) | 
					
						
							|  |  |  |         this.store.setForCurrentTimeline({ignoreBlurEvents: false}) | 
					
						
							|  |  |  |         window.addEventListener('pushState', this.onPushState) | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       teardownFocus() { | 
					
						
							|  |  |  |         window.removeEventListener('pushState', this.onPushState) | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       onPushState() { | 
					
						
							|  |  |  |         this.store.setForCurrentTimeline({ ignoreBlurEvents: true }) | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-02-10 13:57:04 -08:00
										 |  |  |       saveFocus(e) { | 
					
						
							|  |  |  |         let instanceName = this.store.get('currentInstance') | 
					
						
							|  |  |  |         let timelineName = this.get('timeline') | 
					
						
							|  |  |  |         let lastFocusedElementSelector | 
					
						
							|  |  |  |         let activeElement = e.target | 
					
						
							|  |  |  |         if (activeElement) { | 
					
						
							|  |  |  |           let focusKey = activeElement.getAttribute('focus-key') | 
					
						
							|  |  |  |           if (focusKey) { | 
					
						
							|  |  |  |             lastFocusedElementSelector = `[focus-key=${focusKey}]` | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         console.log('saving focus to ', lastFocusedElementSelector) | 
					
						
							|  |  |  |         this.store.setForTimeline(instanceName, timelineName, { | 
					
						
							|  |  |  |           lastFocusedElementSelector | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       clearFocus() { | 
					
						
							|  |  |  |         if (this.store.get('ignoreBlurEvents')) { | 
					
						
							|  |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         console.log('clearing focus') | 
					
						
							|  |  |  |         let instanceName = this.store.get('currentInstance') | 
					
						
							|  |  |  |         let timelineName = this.get('timeline') | 
					
						
							|  |  |  |         this.store.setForTimeline(instanceName, timelineName, { | 
					
						
							|  |  |  |           lastFocusedElementSelector: null | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       restoreFocus() { | 
					
						
							|  |  |  |         let lastFocusedElementSelector = this.store.get('lastFocusedElementSelector') | 
					
						
							|  |  |  |         console.log('lastFocused', lastFocusedElementSelector) | 
					
						
							|  |  |  |         if (lastFocusedElementSelector) { | 
					
						
							|  |  |  |           requestAnimationFrame(() => { | 
					
						
							|  |  |  |             requestAnimationFrame(() => { | 
					
						
							|  |  |  |               let element = document.querySelector(lastFocusedElementSelector) | 
					
						
							|  |  |  |               console.log('el', element) | 
					
						
							|  |  |  |               if (element) { | 
					
						
							|  |  |  |                 element.focus() | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2018-01-10 20:45:02 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-08 18:14:21 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | </script> |