about summary refs log tree commit diff
path: root/src/state/models/feeds/posts.ts
diff options
context:
space:
mode:
authorAnsh <anshnanda10@gmail.com>2023-04-19 13:58:24 -0700
committerGitHub <noreply@github.com>2023-04-19 15:58:24 -0500
commit1472bd4f173a483e5f1a91514244fecaec23808f (patch)
treefc33a3e90d4024939ef022a2c468f7b58df5fc37 /src/state/models/feeds/posts.ts
parentbe83d2933cfce1035573bc14108a87451cf48c2d (diff)
downloadvoidsky-1472bd4f173a483e5f1a91514244fecaec23808f.tar.zst
#420: add updateDataOptimistically utility to disallow like counter out of sync (#446)
* add isLikedPressed flag to disallow like counter out of sync

* create revertible helper for updateDataOptimistically

* test implementation

* Update updateDataOptimistically() and apply to reposts

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
Diffstat (limited to 'src/state/models/feeds/posts.ts')
-rw-r--r--src/state/models/feeds/posts.ts74
1 files changed, 43 insertions, 31 deletions
diff --git a/src/state/models/feeds/posts.ts b/src/state/models/feeds/posts.ts
index c82453946..e3328c71a 100644
--- a/src/state/models/feeds/posts.ts
+++ b/src/state/models/feeds/posts.ts
@@ -19,6 +19,7 @@ import {
   mergePosts,
 } from 'lib/api/build-suggested-posts'
 import {FeedTuner, FeedViewPostsSlice} from 'lib/api/feed-manip'
+import {updateDataOptimistically} from 'lib/async/revertible'
 
 type FeedViewPost = AppBskyFeedDefs.FeedViewPost
 type ReasonRepost = AppBskyFeedDefs.ReasonRepost
@@ -91,45 +92,56 @@ export class PostsFeedItemModel {
   }
 
   async toggleLike() {
-    if (this.post.viewer?.like) {
-      await this.rootStore.agent.deleteLike(this.post.viewer.like)
-      runInAction(() => {
-        this.post.likeCount = this.post.likeCount || 0
-        this.post.viewer = this.post.viewer || {}
-        this.post.likeCount--
-        this.post.viewer.like = undefined
-      })
+    this.post.viewer = this.post.viewer || {}
+    if (this.post.viewer.like) {
+      const url = this.post.viewer.like
+      await updateDataOptimistically(
+        this.post,
+        () => {
+          this.post.likeCount = (this.post.likeCount || 0) - 1
+          this.post.viewer!.like = undefined
+        },
+        () => this.rootStore.agent.deleteLike(url),
+      )
     } else {
-      const res = await this.rootStore.agent.like(this.post.uri, this.post.cid)
-      runInAction(() => {
-        this.post.likeCount = this.post.likeCount || 0
-        this.post.viewer = this.post.viewer || {}
-        this.post.likeCount++
-        this.post.viewer.like = res.uri
-      })
+      await updateDataOptimistically(
+        this.post,
+        () => {
+          this.post.likeCount = (this.post.likeCount || 0) + 1
+          this.post.viewer!.like = 'pending'
+        },
+        () => this.rootStore.agent.like(this.post.uri, this.post.cid),
+        res => {
+          this.post.viewer!.like = res.uri
+        },
+      )
     }
   }
 
   async toggleRepost() {
+    this.post.viewer = this.post.viewer || {}
     if (this.post.viewer?.repost) {
-      await this.rootStore.agent.deleteRepost(this.post.viewer.repost)
-      runInAction(() => {
-        this.post.repostCount = this.post.repostCount || 0
-        this.post.viewer = this.post.viewer || {}
-        this.post.repostCount--
-        this.post.viewer.repost = undefined
-      })
+      const url = this.post.viewer.repost
+      await updateDataOptimistically(
+        this.post,
+        () => {
+          this.post.repostCount = (this.post.repostCount || 0) - 1
+          this.post.viewer!.repost = undefined
+        },
+        () => this.rootStore.agent.deleteRepost(url),
+      )
     } else {
-      const res = await this.rootStore.agent.repost(
-        this.post.uri,
-        this.post.cid,
+      await updateDataOptimistically(
+        this.post,
+        () => {
+          this.post.repostCount = (this.post.repostCount || 0) + 1
+          this.post.viewer!.repost = 'pending'
+        },
+        () => this.rootStore.agent.repost(this.post.uri, this.post.cid),
+        res => {
+          this.post.viewer!.repost = res.uri
+        },
       )
-      runInAction(() => {
-        this.post.repostCount = this.post.repostCount || 0
-        this.post.viewer = this.post.viewer || {}
-        this.post.repostCount++
-        this.post.viewer.repost = res.uri
-      })
     }
   }