forked from cybrespace/pinafore
implement RealmStore
This commit is contained in:
parent
b8a7c34228
commit
8afe67c471
|
@ -29,7 +29,7 @@
|
||||||
export default {
|
export default {
|
||||||
oncreate() {
|
oncreate() {
|
||||||
mark('PseudoVirtualList oncreate()')
|
mark('PseudoVirtualList oncreate()')
|
||||||
this.store.set({currentRealm: this.get('realm')})
|
this.store.setCurrentRealm(this.get('realm'))
|
||||||
|
|
||||||
// When re-rendering, assume all items are non-intersecting until told otherwise.
|
// When re-rendering, assume all items are non-intersecting until told otherwise.
|
||||||
// We already have the heights cached.
|
// We already have the heights cached.
|
||||||
|
|
|
@ -1,21 +1,14 @@
|
||||||
import { Store } from 'svelte/store.js'
|
import { RealmStore } from '../../_utils/RealmStore'
|
||||||
|
|
||||||
class PseudoVirtualListStore extends Store {
|
class PseudoVirtualListStore extends RealmStore {
|
||||||
setForRealm(obj) {
|
constructor(state) {
|
||||||
let realmName = this.get('currentRealm')
|
super(state, /* maxSize */ 10)
|
||||||
let realms = this.get('realms') || {}
|
|
||||||
realms[realmName] = Object.assign(realms[realmName] || {}, obj)
|
|
||||||
this.set({realms: realms})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const pseudoVirtualListStore = new PseudoVirtualListStore()
|
const pseudoVirtualListStore = new PseudoVirtualListStore()
|
||||||
|
|
||||||
pseudoVirtualListStore.compute('intersectionStates',
|
pseudoVirtualListStore.computeForRealm('intersectionStates', {})
|
||||||
['realms', 'currentRealm'],
|
|
||||||
(realms, currentRealm) => {
|
|
||||||
return (realms && realms[currentRealm] && realms[currentRealm].intersectionStates) || {}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (process.browser && process.env.NODE_NODE !== 'production') {
|
if (process.browser && process.env.NODE_NODE !== 'production') {
|
||||||
window.pseudoVirtualListStore = pseudoVirtualListStore
|
window.pseudoVirtualListStore = pseudoVirtualListStore
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
oncreate() {
|
oncreate() {
|
||||||
mark('onCreate VirtualListContainer')
|
mark('onCreate VirtualListContainer')
|
||||||
let node = this.refs.node
|
let node = this.refs.node
|
||||||
let realm = this.get('realm')
|
this.store.setCurrentRealm(this.get('realm'))
|
||||||
this.store.set({currentRealm: realm})
|
|
||||||
let scrollTop = this.store.get('scrollTop')
|
let scrollTop = this.store.get('scrollTop')
|
||||||
if (scrollTop > 0) {
|
if (scrollTop > 0) {
|
||||||
this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => {
|
this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { Store } from 'svelte/store.js'
|
|
||||||
import { mark, stop } from '../../_utils/marks'
|
import { mark, stop } from '../../_utils/marks'
|
||||||
|
import { RealmStore } from '../../_utils/RealmStore'
|
||||||
|
|
||||||
const VIEWPORT_RENDER_FACTOR = 4
|
const VIEWPORT_RENDER_FACTOR = 4
|
||||||
|
|
||||||
class VirtualListStore extends Store {
|
class VirtualListStore extends RealmStore {
|
||||||
constructor(state) {
|
constructor(state) {
|
||||||
super(state)
|
super(state, /* maxSize */ 10)
|
||||||
this._batches = {}
|
this._batches = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,41 +37,18 @@ class VirtualListStore extends Store {
|
||||||
stop('batchUpdate()')
|
stop('batchUpdate()')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setForRealm(obj) {
|
|
||||||
let realmName = this.get('currentRealm')
|
|
||||||
let realms = this.get('realms') || {}
|
|
||||||
realms[realmName] = Object.assign(realms[realmName] || {}, obj)
|
|
||||||
this.set({realms: realms})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const virtualListStore = new VirtualListStore({
|
const virtualListStore = new VirtualListStore({
|
||||||
realms: {},
|
|
||||||
currentRealm: null,
|
|
||||||
itemHeights: {},
|
itemHeights: {},
|
||||||
footerHeight: 0
|
footerHeight: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
virtualListStore.compute('items', ['currentRealm', 'realms'], (currentRealm, realms) => {
|
virtualListStore.computeForRealm('items', [])
|
||||||
return realms[currentRealm] && realms[currentRealm].items || []
|
virtualListStore.computeForRealm('showFooter', false)
|
||||||
})
|
virtualListStore.computeForRealm('scrollTop', 0)
|
||||||
|
virtualListStore.computeForRealm('scrollHeight', 0)
|
||||||
virtualListStore.compute('showFooter', ['currentRealm', 'realms'], (currentRealm, realms) => {
|
virtualListStore.computeForRealm('offsetHeight', 0)
|
||||||
return realms[currentRealm] && realms[currentRealm].showFooter
|
|
||||||
})
|
|
||||||
|
|
||||||
virtualListStore.compute('scrollTop', ['currentRealm', 'realms'], (currentRealm, realms) => {
|
|
||||||
return realms[currentRealm] && realms[currentRealm].scrollTop || 0
|
|
||||||
})
|
|
||||||
|
|
||||||
virtualListStore.compute('scrollHeight', ['currentRealm', 'realms'], (currentRealm, realms) => {
|
|
||||||
return realms[currentRealm] && realms[currentRealm].scrollHeight || 0
|
|
||||||
})
|
|
||||||
|
|
||||||
virtualListStore.compute('offsetHeight', ['currentRealm', 'realms'], (currentRealm, realms) => {
|
|
||||||
return realms[currentRealm] && realms[currentRealm].offsetHeight || 0
|
|
||||||
})
|
|
||||||
|
|
||||||
virtualListStore.compute('visibleItems',
|
virtualListStore.compute('visibleItems',
|
||||||
['items', 'scrollTop', 'itemHeights', 'offsetHeight'],
|
['items', 'scrollTop', 'itemHeights', 'offsetHeight'],
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// A store where you can divide data into "realms" that are backed with an LRU cache.
|
||||||
|
// Each realm has self-contained data that you can set with setForRealm() and compute
|
||||||
|
// with computeForRealm(). The maxSize determines how many realms to keep in the LRU cache.
|
||||||
|
import { Store } from 'svelte/store.js'
|
||||||
|
import QuickLRU from 'quick-lru'
|
||||||
|
|
||||||
|
export class RealmStore extends Store {
|
||||||
|
constructor(init, maxSize) {
|
||||||
|
super(init)
|
||||||
|
this.set({realms: new QuickLRU({maxSize: maxSize})})
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentRealm(realm) {
|
||||||
|
this.set({currentRealm: realm})
|
||||||
|
}
|
||||||
|
|
||||||
|
setForRealm(obj) {
|
||||||
|
let realmName = this.get('currentRealm')
|
||||||
|
let realms = this.get('realms')
|
||||||
|
realms.set(realmName, Object.assign(realms.get(realmName) || {}, obj))
|
||||||
|
this.set({realms: realms})
|
||||||
|
}
|
||||||
|
|
||||||
|
computeForRealm(key, defaultValue) {
|
||||||
|
this.compute(key,
|
||||||
|
['realms', 'currentRealm'],
|
||||||
|
(realms, currentRealm) => {
|
||||||
|
let realmData = realms.get(currentRealm)
|
||||||
|
return (realmData && realmData[key]) || defaultValue
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue