about summary refs log tree commit diff
path: root/src/state
diff options
context:
space:
mode:
Diffstat (limited to 'src/state')
-rw-r--r--src/state/models/lists/blocked-accounts.ts107
-rw-r--r--src/state/models/lists/muted-accounts.ts107
-rw-r--r--src/state/queries/my-blocked-accounts.ts28
-rw-r--r--src/state/queries/my-muted-accounts.ts28
-rw-r--r--src/state/queries/profile.ts8
5 files changed, 64 insertions, 214 deletions
diff --git a/src/state/models/lists/blocked-accounts.ts b/src/state/models/lists/blocked-accounts.ts
deleted file mode 100644
index 5c3dbe7ce..000000000
--- a/src/state/models/lists/blocked-accounts.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import {makeAutoObservable} from 'mobx'
-import {
-  AppBskyGraphGetBlocks as GetBlocks,
-  AppBskyActorDefs as ActorDefs,
-} from '@atproto/api'
-import {RootStoreModel} from '../root-store'
-import {cleanError} from 'lib/strings/errors'
-import {bundleAsync} from 'lib/async/bundle'
-import {logger} from '#/logger'
-
-const PAGE_SIZE = 30
-
-export class BlockedAccountsModel {
-  // state
-  isLoading = false
-  isRefreshing = false
-  hasLoaded = false
-  error = ''
-  hasMore = true
-  loadMoreCursor?: string
-
-  // data
-  blocks: ActorDefs.ProfileView[] = []
-
-  constructor(public rootStore: RootStoreModel) {
-    makeAutoObservable(
-      this,
-      {
-        rootStore: false,
-      },
-      {autoBind: true},
-    )
-  }
-
-  get hasContent() {
-    return this.blocks.length > 0
-  }
-
-  get hasError() {
-    return this.error !== ''
-  }
-
-  get isEmpty() {
-    return this.hasLoaded && !this.hasContent
-  }
-
-  // public api
-  // =
-
-  async refresh() {
-    return this.loadMore(true)
-  }
-
-  loadMore = bundleAsync(async (replace: boolean = false) => {
-    if (!replace && !this.hasMore) {
-      return
-    }
-    this._xLoading(replace)
-    try {
-      const res = await this.rootStore.agent.app.bsky.graph.getBlocks({
-        limit: PAGE_SIZE,
-        cursor: replace ? undefined : this.loadMoreCursor,
-      })
-      if (replace) {
-        this._replaceAll(res)
-      } else {
-        this._appendAll(res)
-      }
-      this._xIdle()
-    } catch (e: any) {
-      this._xIdle(e)
-    }
-  })
-
-  // state transitions
-  // =
-
-  _xLoading(isRefreshing = false) {
-    this.isLoading = true
-    this.isRefreshing = isRefreshing
-    this.error = ''
-  }
-
-  _xIdle(err?: any) {
-    this.isLoading = false
-    this.isRefreshing = false
-    this.hasLoaded = true
-    this.error = cleanError(err)
-    if (err) {
-      logger.error('Failed to fetch user followers', {error: err})
-    }
-  }
-
-  // helper functions
-  // =
-
-  _replaceAll(res: GetBlocks.Response) {
-    this.blocks = []
-    this._appendAll(res)
-  }
-
-  _appendAll(res: GetBlocks.Response) {
-    this.loadMoreCursor = res.data.cursor
-    this.hasMore = !!this.loadMoreCursor
-    this.blocks = this.blocks.concat(res.data.blocks)
-  }
-}
diff --git a/src/state/models/lists/muted-accounts.ts b/src/state/models/lists/muted-accounts.ts
deleted file mode 100644
index 19ade0d9c..000000000
--- a/src/state/models/lists/muted-accounts.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import {makeAutoObservable} from 'mobx'
-import {
-  AppBskyGraphGetMutes as GetMutes,
-  AppBskyActorDefs as ActorDefs,
-} from '@atproto/api'
-import {RootStoreModel} from '../root-store'
-import {cleanError} from 'lib/strings/errors'
-import {bundleAsync} from 'lib/async/bundle'
-import {logger} from '#/logger'
-
-const PAGE_SIZE = 30
-
-export class MutedAccountsModel {
-  // state
-  isLoading = false
-  isRefreshing = false
-  hasLoaded = false
-  error = ''
-  hasMore = true
-  loadMoreCursor?: string
-
-  // data
-  mutes: ActorDefs.ProfileView[] = []
-
-  constructor(public rootStore: RootStoreModel) {
-    makeAutoObservable(
-      this,
-      {
-        rootStore: false,
-      },
-      {autoBind: true},
-    )
-  }
-
-  get hasContent() {
-    return this.mutes.length > 0
-  }
-
-  get hasError() {
-    return this.error !== ''
-  }
-
-  get isEmpty() {
-    return this.hasLoaded && !this.hasContent
-  }
-
-  // public api
-  // =
-
-  async refresh() {
-    return this.loadMore(true)
-  }
-
-  loadMore = bundleAsync(async (replace: boolean = false) => {
-    if (!replace && !this.hasMore) {
-      return
-    }
-    this._xLoading(replace)
-    try {
-      const res = await this.rootStore.agent.app.bsky.graph.getMutes({
-        limit: PAGE_SIZE,
-        cursor: replace ? undefined : this.loadMoreCursor,
-      })
-      if (replace) {
-        this._replaceAll(res)
-      } else {
-        this._appendAll(res)
-      }
-      this._xIdle()
-    } catch (e: any) {
-      this._xIdle(e)
-    }
-  })
-
-  // state transitions
-  // =
-
-  _xLoading(isRefreshing = false) {
-    this.isLoading = true
-    this.isRefreshing = isRefreshing
-    this.error = ''
-  }
-
-  _xIdle(err?: any) {
-    this.isLoading = false
-    this.isRefreshing = false
-    this.hasLoaded = true
-    this.error = cleanError(err)
-    if (err) {
-      logger.error('Failed to fetch user followers', {error: err})
-    }
-  }
-
-  // helper functions
-  // =
-
-  _replaceAll(res: GetMutes.Response) {
-    this.mutes = []
-    this._appendAll(res)
-  }
-
-  _appendAll(res: GetMutes.Response) {
-    this.loadMoreCursor = res.data.cursor
-    this.hasMore = !!this.loadMoreCursor
-    this.mutes = this.mutes.concat(res.data.mutes)
-  }
-}
diff --git a/src/state/queries/my-blocked-accounts.ts b/src/state/queries/my-blocked-accounts.ts
new file mode 100644
index 000000000..448f7dd67
--- /dev/null
+++ b/src/state/queries/my-blocked-accounts.ts
@@ -0,0 +1,28 @@
+import {AppBskyGraphGetBlocks} from '@atproto/api'
+import {useInfiniteQuery, InfiniteData, QueryKey} from '@tanstack/react-query'
+import {useSession} from '../session'
+
+export const RQKEY = () => ['my-blocked-accounts']
+type RQPageParam = string | undefined
+
+export function useMyBlockedAccountsQuery() {
+  const {agent} = useSession()
+  return useInfiniteQuery<
+    AppBskyGraphGetBlocks.OutputSchema,
+    Error,
+    InfiniteData<AppBskyGraphGetBlocks.OutputSchema>,
+    QueryKey,
+    RQPageParam
+  >({
+    queryKey: RQKEY(),
+    async queryFn({pageParam}: {pageParam: RQPageParam}) {
+      const res = await agent.app.bsky.graph.getBlocks({
+        limit: 30,
+        cursor: pageParam,
+      })
+      return res.data
+    },
+    initialPageParam: undefined,
+    getNextPageParam: lastPage => lastPage.cursor,
+  })
+}
diff --git a/src/state/queries/my-muted-accounts.ts b/src/state/queries/my-muted-accounts.ts
new file mode 100644
index 000000000..109874673
--- /dev/null
+++ b/src/state/queries/my-muted-accounts.ts
@@ -0,0 +1,28 @@
+import {AppBskyGraphGetMutes} from '@atproto/api'
+import {useInfiniteQuery, InfiniteData, QueryKey} from '@tanstack/react-query'
+import {useSession} from '../session'
+
+export const RQKEY = () => ['my-muted-accounts']
+type RQPageParam = string | undefined
+
+export function useMyMutedAccountsQuery() {
+  const {agent} = useSession()
+  return useInfiniteQuery<
+    AppBskyGraphGetMutes.OutputSchema,
+    Error,
+    InfiniteData<AppBskyGraphGetMutes.OutputSchema>,
+    QueryKey,
+    RQPageParam
+  >({
+    queryKey: RQKEY(),
+    async queryFn({pageParam}: {pageParam: RQPageParam}) {
+      const res = await agent.app.bsky.graph.getMutes({
+        limit: 30,
+        cursor: pageParam,
+      })
+      return res.data
+    },
+    initialPageParam: undefined,
+    getNextPageParam: lastPage => lastPage.cursor,
+  })
+}
diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts
index 63367b261..de2b1d65c 100644
--- a/src/state/queries/profile.ts
+++ b/src/state/queries/profile.ts
@@ -11,6 +11,8 @@ import {useSession} from '../session'
 import {updateProfileShadow} from '../cache/profile-shadow'
 import {uploadBlob} from '#/lib/api'
 import {until} from '#/lib/async/until'
