about summary refs log tree commit diff
path: root/src/state/models
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-03-21 17:58:50 -0500
committerGitHub <noreply@github.com>2023-03-21 17:58:50 -0500
commita7e3ce25854d6186b77e68c155a9a8bcdbd896ec (patch)
tree55c1a86575876c50824be7175a047c3e409ff7e6 /src/state/models
parent48e18662f69530d5c201d08014a039126c88e7dd (diff)
downloadvoidsky-a7e3ce25854d6186b77e68c155a9a8bcdbd896ec.tar.zst
Add fulltext search for posts and profiles (closes #340) (#342)
* Refactor mobile search screen

* Remove 'staleness' fetch trigger on search

* Implement a temporary fulltext search solution

* Add missing key from profile search result

* A few UI & UX improvements to the search suggestions

* Update web search suggestions

* Implement search in web build
Diffstat (limited to 'src/state/models')
-rw-r--r--src/state/models/ui/search.ts51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/state/models/ui/search.ts b/src/state/models/ui/search.ts
new file mode 100644
index 000000000..91e1b24bf
--- /dev/null
+++ b/src/state/models/ui/search.ts
@@ -0,0 +1,51 @@
+import {makeAutoObservable, runInAction} from 'mobx'
+import {searchProfiles, searchPosts} from 'lib/api/search'
+import {AppBskyActorProfile as Profile} from '@atproto/api'
+import {RootStoreModel} from '../root-store'
+
+export class SearchUIModel {
+  isPostsLoading = false
+  isProfilesLoading = false
+  query: string = ''
+  postUris: string[] = []
+  profiles: Profile.View[] = []
+
+  constructor(public rootStore: RootStoreModel) {
+    makeAutoObservable(this)
+  }
+
+  async fetch(q: string) {
+    this.postUris = []
+    this.profiles = []
+    this.query = q
+    if (!q.trim()) {
+      return
+    }
+
+    this.isPostsLoading = true
+    this.isProfilesLoading = true
+
+    const [postsSearch, profilesSearch] = await Promise.all([
+      searchPosts(q).catch(_e => []),
+      searchProfiles(q).catch(_e => []),
+    ])
+    runInAction(() => {
+      this.postUris = postsSearch?.map(p => `at://${p.user.did}/${p.tid}`) || []
+      this.isPostsLoading = false
+    })
+
+    let profiles: Profile.View[] = []
+    if (profilesSearch?.length) {
+      do {
+        const res = await this.rootStore.api.app.bsky.actor.getProfiles({
+          actors: profilesSearch.splice(0, 25).map(p => p.did),
+        })
+        profiles = profiles.concat(res.data.profiles)
+      } while (profilesSearch.length)
+    }
+    runInAction(() => {
+      this.profiles = profiles
+      this.isProfilesLoading = false
+    })
+  }
+}