refactor VirtualList to be more self-contained

This commit is contained in:
Nolan Lawson 2018-02-12 22:06:05 -08:00
parent 24e8bdbd86
commit acc1ce396d
12 changed files with 65 additions and 77 deletions

View file

@ -1,19 +1,11 @@
<:Window bind:online />
<Nav :page />
{{#if virtual}}
<VirtualListContainer realm="{{$currentInstance + '/' + virtualRealm}}">
<main>
<slot></slot>
</main>
</VirtualListContainer>
{{else}}
<div class="container">
<main>
<slot></slot>
</main>
</div>
{{/if}}
<div class="container">
<main>
<slot></slot>
</main>
</div>
<script>
import Nav from './Nav.html';
import VirtualListContainer from './virtualList/VirtualListContainer.html'

View file

@ -43,7 +43,7 @@
this.store.setForRealm({intersectionStates: intersectionStates})
this.set({intersectionObserver: new IntersectionObserver(this.onIntersection.bind(this), {
root: document.getElementsByClassName('container')[0], // TODO: fix this
root: document.querySelector('.container'),
rootMargin: '300% 0px'
})})
this.observe('allItemsHaveHeight', allItemsHaveHeight => {
@ -80,8 +80,7 @@
}
this.set({scrolledToPosition: true})
console.log('scrollToPosition', rect.top)
// TODO: there should be some cleaner way to grab the container element
let container = document.getElementsByClassName('container')[0]
let container = document.querySelector('.container')
if (!container) {
return
}

View file

@ -1,19 +1,21 @@
<div class="virtual-list {{shown ? '' : 'hidden'}}" style="height: {{$height}}px;">
<VirtualListHeader component="{{headerComponent}}" virtualProps="{{headerProps}}" shown="{{$showHeader}}"/>
{{#if $visibleItems}}
{{#each $visibleItems as visibleItem @key}}
<VirtualListLazyItem :component
offset="{{visibleItem.offset}}"
makeProps="{{makeProps}}"
key="{{visibleItem.key}}"
index="{{visibleItem.index}}"
/>
{{/each}}
{{/if}}
{{#if $showFooter}}
<VirtualListFooter component="{{footerComponent}}"/>
{{/if}}
</div>
<VirtualListContainer :realm >
<div class="virtual-list {{shown ? '' : 'hidden'}}" style="height: {{$height}}px;">
<VirtualListHeader component="{{headerComponent}}" virtualProps="{{headerProps}}" shown="{{$showHeader}}"/>
{{#if $visibleItems}}
{{#each $visibleItems as visibleItem @key}}
<VirtualListLazyItem :component
offset="{{visibleItem.offset}}"
makeProps="{{makeProps}}"
key="{{visibleItem.key}}"
index="{{visibleItem.index}}"
/>
{{/each}}
{{/if}}
{{#if $showFooter}}
<VirtualListFooter component="{{footerComponent}}" />
{{/if}}
</div>
</VirtualListContainer>
<style>
.virtual-list {
position: relative;
@ -21,6 +23,7 @@
}
</style>
<script>
import VirtualListContainer from './VirtualListContainer.html'
import VirtualListLazyItem from './VirtualListLazyItem'
import VirtualListFooter from './VirtualListFooter.html'
import VirtualListHeader from './VirtualListHeader.html'
@ -86,6 +89,7 @@
}),
store: () => virtualListStore,
components: {
VirtualListContainer,
VirtualListLazyItem,
VirtualListFooter,
VirtualListHeader

View file

@ -1,12 +1,6 @@
<div class="container"
on:scroll="onScroll(event)"
on:fullscreen="onFullscreenChange()"
ref:node>
<slot></slot>
</div>
<slot></slot>
<script>
import { virtualListStore } from './virtualListStore'
import throttle from 'lodash/throttle'
import { isFullscreen, attachFullscreenListener, detachFullscreenListener } from '../../_utils/fullscreen'
import { mark, stop } from '../../_utils/marks'
@ -16,7 +10,9 @@
export default {
oncreate() {
mark('onCreate VirtualListContainer')
let node = this.refs.node
let node = document.querySelector('.container')
this.setupScroll(node)
this.setupFullscreen()
this.store.setCurrentRealm(this.get('realm'))
let scrollTop = this.store.get('scrollTop')
if (scrollTop > 0) {
@ -40,46 +36,47 @@
}
stop('onCreate VirtualListContainer')
},
ondestroy() {
this.teardownScroll()
this.teardownFullscreen()
},
store: () => virtualListStore,
events: {
scroll(node, callback) {
const onScroll = throttle(event => {
mark('onScroll')
methods: {
setupScroll(node) {
if (!node) {
return
}
this.scrollListener = throttle(event => {
if (this.get('fullscreen')) {
return
}
callback(event)
stop('onScroll')
this.onScroll(event)
}, SCROLL_EVENT_DELAY, {
leading: true,
trailing: true
})
node.addEventListener('scroll', onScroll)
return {
teardown() {
node.removeEventListener('scroll', onScroll)
}
node.addEventListener('scroll', this.scrollListener)
},
teardownScroll() {
let node = document.querySelector('.container')
if (node) {
node.removeEventListener('scroll', this.scrollListener)
}
},
fullscreen(node, callback) {
const onFullscreen = (() => {
callback()
})
attachFullscreenListener(onFullscreen)
return {
teardown() {
detachFullscreenListener(onFullscreen)
}
}
}
},
methods: {
setupFullscreen() {
this.onFullscreenChange = this.onFullscreenChange.bind(this)
attachFullscreenListener(this.onFullscreenChange)
},
teardownFullscreen() {
detachFullscreenListener(this.onFullscreenChange)
},
onScroll(event) {
mark('onScroll')
this.store.setForRealm({
scrollTop: event.target.scrollTop,
scrollHeight: event.target.scrollHeight
})
stop('onScroll')
},
onFullscreenChange() {
mark('onFullscreenChange')

View file

@ -2,9 +2,7 @@
<title>Pinafore {{profileName}}</title>
</:Head>
<Layout page='tags'
virtual="true"
virtualRealm='account/{{params.accountId}}' >
<Layout page='tags'>
{{#if $isUserLoggedIn}}
<DynamicPageBanner title="{{profileName}}" />
{{#if $currentAccountProfile}}

View file

@ -2,7 +2,7 @@
<title>Pinafore Favorites</title>
</:Head>
<Layout page='favorites' virtual="true" virtualRealm="favorites">
<Layout page='favorites'>
{{#if $isUserLoggedIn}}
{{#if $pinnedPage !== '/favorites'}}
<DynamicPageBanner title="Favorites" icon="#fa-star"/>

View file

@ -2,7 +2,7 @@
<title>Pinafore Federated</title>
</:Head>
<Layout page='federated' virtual="true" virtualRealm="federated">
<Layout page='federated'>
{{#if $isUserLoggedIn}}
{{#if $pinnedPage !== '/federated'}}
<DynamicPageBanner title="Federated Timeline" icon="#fa-globe"/>

View file

@ -2,7 +2,7 @@
<title>Pinafore Home</title>
</:Head>
<Layout page='home' virtual="true" virtualRealm="home">
<Layout page='home'>
{{#if $isUserLoggedIn}}
<LazyTimeline timeline='home' />
{{else}}

View file

@ -2,7 +2,7 @@
<title>Pinafore {{listTitle}}</title>
</:Head>
<Layout page='lists' virtual="true" virtualRealm="list/{{params.listId}}">
<Layout page='lists'>
{{#if $isUserLoggedIn}}
{{#if $pinnedPage !== `/lists/${params.listId}`}}
<DynamicPageBanner title="{{listTitle}}" icon="#fa-bars"/>

View file

@ -2,7 +2,7 @@
<title>Pinafore Local</title>
</:Head>
<Layout page='local' virtual="true" virtualRealm="local">
<Layout page='local'>
{{#if $isUserLoggedIn}}
{{#if $pinnedPage !== '/local'}}
<DynamicPageBanner title="Local Timeline" icon="#fa-users"/>

View file

@ -2,7 +2,7 @@
<title>Pinafore Notifications</title>
</:Head>
<Layout page='notifications' virtual="true" virtualRealm="notifications">
<Layout page='notifications'>
{{#if $isUserLoggedIn}}
<LazyTimeline timeline='notifications' />
{{else}}

View file

@ -2,9 +2,7 @@
<title>Pinafore #{{params.tagName}}</title>
</:Head>
<Layout page='tags'
virtual="true"
virtualRealm='tag/{{params.tagName}}' >
<Layout page='tags'>
{{#if $isUserLoggedIn}}
<DynamicPageBanner title="{{'#' + params.tagName}}"/>
<LazyTimeline timeline='tag/{{params.tagName}}' />