forked from cybrespace/pinafore
refactor VirtualList to be more self-contained
This commit is contained in:
parent
24e8bdbd86
commit
acc1ce396d
|
@ -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}}
|
||||
<script>
|
||||
import Nav from './Nav.html';
|
||||
import VirtualListContainer from './virtualList/VirtualListContainer.html'
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<VirtualListContainer :realm >
|
||||
<div class="virtual-list {{shown ? '' : 'hidden'}}" style="height: {{$height}}px;">
|
||||
<VirtualListHeader component="{{headerComponent}}" virtualProps="{{headerProps}}" shown="{{$showHeader}}"/>
|
||||
{{#if $visibleItems}}
|
||||
|
@ -14,6 +15,7 @@
|
|||
<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
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
<div class="container"
|
||||
on:scroll="onScroll(event)"
|
||||
on:fullscreen="onFullscreenChange()"
|
||||
ref:node>
|
||||
<slot></slot>
|
||||
</div>
|
||||
<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)
|
||||
}
|
||||
}
|
||||
}
|
||||
setupFullscreen() {
|
||||
this.onFullscreenChange = this.onFullscreenChange.bind(this)
|
||||
attachFullscreenListener(this.onFullscreenChange)
|
||||
},
|
||||
teardownFullscreen() {
|
||||
detachFullscreenListener(this.onFullscreenChange)
|
||||
},
|
||||
methods: {
|
||||
onScroll(event) {
|
||||
mark('onScroll')
|
||||
this.store.setForRealm({
|
||||
scrollTop: event.target.scrollTop,
|
||||
scrollHeight: event.target.scrollHeight
|
||||
})
|
||||
stop('onScroll')
|
||||
},
|
||||
onFullscreenChange() {
|
||||
mark('onFullscreenChange')
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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}}' />
|
||||
|
|
Loading…
Reference in New Issue