diff --git a/js/components/rant-feed.js b/js/components/rant-feed.js index f3c8a2c..3d92399 100644 --- a/js/components/rant-feed.js +++ b/js/components/rant-feed.js @@ -23,6 +23,8 @@ class RantFeed extends BaseComponent { this.blockChangeHandler = () => this.render(); this.stateKey = this.buildStateKey(); this.pendingRestore = null; + this.isRestoring = false; + this.scrollHandler = this.debounce(() => this.onScroll(), 200); this.render(); this.bindEvents(); @@ -43,6 +45,11 @@ class RantFeed extends BaseComponent { this.stateKey = key; } + onScroll() { + if (this.isRestoring || this.isLoading) return; + this.saveScrollState(); + } + getTopVisibleRant() { const cards = this.$$('rant-card'); if (!cards || cards.length === 0) return null; @@ -88,13 +95,17 @@ class RantFeed extends BaseComponent { return false; } + this.isRestoring = true; this.pendingRestore = state; await this.loadWithLimit(state.skip || this.limit); return true; } scrollToAnchor() { - if (!this.pendingRestore) return; + if (!this.pendingRestore) { + this.isRestoring = false; + return; + } const { anchorRantId, offsetFromTop } = this.pendingRestore; this.pendingRestore = null; @@ -106,7 +117,9 @@ class RantFeed extends BaseComponent { const scrollY = window.scrollY + rect.top - offsetFromTop; window.scrollTo(0, Math.max(0, scrollY)); } - this.clearScrollState(); + setTimeout(() => { + this.isRestoring = false; + }, 100); }); } @@ -301,6 +314,7 @@ class RantFeed extends BaseComponent { this.on(this, 'click', this.handleClick); this.setupInfiniteScroll(); window.addEventListener('rantii:block-change', this.blockChangeHandler); + window.addEventListener('scroll', this.scrollHandler); } handleClick(e) { @@ -345,7 +359,7 @@ class RantFeed extends BaseComponent { } onDisconnected() { - this.saveScrollState(); + window.removeEventListener('scroll', this.scrollHandler); if (this.intersectionObserver) { this.intersectionObserver.disconnect(); }