reasource-based-search-results-load
This commit is contained in:
parent
5c827ca287
commit
b866af2ff7
|
@ -2,6 +2,7 @@ import type { Author, Shout, Topic } from '../../../graphql/schema/core.gen'
|
||||||
|
|
||||||
import { getPagePath, openPage } from '@nanostores/router'
|
import { getPagePath, openPage } from '@nanostores/router'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
|
import { createMemo, createSignal, For, Show } from 'solid-js'
|
||||||
|
|
||||||
import { useLocalize } from '../../../context/localize'
|
import { useLocalize } from '../../../context/localize'
|
||||||
import { useSession } from '../../../context/session'
|
import { useSession } from '../../../context/session'
|
||||||
|
|
|
@ -4,8 +4,6 @@ import { getPagePath, redirectPage } from '@nanostores/router'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import { Show, createSignal, createEffect, onMount, onCleanup, For } from 'solid-js'
|
import { Show, createSignal, createEffect, onMount, onCleanup, For } from 'solid-js'
|
||||||
|
|
||||||
import { apiClient } from '../../../utils/apiClient'
|
|
||||||
|
|
||||||
import { useLocalize } from '../../../context/localize'
|
import { useLocalize } from '../../../context/localize'
|
||||||
import { useSession } from '../../../context/session'
|
import { useSession } from '../../../context/session'
|
||||||
import { apiClient } from '../../../graphql/client/core'
|
import { apiClient } from '../../../graphql/client/core'
|
||||||
|
@ -22,7 +20,6 @@ import { HeaderAuth } from '../HeaderAuth'
|
||||||
import { Modal } from '../Modal'
|
import { Modal } from '../Modal'
|
||||||
import { SearchModal } from '../SearchModal/SearchModal'
|
import { SearchModal } from '../SearchModal/SearchModal'
|
||||||
import { Snackbar } from '../Snackbar'
|
import { Snackbar } from '../Snackbar'
|
||||||
import { SearchModal } from '../SearchModal/SearchModal'
|
|
||||||
|
|
||||||
import { Link } from './Link'
|
import { Link } from './Link'
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ export const HeaderAuth = (props: Props) => {
|
||||||
|
|
||||||
<Show when={!isSaveButtonVisible()}>
|
<Show when={!isSaveButtonVisible()}>
|
||||||
<div class={styles.userControlItem}>
|
<div class={styles.userControlItem}>
|
||||||
<a href="?modal=search">
|
<a href="?m=search">
|
||||||
<Icon name="search" class={styles.icon} />
|
<Icon name="search" class={styles.icon} />
|
||||||
<Icon name="search" class={clsx(styles.icon, styles.iconHover)} />
|
<Icon name="search" class={clsx(styles.icon, styles.iconHover)} />
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { Shout } from '../../../graphql/schema/core.gen'
|
import type { Shout } from '../../../graphql/schema/core.gen'
|
||||||
|
|
||||||
import { createResource, createSignal, For, Show } from 'solid-js'
|
import { createEffect, createResource, createSignal, For, onCleanup, Show } from 'solid-js'
|
||||||
import { debounce } from 'throttle-debounce'
|
import { debounce } from 'throttle-debounce'
|
||||||
|
|
||||||
import { useLocalize } from '../../../context/localize'
|
import { useLocalize } from '../../../context/localize'
|
||||||
|
@ -55,6 +55,7 @@ export const SearchModal = () => {
|
||||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
const [inputValue, setInputValue] = createSignal('')
|
const [inputValue, setInputValue] = createSignal('')
|
||||||
const [isLoading, setIsLoading] = createSignal(false)
|
const [isLoading, setIsLoading] = createSignal(false)
|
||||||
|
const [offset, setOffset] = createSignal<number>(0)
|
||||||
const [searchResultsList, { refetch: loadSearchResults, mutate: setSearchResultsList }] = createResource<
|
const [searchResultsList, { refetch: loadSearchResults, mutate: setSearchResultsList }] = createResource<
|
||||||
Shout[]
|
Shout[]
|
||||||
>(
|
>(
|
||||||
|
@ -63,8 +64,10 @@ export const SearchModal = () => {
|
||||||
const { hasMore, newShouts } = await loadShoutsSearch({
|
const { hasMore, newShouts } = await loadShoutsSearch({
|
||||||
limit: FEED_PAGE_SIZE,
|
limit: FEED_PAGE_SIZE,
|
||||||
text: inputValue(),
|
text: inputValue(),
|
||||||
offset: searchResultsList().length,
|
offset: offset(),
|
||||||
})
|
})
|
||||||
|
setIsLoading(false)
|
||||||
|
setOffset(newShouts.length)
|
||||||
setIsLoadMoreButtonVisible(hasMore)
|
setIsLoadMoreButtonVisible(hasMore)
|
||||||
return newShouts
|
return newShouts
|
||||||
},
|
},
|
||||||
|
@ -76,13 +79,33 @@ export const SearchModal = () => {
|
||||||
|
|
||||||
let searchEl: HTMLInputElement
|
let searchEl: HTMLInputElement
|
||||||
const debouncedLoadMore = debounce(500, loadSearchResults)
|
const debouncedLoadMore = debounce(500, loadSearchResults)
|
||||||
const handleQueryInput = () => {
|
|
||||||
const inp = searchEl.value
|
const handleQueryInput = async () => {
|
||||||
setInputValue(inp)
|
setInputValue(searchEl.value)
|
||||||
if (inp?.length > 2) debouncedLoadMore()
|
if (searchEl.value?.length > 2) {
|
||||||
else setSearchResultsList([])
|
await debouncedLoadMore()
|
||||||
|
} else {
|
||||||
|
setIsLoading(false)
|
||||||
|
setSearchResultsList([])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const enterQuery = async (ev: KeyboardEvent) => {
|
||||||
|
setIsLoading(true)
|
||||||
|
if (ev.key === 'Enter' && inputValue().length > 2) {
|
||||||
|
await debouncedLoadMore()
|
||||||
|
} else {
|
||||||
|
setIsLoading(false)
|
||||||
|
setSearchResultsList([])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup the debounce timer when the component unmounts
|
||||||
|
onCleanup(() => {
|
||||||
|
debouncedLoadMore.cancel()
|
||||||
|
console.log('cleanup search')
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={styles.searchContainer}>
|
<div class={styles.searchContainer}>
|
||||||
<input
|
<input
|
||||||
|
@ -90,13 +113,13 @@ export const SearchModal = () => {
|
||||||
placeholder={t('Site search')}
|
placeholder={t('Site search')}
|
||||||
class={styles.searchInput}
|
class={styles.searchInput}
|
||||||
onInput={handleQueryInput}
|
onInput={handleQueryInput}
|
||||||
onChange={debouncedLoadMore}
|
onKeyDown={enterQuery}
|
||||||
ref={searchEl}
|
ref={searchEl}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
class={styles.searchButton}
|
class={styles.searchButton}
|
||||||
onClick={loadSearchResults}
|
onClick={debouncedLoadMore}
|
||||||
value={isLoading() ? <div class={styles.searchLoader} /> : <Icon name="search" />}
|
value={isLoading() ? <div class={styles.searchLoader} /> : <Icon name="search" />}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user