about summary refs log tree commit diff
path: root/src/state/queries/actor-autocomplete.ts
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-11-12 12:45:25 -0800
committerGitHub <noreply@github.com>2023-11-12 12:45:25 -0800
commitd9e0a927c1c98ebd6aa3885ab517af27e7de2522 (patch)
treecee196297391e497f1aa3b650d66633f3a86ca34 /src/state/queries/actor-autocomplete.ts
parent05b728fffcdb17708fdb52685725faf7fdc545bc (diff)
downloadvoidsky-d9e0a927c1c98ebd6aa3885ab517af27e7de2522.tar.zst
Refactor lists to use new queries (#1875)
* Refactor lists queries to react-query

* Delete old lists-list model

* Implement list, list-members, and list-memberships react-queries

* Update CreateOrEditList modal

* First pass at my-follows and actor-autocomplete queries

* Update ListAddUserModal to use new queries, change to ListAddRemoveUsersModal

* Update UserAddRemoveLists modal

* Remove old TODO

* Fix indent, autocomplete query

* Add a todo

---------

Co-authored-by: Eric Bailey <git@esb.lol>
Diffstat (limited to 'src/state/queries/actor-autocomplete.ts')
-rw-r--r--src/state/queries/actor-autocomplete.ts66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/state/queries/actor-autocomplete.ts b/src/state/queries/actor-autocomplete.ts
new file mode 100644
index 000000000..18abb6314
--- /dev/null
+++ b/src/state/queries/actor-autocomplete.ts
@@ -0,0 +1,66 @@
+import {AppBskyActorDefs} from '@atproto/api'
+import {useQuery} from '@tanstack/react-query'
+import {useSession} from '../session'
+import {useMyFollowsQuery} from './my-follows'
+
+export const RQKEY = (prefix: string) => ['actor-autocomplete', prefix]
+
+export function useActorAutocompleteQuery(prefix: string) {
+  const {agent} = useSession()
+  const {data: follows, isFetching} = useMyFollowsQuery()
+  return useQuery<AppBskyActorDefs.ProfileViewBasic[]>({
+    queryKey: RQKEY(prefix || ''),
+    async queryFn() {
+      const res = await agent.searchActorsTypeahead({
+        term: prefix,
+        limit: 8,
+      })
+      return computeSuggestions(prefix, follows, res.data.actors)
+    },
+    enabled: !isFetching && !!prefix,
+  })
+}
+
+function computeSuggestions(
+  prefix: string,
+  follows: AppBskyActorDefs.ProfileViewBasic[] = [],
+  searched: AppBskyActorDefs.ProfileViewBasic[] = [],
+) {
+  if (prefix) {
+    const items: AppBskyActorDefs.ProfileViewBasic[] = []
+    for (const item of follows) {
+      if (prefixMatch(prefix, item)) {
+        items.push(item)
+      }
+      if (items.length >= 8) {
+        break
+      }
+    }
+    for (const item of searched) {
+      if (!items.find(item2 => item2.handle === item.handle)) {
+        items.push({
+          did: item.did,
+          handle: item.handle,
+          displayName: item.displayName,
+          avatar: item.avatar,
+        })
+      }
+    }
+    return items
+  } else {
+    return follows
+  }
+}
+
+function prefixMatch(
+  prefix: string,
+  info: AppBskyActorDefs.ProfileViewBasic,
+): boolean {
+  if (info.handle.includes(prefix)) {
+    return true
+  }
+  if (info.displayName?.toLocaleLowerCase().includes(prefix)) {
+    return true
+  }
+  return false
+}