64 lines
1.6 KiB
JavaScript
64 lines
1.6 KiB
JavaScript
import { useEffect, useMemo, useState } from 'react'
|
|
import useAlgoliaSearch from 'react-native-minuit/src/hooks/useAlgoliaSearch'
|
|
import { AlgoliaProjectConfig } from '../data/keys'
|
|
import { hasCoverAsset, hydrateProjects } from './searchProjectAssets'
|
|
|
|
const batchSize = 12
|
|
|
|
const usePlaylistMusicSearch = () => {
|
|
const [search, setSearch] = useState('')
|
|
const [hydratedMusics, setHydratedMusics] = useState(null)
|
|
|
|
const normalizedSearch = useMemo(() => search.trim(), [search])
|
|
|
|
const { hits: musics, loading } = useAlgoliaSearch({
|
|
query: normalizedSearch,
|
|
algoliaObject: AlgoliaProjectConfig,
|
|
batch: batchSize,
|
|
condition: normalizedSearch.length > 0,
|
|
searchParams: {
|
|
filters: 'hasSong:true',
|
|
},
|
|
})
|
|
|
|
useEffect(() => {
|
|
let isCancelled = false
|
|
const nextMusics = Array.isArray(musics) ? musics : []
|
|
const requiresHydration =
|
|
nextMusics.length > 0 && nextMusics.some((project) => !hasCoverAsset(project))
|
|
|
|
if (!requiresHydration) {
|
|
setHydratedMusics(null)
|
|
return () => {
|
|
isCancelled = true
|
|
}
|
|
}
|
|
|
|
setHydratedMusics(null)
|
|
;(async () => {
|
|
const hydrated = await hydrateProjects(nextMusics, { ensureCover: true })
|
|
if (!isCancelled) {
|
|
setHydratedMusics(hydrated)
|
|
}
|
|
})()
|
|
|
|
return () => {
|
|
isCancelled = true
|
|
}
|
|
}, [musics])
|
|
|
|
const visibleMusics = (hydratedMusics ?? musics)?.filter(
|
|
(project) => project?.songPublishedOnMusicLand !== false
|
|
)
|
|
|
|
return {
|
|
search,
|
|
setSearch,
|
|
musics: visibleMusics,
|
|
loading,
|
|
hasSearch: normalizedSearch.length > 0,
|
|
}
|
|
}
|
|
|
|
export default usePlaylistMusicSearch
|