about summary refs log tree commit diff
path: root/src/lib/api/feed-manip.ts
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-11-29 16:58:14 -0800
committerGitHub <noreply@github.com>2023-11-29 18:58:14 -0600
commit630637874db9bf188214657b576cbf2965a77278 (patch)
treee5e00955cb38db3f5c642da943529fde8e855d33 /src/lib/api/feed-manip.ts
parenta59d235e8b319f6c33e0a0221c99c915128826a6 (diff)
downloadvoidsky-630637874db9bf188214657b576cbf2965a77278.tar.zst
Fix state lifecycle management with post-feed query, solving the duplicate key issue (#2034)
* Assign keys to feed slices via a counter, to enable duplicate items in the feed if needed

* Move post-feed query state into the query's page params to consistently bind their lifecycles
Diffstat (limited to 'src/lib/api/feed-manip.ts')
-rw-r--r--src/lib/api/feed-manip.ts35
1 files changed, 19 insertions, 16 deletions
diff --git a/src/lib/api/feed-manip.ts b/src/lib/api/feed-manip.ts
index 912302d0a..1123c4e23 100644
--- a/src/lib/api/feed-manip.ts
+++ b/src/lib/api/feed-manip.ts
@@ -16,14 +16,7 @@ export type FeedTunerFn = (
 export class FeedViewPostsSlice {
   isFlattenedReply = false
 
-  constructor(public items: FeedViewPost[] = []) {}
-
-  get _reactKey() {
-    const rootItem = this.isFlattenedReply ? this.items[1] : this.items[0]
-    return `slice-${rootItem.post.uri}-${
-      rootItem.reason?.indexedAt || rootItem.post.indexedAt
-    }`
-  }
+  constructor(public items: FeedViewPost[], public _reactKey: string) {}
 
   get uri() {
     if (this.isFlattenedReply) {
@@ -118,28 +111,34 @@ export class FeedViewPostsSlice {
 }
 
 export class NoopFeedTuner {
-  reset() {}
+  private keyCounter = 0
+
+  reset() {
+    this.keyCounter = 0
+  }
   tune(
     feed: FeedViewPost[],
-    _tunerFns: FeedTunerFn[] = [],
     _opts?: {dryRun: boolean; maintainOrder: boolean},
   ): FeedViewPostsSlice[] {
-    return feed.map(item => new FeedViewPostsSlice([item]))
+    return feed.map(
+      item => new FeedViewPostsSlice([item], `slice-${this.keyCounter++}`),
+    )
   }
 }
 
 export class FeedTuner {
+  private keyCounter = 0
   seenUris: Set<string> = new Set()
 
-  constructor() {}
+  constructor(public tunerFns: FeedTunerFn[]) {}
 
   reset() {
+    this.keyCounter = 0
     this.seenUris.clear()
   }
 
   tune(
     feed: FeedViewPost[],
-    tunerFns: FeedTunerFn[] = [],
     {dryRun, maintainOrder}: {dryRun: boolean; maintainOrder: boolean} = {
       dryRun: false,
       maintainOrder: false,
@@ -148,7 +147,9 @@ export class FeedTuner {
     let slices: FeedViewPostsSlice[] = []
 
     if (maintainOrder) {
-      slices = feed.map(item => new FeedViewPostsSlice([item]))
+      slices = feed.map(
+        item => new FeedViewPostsSlice([item], `slice-${this.keyCounter++}`),
+      )
     } else {
       // arrange the posts into thread slices
       for (let i = feed.length - 1; i >= 0; i--) {
@@ -164,12 +165,14 @@ export class FeedTuner {
             continue
           }
         }
-        slices.unshift(new FeedViewPostsSlice([item]))
+        slices.unshift(
+          new FeedViewPostsSlice([item], `slice-${this.keyCounter++}`),
+        )
       }
     }
 
     // run the custom tuners
-    for (const tunerFn of tunerFns) {
+    for (const tunerFn of this.tunerFns) {
       slices = tunerFn(this, slices.slice())
     }