114 lines
		
	
	
		
			No EOL
		
	
	
		
			3.7 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			No EOL
		
	
	
		
			3.7 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <slot></slot>
 | ||
| <script>
 | ||
|   import { virtualListStore } from './virtualListStore'
 | ||
|   import throttle from 'lodash-es/throttle'
 | ||
|   import { isFullscreen, attachFullscreenListener, detachFullscreenListener } from '../../_utils/fullscreen'
 | ||
|   import { mark, stop } from '../../_utils/marks'
 | ||
|   import { doubleRAF } from '../../_utils/doubleRAF'
 | ||
|   import { observe } from 'svelte-extras'
 | ||
| 
 | ||
|   const SCROLL_EVENT_DELAY = 300
 | ||
| 
 | ||
|   export default {
 | ||
|     oncreate () {
 | ||
|       mark('onCreate VirtualListContainer')
 | ||
|       let {
 | ||
|         realm,
 | ||
|         containerQuery
 | ||
|       } = this.get()
 | ||
|       this.store.setCurrentRealm(realm)
 | ||
|       let node = document.querySelector(containerQuery)
 | ||
|       this.setupScroll(node)
 | ||
|       this.setupFullscreen()
 | ||
|       let { scrollTop } = this.store.get()
 | ||
|       if (scrollTop > 0) {
 | ||
|         this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => {
 | ||
|           console.log('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight)
 | ||
|           let { initializedScrollTop } = this.get()
 | ||
|           if (!initializedScrollTop && allVisibleItemsHaveHeight && node) {
 | ||
|             this.set({ 'initializedScrollTop': true })
 | ||
|             mark('set scrollTop')
 | ||
|             console.log('forcing scroll top to ', scrollTop)
 | ||
|             node.scrollTop = scrollTop
 | ||
|             stop('set scrollTop')
 | ||
|             doubleRAF(() => {
 | ||
|               console.log('initialized VirtualList')
 | ||
|               this.fire('initialized')
 | ||
|             })
 | ||
|           }
 | ||
|         })
 | ||
|       } else {
 | ||
|         this.fire('noNeedToScroll')
 | ||
|         this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => {
 | ||
|           if (allVisibleItemsHaveHeight) {
 | ||
|             console.log('initialized VirtualList')
 | ||
|             this.fire('initialized')
 | ||
|           }
 | ||
|         })
 | ||
|         this.store.setForRealm({
 | ||
|           scrollHeight: node.scrollHeight,
 | ||
|           offsetHeight: node.offsetHeight
 | ||
|         })
 | ||
|       }
 | ||
|       stop('onCreate VirtualListContainer')
 | ||
|     },
 | ||
|     ondestroy () {
 | ||
|       this.teardownScroll()
 | ||
|       this.teardownFullscreen()
 | ||
|       this.store.setCurrentRealm(null)
 | ||
|     },
 | ||
|     store: () => virtualListStore,
 | ||
|     methods: {
 | ||
|       observe,
 | ||
|       setupScroll (node) {
 | ||
|         if (!node) {
 | ||
|           return
 | ||
|         }
 | ||
|         this.scrollListener = throttle(event => {
 | ||
|           let { fullscreen } = this.get()
 | ||
|           if (fullscreen) {
 | ||
|             return
 | ||
|           }
 | ||
|           this.onScroll(event)
 | ||
|         }, SCROLL_EVENT_DELAY, {
 | ||
|           leading: true,
 | ||
|           trailing: true
 | ||
|         })
 | ||
|         node.addEventListener('scroll', this.scrollListener)
 | ||
|       },
 | ||
|       teardownScroll () {
 | ||
|         let { containerQuery } = this.get()
 | ||
|         let node = document.querySelector(containerQuery)
 | ||
|         if (node) {
 | ||
|           node.removeEventListener('scroll', this.scrollListener)
 | ||
|         }
 | ||
|       },
 | ||
|       setupFullscreen () {
 | ||
|         this.onFullscreenChange = this.onFullscreenChange.bind(this)
 | ||
|         attachFullscreenListener(this.onFullscreenChange)
 | ||
|       },
 | ||
|       teardownFullscreen () {
 | ||
|         detachFullscreenListener(this.onFullscreenChange)
 | ||
|       },
 | ||
|       onScroll (event) {
 | ||
|         let { scrollTop, scrollHeight } = event.target
 | ||
| 
 | ||
|         doubleRAF(() => {
 | ||
|           mark('onScroll -> setForRealm()')
 | ||
|           this.store.setForRealm({ scrollTop, scrollHeight })
 | ||
|           stop('onScroll -> setForRealm()')
 | ||
|         })
 | ||
|       },
 | ||
|       onFullscreenChange () {
 | ||
|         mark('onFullscreenChange')
 | ||
|         console.log('is fullscreen? ', isFullscreen())
 | ||
|         this.set({ fullscreen: isFullscreen() })
 | ||
|         stop('onFullscreenChange')
 | ||
|       }
 | ||
|     },
 | ||
|     computed: {
 | ||
|       // TODO: bug in svelte/store – the observer in oncreate() never get removed without this hack
 | ||
|       allVisibleItemsHaveHeight: ({ $allVisibleItemsHaveHeight }) => $allVisibleItemsHaveHeight
 | ||
|     }
 | ||
|   }
 | ||
| </script> |