diff --git a/src/components/SearchModal/SearchModal.tsx b/src/components/SearchModal/SearchModal.tsx index c8fd5717..72922959 100644 --- a/src/components/SearchModal/SearchModal.tsx +++ b/src/components/SearchModal/SearchModal.tsx @@ -2,7 +2,8 @@ import { For, Show, createResource, createSignal, onCleanup } from 'solid-js' import { debounce } from 'throttle-debounce' import { Button } from '~/components/_shared/Button' import { Icon } from '~/components/_shared/Icon' -import { useFeed } from '~/context/feed' +import { LoadMoreItems, LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper' +import { SHOUTS_PER_PAGE, useFeed } from '~/context/feed' import { useLocalize } from '~/context/localize' import type { Shout } from '~/graphql/schema/core.gen' import { restoreScrollPosition, saveScrollPosition } from '~/utils/scroll' @@ -13,9 +14,7 @@ import { SearchResultItem } from './SearchResultItem' import styles from './SearchModal.module.scss' // @@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( @@ -48,34 +47,30 @@ export const SearchModal = () => { const [inputValue, setInputValue] = createSignal('') const [isLoading, setIsLoading] = createSignal(false) const [offset, setOffset] = createSignal(0) + + const fetchSearchResults = async () => { + setIsLoading(true) + saveScrollPosition() + const { hasMore, newShouts } = await loadShoutsSearch({ + limit: FEED_PAGE_SIZE, + text: inputValue(), + offset: offset() + }) + setIsLoading(false) + setOffset(newShouts.length) + setIsLoadMoreButtonVisible(hasMore) + return newShouts + } const [searchResultsList, { refetch: loadSearchResults, mutate: setSearchResultsList }] = createResource< Shout[] - >( - async () => { - setIsLoading(true) - saveScrollPosition() - const { hasMore, newShouts } = await loadShoutsSearch({ - limit: FEED_PAGE_SIZE, - text: inputValue(), - offset: offset() - }) - setIsLoading(false) - setOffset(newShouts.length) - setIsLoadMoreButtonVisible(hasMore) - return newShouts - }, - { - ssrLoadFrom: 'initial', - initialValue: [] - } - ) + >(fetchSearchResults, { ssrLoadFrom: 'initial', initialValue: [] }) - let searchEl: HTMLInputElement + const [searchEl, setSearchEl] = createSignal() const debouncedLoadMore = debounce(500, loadSearchResults) const handleQueryInput = async () => { - setInputValue(searchEl.value) - if (searchEl.value?.length > 2) { + setInputValue(searchEl()?.value ?? '') + if ((searchEl()?.value?.length || 0) > 2) { await debouncedLoadMore() } else { setIsLoading(false) @@ -101,6 +96,11 @@ export const SearchModal = () => { // console.debug('[SearchModal] cleanup debouncing search') }) + const loadMoreResults = async () => { + const result = await fetchSearchResults() + return result as LoadMoreItems + } + return (
{ class={styles.searchInput} onInput={handleQueryInput} onKeyDown={enterQuery} - ref={(el: HTMLInputElement) => (searchEl = el)} + ref={setSearchEl} /> -

- +