import type { MaybeRef } from '@vueuse/core' import type { Account, Paginator, Results, SearchParams, Status } from 'masto' export interface UseSearchOptions { type?: MaybeRef<'accounts' | 'hashtags' | 'statuses'> } export function useSearch(query: MaybeRef, options?: UseSearchOptions) { const done = ref(false) const masto = useMasto() const loading = ref(false) const statuses = ref([]) const accounts = ref([]) const hashtags = ref([]) let paginator: Paginator | undefined debouncedWatch(() => unref(query), async () => { if (!unref(query) || !isMastoInitialised.value) return loading.value = true /** * Based on the source it seems like modifying the params when calling next would result in a new search, * but that doesn't seem to be the case. So instead we just create a new paginator with the new params. */ paginator = masto.search({ q: unref(query), resolve: true, type: unref(options?.type) }) const nextResults = await paginator.next() done.value = nextResults.done || false statuses.value = nextResults.value?.statuses || [] accounts.value = nextResults.value?.accounts || [] hashtags.value = nextResults.value?.hashtags || [] loading.value = false }, { debounce: 500 }) const next = async () => { if (!unref(query) || !isMastoInitialised.value || !paginator) return loading.value = true const nextResults = await paginator.next() loading.value = false done.value = nextResults.done || false statuses.value = [ ...statuses.value, ...(nextResults.value.statuses || []), ] accounts.value = [ ...statuses.value, ...(nextResults.value.accounts || []), ] hashtags.value = [ ...statuses.value, ...(nextResults.value.statuses || []), ] } return { accounts, hashtags, statuses, loading: readonly(loading), next, } }