diff --git a/src/components/Nav/SearchModal/SearchModal.tsx b/src/components/Nav/SearchModal/SearchModal.tsx index 3c786608..85176702 100644 --- a/src/components/Nav/SearchModal/SearchModal.tsx +++ b/src/components/Nav/SearchModal/SearchModal.tsx @@ -1,8 +1,12 @@ import type { Shout } from '../../../graphql/schema/core.gen' -import { createSignal, Show, For } from 'solid-js' +import { createResource, createSignal, For, Show } from 'solid-js' +import { debounce } from 'throttle-debounce' import { useLocalize } from '../../../context/localize' +import { loadShoutsSearch } from '../../../stores/zine/articles' +// import { restoreScrollPosition, saveScrollPosition } from '../../../utils/scroll' +import { byScore } from '../../../utils/sortby' import { Button } from '../../_shared/Button' import { Icon } from '../../_shared/Icon' import { FEED_PAGE_SIZE } from '../../Views/Feed/Feed' @@ -10,13 +14,11 @@ import { FEED_PAGE_SIZE } from '../../Views/Feed/Feed' import { SearchResultItem } from './SearchResultItem' import styles from './SearchModal.module.scss' -import { restoreScrollPosition, saveScrollPosition } from '../../../utils/scroll' -import { loadShoutsSearch, useArticlesStore } from '../../../stores/zine/articles' -import { byScore } from '../../../utils/sortby' // @@TODO handle empty article options after backend support (subtitle, cover, etc.) // @@TODO implement load more // @@TODO implement FILTERS & TOPICS +// @@TODO use save/restoreScrollPosition if needed const getSearchCoincidences = ({ str, intersection }: { str: string; intersection: string }) => `${str.replaceAll( @@ -24,16 +26,16 @@ const getSearchCoincidences = ({ str, intersection }: { str: string; intersectio (casePreservedMatch) => `${casePreservedMatch}`, )}` -const prepareSearchResults = (list, searchValue) => - list.map((article, index) => ({ +const prepareSearchResults = (list: Shout[], searchValue: string) => + list.sort(byScore()).map((article, index) => ({ ...article, - body: '', - cover: '', - createdAt: '', + body: article.body, + cover: article.cover, + created_at: article.created_at, id: index, slug: article.slug, - authors: [], - topics: [], + authors: article.authors, + topics: article.topics, title: article.title ? getSearchCoincidences({ str: article.title, @@ -50,38 +52,35 @@ const prepareSearchResults = (list, searchValue) => export const SearchModal = () => { const { t } = useLocalize() - const { sortedArticles } = useArticlesStore() const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) - const [offset, setOffset] = createSignal(0) const [inputValue, setInputValue] = createSignal('') - //const [searchResultsList, setSearchResultsList] = createSignal<[] | null>([]) const [isLoading, setIsLoading] = createSignal(false) - // const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) - - let searchEl: HTMLInputElement - const handleQueryChange = async (_ev) => { - setInputValue(searchEl.value) - - if (inputValue() && inputValue().length > 2) await loadMore() - } - - const loadMore = async () => { - setIsLoading(true) - saveScrollPosition() - if (inputValue() && inputValue().length > 2) { - console.log(inputValue()) - const { hasMore } = await loadShoutsSearch({ - text: inputValue(), - offset: offset(), + const [searchResultsList, { refetch: loadSearchResults, mutate: setSearchResultsList }] = createResource< + Shout[] + >( + async () => { + setIsLoading(true) + const { hasMore, newShouts } = await loadShoutsSearch({ limit: FEED_PAGE_SIZE, + text: inputValue(), + offset: searchResultsList().length, }) setIsLoadMoreButtonVisible(hasMore) - setOffset(offset() + FEED_PAGE_SIZE) - } else { - console.warn('[SaerchView] no query found') - } - restoreScrollPosition() - setIsLoading(false) + return newShouts + }, + { + ssrLoadFrom: 'initial', + initialValue: [], + }, + ) + + let searchEl: HTMLInputElement + const debouncedLoadMore = debounce(500, loadSearchResults) + const handleQueryInput = () => { + const inp = searchEl.value + setInputValue(inp) + if (inp?.length > 2) debouncedLoadMore() + else setSearchResultsList([]) } return ( @@ -90,13 +89,14 @@ export const SearchModal = () => { type="search" placeholder={t('Site search')} class={styles.searchInput} - onInput={handleQueryChange} + onInput={handleQueryInput} + onChange={debouncedLoadMore} ref={searchEl} />

- +