+import {RQKEY as RQKEY_MY_MUTED} from './my-muted-accounts'
+import {RQKEY as RQKEY_MY_BLOCKED} from './my-blocked-accounts'
 
 export const RQKEY = (did: string) => ['profile', did]
 
@@ -147,6 +149,7 @@ export function useProfileUnfollowMutation() {
 
 export function useProfileMuteMutation() {
   const {agent} = useSession()
+  const queryClient = useQueryClient()
   return useMutation<void, Error, {did: string}>({
     mutationFn: async ({did}) => {
       await agent.mute(did)
@@ -157,6 +160,9 @@ export function useProfileMuteMutation() {
         muted: true,
       })
     },
+    onSuccess() {
+      queryClient.invalidateQueries({queryKey: RQKEY_MY_MUTED()})
+    },
     onError(error, variables) {
       // revert the optimistic update
       updateProfileShadow(variables.did, {
@@ -189,6 +195,7 @@ export function useProfileUnmuteMutation() {
 
 export function useProfileBlockMutation() {
   const {agent, currentAccount} = useSession()
+  const queryClient = useQueryClient()
   return useMutation<{uri: string; cid: string}, Error, {did: string}>({
     mutationFn: async ({did}) => {
       if (!currentAccount) {
@@ -210,6 +217,7 @@ export function useProfileBlockMutation() {
       updateProfileShadow(variables.did, {
         blockingUri: data.uri,
       })
+      queryClient.invalidateQueries({queryKey: RQKEY_MY_BLOCKED()})
     },
     onError(error, variables) {
       // revert the optimistic update