65 lines
		
	
	
		
			No EOL
		
	
	
		
			1.8 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			No EOL
		
	
	
		
			1.8 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!-- TODO: setting height is hacky, just make this element the scroller -->
 | |
| <div class="virtual-list" style="height: {{$height}}px;">
 | |
|   {{#each $visibleItems as item @key}}
 | |
|   <VirtualListItem :component
 | |
|                    offset="{{item.offset}}"
 | |
|                    props="{{item.props}}"
 | |
|                    key="{{item.key}}"
 | |
|                    index="{{item.index}}"
 | |
|   />
 | |
|   {{/each}}
 | |
| </div>
 | |
| <style>
 | |
|   .virtual-list {
 | |
|     position: relative;
 | |
|   }
 | |
| </style>
 | |
| <script>
 | |
|   import VirtualListItem from './VirtualListItem'
 | |
|   import { virtualListStore } from '../_utils/virtualListStore'
 | |
|   import throttle from 'lodash/throttle'
 | |
|   import { mark, stop } from '../_utils/marks'
 | |
| 
 | |
|   const DISTANCE_FROM_BOTTOM_TO_FIRE = 400
 | |
|   const SCROLL_TO_BOTTOM_DELAY = 1000
 | |
| 
 | |
|   export default {
 | |
|     oncreate () {
 | |
|       this.observe('items', (items) => {
 | |
|         mark('set items')
 | |
|         this.store.set({
 | |
|           items: items
 | |
|         })
 | |
|         stop('set items')
 | |
|         this.fireScrollToBottom = throttle(() => {
 | |
|           this.fire('scrollToBottom')
 | |
|         }, SCROLL_TO_BOTTOM_DELAY)
 | |
|       })
 | |
| 
 | |
|       let observedOnce = false
 | |
| 
 | |
|       this.observe('distanceFromBottom', (distanceFromBottom) => {
 | |
|         if (!observedOnce) {
 | |
|           observedOnce = true // TODO: the first time is always 0... need better way to handle this
 | |
|           return
 | |
|         }
 | |
|         if (distanceFromBottom >= 0 &&
 | |
|             distanceFromBottom <= DISTANCE_FROM_BOTTOM_TO_FIRE) {
 | |
|           this.fireScrollToBottom()
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     data: () => ({
 | |
|       component: null
 | |
|     }),
 | |
|     store: () => virtualListStore,
 | |
|     components: {
 | |
|       VirtualListItem
 | |
|     },
 | |
|     computed: {
 | |
|       distanceFromBottom: ($scrollHeight, $scrollTop, $offsetHeight) => {
 | |
|         return $scrollHeight - $scrollTop - $offsetHeight
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| </script> |