From ef51842e6a8b9feaf8c631f8d30851c6038f15d6 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 22 Mar 2018 17:33:42 -0700 Subject: [PATCH] calculate listOffset to avoid profile offset issue --- .../_components/virtualList/VirtualList.html | 18 +++++++++++++++++- .../virtualList/virtualListStore.js | 14 ++++++++------ routes/_pages/accounts/[accountId].html | 1 - routes/_utils/getRectFromEntry.js | 16 ++++++++++------ 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/routes/_components/virtualList/VirtualList.html b/routes/_components/virtualList/VirtualList.html index 1061b761..3257a6a3 100644 --- a/routes/_components/virtualList/VirtualList.html +++ b/routes/_components/virtualList/VirtualList.html @@ -1,5 +1,7 @@ -
+
{{#if $visibleItems}} {{#each $visibleItems as visibleItem @key}} @@ -85,6 +87,7 @@ if (scrollTop === 0) { this.fireScrollToTop() } + this.calculateListOffset() }) }, data: () => ({ @@ -104,6 +107,19 @@ scrollTop: ($scrollTop) => $scrollTop, // TODO: bug in svelte store, shouldn't need to do this allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight, + }, + methods: { + calculateListOffset() { + // TODO: better way to get the offset top? + let node = this.refs.node + if (!node) { + return + } + mark('calculateListOffset') + let listOffset = node.offsetParent.offsetTop + this.store.setForRealm({listOffset}) + stop('calculateListOffset') + } } } \ No newline at end of file diff --git a/routes/_components/virtualList/virtualListStore.js b/routes/_components/virtualList/virtualListStore.js index d5b5f6db..e76cb79f 100644 --- a/routes/_components/virtualList/virtualListStore.js +++ b/routes/_components/virtualList/virtualListStore.js @@ -2,7 +2,7 @@ import { mark, stop } from '../../_utils/marks' import { RealmStore } from '../../_utils/RealmStore' import { reselect } from '../../_utils/reselect' -const RENDER_BUFFER_FACTOR = 5 +const RENDER_BUFFER_FACTOR = 1.5 class VirtualListStore extends RealmStore { constructor (state) { @@ -20,16 +20,18 @@ virtualListStore.computeForRealm('headerHeight', 0) virtualListStore.computeForRealm('scrollTop', 0) virtualListStore.computeForRealm('scrollHeight', 0) virtualListStore.computeForRealm('offsetHeight', 0) +virtualListStore.computeForRealm('listOffset', 0) virtualListStore.computeForRealm('itemHeights', {}) virtualListStore.compute('rawVisibleItems', - ['items', 'scrollTop', 'itemHeights', 'offsetHeight', 'showHeader', 'headerHeight'], - (items, scrollTop, itemHeights, offsetHeight, showHeader, headerHeight) => { + ['items', 'scrollTop', 'itemHeights', 'offsetHeight', 'showHeader', 'headerHeight', 'listOffset'], + (items, scrollTop, itemHeights, offsetHeight, showHeader, headerHeight, listOffset) => { window.rawVisibleItemsComputed = (window.rawVisibleItemsComputed || 0) + 1 mark('compute visibleItems') if (!items) { return null } + let effectiveScrollTop = scrollTop - listOffset let renderBuffer = RENDER_BUFFER_FACTOR * offsetHeight let visibleItems = [] let totalOffset = showHeader ? headerHeight : 0 @@ -40,13 +42,13 @@ virtualListStore.compute('rawVisibleItems', let height = itemHeights[key] || 0 let currentOffset = totalOffset totalOffset += height - let isAboveViewport = (currentOffset < scrollTop) + let isAboveViewport = (currentOffset < effectiveScrollTop) if (isAboveViewport) { - if ((scrollTop - height - renderBuffer) > currentOffset) { + if ((effectiveScrollTop - height - renderBuffer) > currentOffset) { continue // above the area we want to render } } else { - if (currentOffset > (scrollTop + offsetHeight + renderBuffer)) { + if (currentOffset > (effectiveScrollTop + offsetHeight + renderBuffer)) { break // below the area we want to render } } diff --git a/routes/_pages/accounts/[accountId].html b/routes/_pages/accounts/[accountId].html index c11c481b..879a681b 100644 --- a/routes/_pages/accounts/[accountId].html +++ b/routes/_pages/accounts/[accountId].html @@ -30,7 +30,6 @@ export default { oncreate() { let accountId = this.get('params').accountId - let instanceName = this.store.get('currentInstance') updateProfileAndRelationship(accountId) }, store: () => store, diff --git a/routes/_utils/getRectFromEntry.js b/routes/_utils/getRectFromEntry.js index 8a0837a1..d45006da 100644 --- a/routes/_utils/getRectFromEntry.js +++ b/routes/_utils/getRectFromEntry.js @@ -3,16 +3,20 @@ let hasBoundingRectBug +function rectsAreEqual (rectA, rectB) { + return rectA.height === rectB.height && + rectA.top === rectB.top && + rectA.width === rectB.width && + rectA.bottom === rectB.bottom && + rectA.left === rectB.left && + rectA.right === rectB.right +} + export function getRectFromEntry (entry) { if (typeof hasBoundingRectBug !== 'boolean') { const boundingRect = entry.target.getBoundingClientRect() const observerRect = entry.boundingClientRect - hasBoundingRectBug = boundingRect.height !== observerRect.height || - boundingRect.top !== observerRect.top || - boundingRect.width !== observerRect.width || - boundingRect.bottom !== observerRect.bottom || - boundingRect.left !== observerRect.left || - boundingRect.right !== observerRect.right + hasBoundingRectBug = !rectsAreEqual(boundingRect, observerRect) } return hasBoundingRectBug ? entry.target.getBoundingClientRect() : entry.boundingClientRect }