about summary refs log tree commit diff
path: root/src/state/models/votes-view.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/state/models/votes-view.ts')
-rw-r--r--src/state/models/votes-view.ts62
1 files changed, 32 insertions, 30 deletions
diff --git a/src/state/models/votes-view.ts b/src/state/models/votes-view.ts
index df939226f..ad8698d21 100644
--- a/src/state/models/votes-view.ts
+++ b/src/state/models/votes-view.ts
@@ -2,6 +2,9 @@ import {makeAutoObservable, runInAction} from 'mobx'
 import {AtUri} from '../../third-party/uri'
 import {AppBskyFeedGetVotes as GetVotes} from '@atproto/api'
 import {RootStoreModel} from './root-store'
+import {cleanError} from 'lib/strings/errors'
+import {bundleAsync} from 'lib/async/bundle'
+import * as apilib from 'lib/api/index'
 
 const PAGE_SIZE = 30
 
@@ -17,7 +20,6 @@ export class VotesViewModel {
   params: GetVotes.QueryParams
   hasMore = true
   loadMoreCursor?: string
-  private _loadMorePromise: Promise<void> | undefined
 
   // data
   uri: string = ''
@@ -54,17 +56,31 @@ export class VotesViewModel {
     return this.loadMore(true)
   }
 
-  async loadMore(isRefreshing = false) {
-    if (this._loadMorePromise) {
-      return this._loadMorePromise
+  loadMore = bundleAsync(async (replace: boolean = false) => {
+    if (!replace && !this.hasMore) {
+      return
     }
-    if (!this.resolvedUri) {
-      await this._resolveUri()
+    this._xLoading(replace)
+    try {
+      if (!this.resolvedUri) {
+        await this._resolveUri()
+      }
+      const params = Object.assign({}, this.params, {
+        uri: this.resolvedUri,
+        limit: PAGE_SIZE,
+        before: replace ? undefined : this.loadMoreCursor,
+      })
+      const res = await this.rootStore.api.app.bsky.feed.getVotes(params)
+      if (replace) {
+        this._replaceAll(res)
+      } else {
+        this._appendAll(res)
+      }
+      this._xIdle()
+    } catch (e: any) {
+      this._xIdle(e)
     }
-    this._loadMorePromise = this._loadMore(isRefreshing)
-    await this._loadMorePromise
-    this._loadMorePromise = undefined
-  }
+  })
 
   // state transitions
   // =
@@ -79,20 +95,20 @@ export class VotesViewModel {
     this.isLoading = false
     this.isRefreshing = false
     this.hasLoaded = true
-    this.error = err ? err.toString() : ''
+    this.error = cleanError(err)
     if (err) {
       this.rootStore.log.error('Failed to fetch votes', err)
     }
   }
 
-  // loader functions
+  // helper functions
   // =
 
   private async _resolveUri() {
     const urip = new AtUri(this.params.uri)
     if (!urip.host.startsWith('did:')) {
       try {
-        urip.host = await this.rootStore.resolveName(urip.host)
+        urip.host = await apilib.resolveName(this.rootStore, urip.host)
       } catch (e: any) {
         this.error = e.toString()
       }
@@ -102,23 +118,9 @@ export class VotesViewModel {
     })
   }
 
-  private async _loadMore(isRefreshing = false) {
-    this._xLoading(isRefreshing)
-    try {
-      const params = Object.assign({}, this.params, {
-        uri: this.resolvedUri,
-        limit: PAGE_SIZE,
-        before: this.loadMoreCursor,
-      })
-      if (this.isRefreshing) {
-        this.votes = []
-      }
-      const res = await this.rootStore.api.app.bsky.feed.getVotes(params)
-      this._appendAll(res)
-      this._xIdle()
-    } catch (e: any) {
-      this._xIdle(e)
-    }
+  private _replaceAll(res: GetVotes.Response) {
+    this.votes = []
+    this._appendAll(res)
   }
 
   private _appendAll(res: GetVotes.Response) {