Extract emoji search
This commit is contained in:
@@ -1,11 +1,8 @@
|
|||||||
import {useCallback} from 'react'
|
import {useCallback} from 'react'
|
||||||
import {moderateProfile, type ModerationOpts} from '@atproto/api'
|
import {moderateProfile, type ModerationOpts} from '@atproto/api'
|
||||||
import {type Emoji} from '@emoji-mart/data'
|
|
||||||
import {keepPreviousData, useQuery} from '@tanstack/react-query'
|
import {keepPreviousData, useQuery} from '@tanstack/react-query'
|
||||||
import Fuse from 'fuse.js'
|
|
||||||
|
|
||||||
import {isJustAMute, moduiContainsHideableOffense} from '#/lib/moderation'
|
import {isJustAMute, moduiContainsHideableOffense} from '#/lib/moderation'
|
||||||
import {useGetEmojis} from '#/lib/useGetEmojis'
|
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {STALE} from '#/state/queries'
|
import {STALE} from '#/state/queries'
|
||||||
import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences'
|
import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences'
|
||||||
@@ -16,36 +13,13 @@ import {
|
|||||||
type AutocompleteItemType,
|
type AutocompleteItemType,
|
||||||
type AutocompleteProfile,
|
type AutocompleteProfile,
|
||||||
} from '#/components/Autocomplete/types'
|
} from '#/components/Autocomplete/types'
|
||||||
|
import {useEmojiSearch} from './useEmojiSearch'
|
||||||
|
|
||||||
const DEFAULT_MOD_OPTS = {
|
const DEFAULT_MOD_OPTS = {
|
||||||
userDid: undefined,
|
userDid: undefined,
|
||||||
prefs: DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs,
|
prefs: DEFAULT_LOGGED_OUT_PREFERENCES.moderationPrefs,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Lazily loaded Fuse instance for emoji search. Built once on first search,
|
|
||||||
* then reused for all subsequent searches.
|
|
||||||
*/
|
|
||||||
let emojiFuseInstance: Fuse<Emoji> | null = null
|
|
||||||
function useEmojiSearch() {
|
|
||||||
const getEmojis = useGetEmojis()
|
|
||||||
|
|
||||||
return useCallback(
|
|
||||||
async (query: string, limit: number = 8) => {
|
|
||||||
if (!emojiFuseInstance) {
|
|
||||||
const data = await getEmojis()
|
|
||||||
emojiFuseInstance = new Fuse(Object.values(data.emojis), {
|
|
||||||
keys: ['search'],
|
|
||||||
threshold: 0.3,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return emojiFuseInstance.search(query, {limit})
|
|
||||||
},
|
|
||||||
[getEmojis],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useAutocomplete({
|
export function useAutocomplete({
|
||||||
type,
|
type,
|
||||||
query: q,
|
query: q,
|
||||||
@@ -90,13 +64,7 @@ export function useAutocomplete({
|
|||||||
profile,
|
profile,
|
||||||
}))
|
}))
|
||||||
} else if (type === 'emoji') {
|
} else if (type === 'emoji') {
|
||||||
const results = await emojiSearch(q, limit || 8)
|
return emojiSearch(q, limit || 8)
|
||||||
return results.map(result => ({
|
|
||||||
key: result.item.id,
|
|
||||||
type: 'emoji' as const,
|
|
||||||
value: result.item.skins[0].native,
|
|
||||||
emoji: result.item,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return []
|
return []
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import {useCallback} from 'react'
|
||||||
|
import {type Emoji} from '@emoji-mart/data'
|
||||||
|
import Fuse from 'fuse.js'
|
||||||
|
|
||||||
|
import {useGetEmojis} from '#/lib/useGetEmojis'
|
||||||
|
import {type AutocompleteEmoji} from '#/components/Autocomplete/types'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lazily loaded Fuse instance for emoji search. Built once on first search,
|
||||||
|
* then reused for all subsequent searches.
|
||||||
|
*/
|
||||||
|
let emojiFuseInstance: Fuse<Emoji> | null = null
|
||||||
|
|
||||||
|
export function useEmojiSearch(): (
|
||||||
|
query: string,
|
||||||
|
limit?: number,
|
||||||
|
) => Promise<AutocompleteEmoji[]> {
|
||||||
|
const getEmojis = useGetEmojis()
|
||||||
|
|
||||||
|
return useCallback(
|
||||||
|
async (query: string, limit: number = 8) => {
|
||||||
|
if (!emojiFuseInstance) {
|
||||||
|
const data = await getEmojis()
|
||||||
|
emojiFuseInstance = new Fuse(Object.values(data.emojis), {
|
||||||
|
keys: ['search'],
|
||||||
|
threshold: 0.3,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = emojiFuseInstance.search(query, {limit})
|
||||||
|
return results.map(result => ({
|
||||||
|
key: result.item.id,
|
||||||
|
type: 'emoji' as const,
|
||||||
|
value: result.item.skins[0].native,
|
||||||
|
emoji: result.item,
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
[getEmojis],
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user