postmerge-2
This commit is contained in:
parent
5f592e6fff
commit
f77d7b28df
|
@ -356,7 +356,7 @@ export const Editor = (props: Props) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
editor().destroy()
|
editor()?.destroy()
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { Shout } from '../../../graphql/schema/core.gen'
|
||||||
import { createSignal, Show, For } from 'solid-js'
|
import { createSignal, Show, For } from 'solid-js'
|
||||||
|
|
||||||
import { useLocalize } from '../../../context/localize'
|
import { useLocalize } from '../../../context/localize'
|
||||||
import { apiClient } from '../../../graphql/client/core'
|
|
||||||
import { Button } from '../../_shared/Button'
|
import { Button } from '../../_shared/Button'
|
||||||
import { Icon } from '../../_shared/Icon'
|
import { Icon } from '../../_shared/Icon'
|
||||||
import { FEED_PAGE_SIZE } from '../../Views/Feed/Feed'
|
import { FEED_PAGE_SIZE } from '../../Views/Feed/Feed'
|
||||||
|
@ -11,6 +10,9 @@ import { FEED_PAGE_SIZE } from '../../Views/Feed/Feed'
|
||||||
import { SearchResultItem } from './SearchResultItem'
|
import { SearchResultItem } from './SearchResultItem'
|
||||||
|
|
||||||
import styles from './SearchModal.module.scss'
|
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 handle empty article options after backend support (subtitle, cover, etc.)
|
||||||
// @@TODO implement load more
|
// @@TODO implement load more
|
||||||
|
@ -48,40 +50,38 @@ const prepareSearchResults = (list, searchValue) =>
|
||||||
|
|
||||||
export const SearchModal = () => {
|
export const SearchModal = () => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
|
const { sortedArticles } = useArticlesStore()
|
||||||
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
|
const [offset, setOffset] = createSignal(0)
|
||||||
const [inputValue, setInputValue] = createSignal('')
|
const [inputValue, setInputValue] = createSignal('')
|
||||||
const [searchResultsList, setSearchResultsList] = createSignal<[] | null>([])
|
//const [searchResultsList, setSearchResultsList] = createSignal<[] | null>([])
|
||||||
const [isLoading, setIsLoading] = createSignal(false)
|
const [isLoading, setIsLoading] = createSignal(false)
|
||||||
// const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
// const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
|
|
||||||
const handleSearch = async () => {
|
let searchEl: HTMLInputElement
|
||||||
const searchValue = inputValue() || ''
|
const handleQueryChange = async (_ev) => {
|
||||||
|
setInputValue(searchEl.value)
|
||||||
|
|
||||||
if (Boolean(searchValue) && searchValue.length > 2) {
|
if (inputValue() && inputValue().length > 2) await loadMore()
|
||||||
setIsLoading(true)
|
}
|
||||||
|
|
||||||
try {
|
const loadMore = async () => {
|
||||||
// TODO: use offset to load more
|
setIsLoading(true)
|
||||||
const response = await apiClient.getShoutsSearch({
|
saveScrollPosition()
|
||||||
text: searchValue,
|
if (inputValue() && inputValue().length > 2) {
|
||||||
limit: FEED_PAGE_SIZE,
|
console.log(inputValue())
|
||||||
offset: 0,
|
const { hasMore } = await loadShoutsSearch({
|
||||||
})
|
text: inputValue(),
|
||||||
const searchResult = await response.json()
|
offset: offset(),
|
||||||
|
limit: FEED_PAGE_SIZE,
|
||||||
if (searchResult.length > 0) {
|
})
|
||||||
const preparedSearchResultsList = prepareSearchResults(searchResult, searchValue)
|
setIsLoadMoreButtonVisible(hasMore)
|
||||||
|
setOffset(offset() + FEED_PAGE_SIZE)
|
||||||
setSearchResultsList(preparedSearchResultsList)
|
} else {
|
||||||
} else {
|
console.warn('[SaerchView] no query found')
|
||||||
setSearchResultsList(null)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log('search request failed', error)
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
restoreScrollPosition()
|
||||||
|
setIsLoading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -90,16 +90,13 @@ export const SearchModal = () => {
|
||||||
type="search"
|
type="search"
|
||||||
placeholder={t('Site search')}
|
placeholder={t('Site search')}
|
||||||
class={styles.searchInput}
|
class={styles.searchInput}
|
||||||
onInput={(event) => {
|
onInput={handleQueryChange}
|
||||||
setInputValue(event.target.value)
|
ref={searchEl}
|
||||||
|
|
||||||
handleSearch()
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
class={styles.searchButton}
|
class={styles.searchButton}
|
||||||
onClick={handleSearch}
|
onClick={loadMore}
|
||||||
value={isLoading() ? <div class={styles.searchLoader} /> : <Icon name="search" />}
|
value={isLoading() ? <div class={styles.searchLoader} /> : <Icon name="search" />}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -111,14 +108,13 @@ export const SearchModal = () => {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Show when={!isLoading()}>
|
<Show when={!isLoading()}>
|
||||||
<Show when={searchResultsList()}>
|
<Show when={sortedArticles()}>
|
||||||
<For each={searchResultsList()}>
|
<For each={sortedArticles().sort(byScore())}>
|
||||||
{(article: Shout) => (
|
{(article: Shout) => (
|
||||||
<div>
|
<div>
|
||||||
<SearchResultItem
|
<SearchResultItem
|
||||||
article={article}
|
article={article}
|
||||||
settings={{
|
settings={{
|
||||||
noimage: true, // @@TODO remove flag after cover support
|
|
||||||
isFloorImportant: true,
|
isFloorImportant: true,
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
nodate: true,
|
nodate: true,
|
||||||
|
@ -128,16 +124,16 @@ export const SearchModal = () => {
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
|
|
||||||
{/* <Show when={isLoadMoreButtonVisible()}>
|
<Show when={isLoadMoreButtonVisible()}>
|
||||||
<p class="load-more-container">
|
<p class="load-more-container">
|
||||||
<button class="button" onClick={loadMore}>
|
<button class="button" onClick={loadMore}>
|
||||||
{t('Load more')}
|
{t('Load more')}
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</Show> */}
|
</Show>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<Show when={!searchResultsList()}>
|
<Show when={!sortedArticles()}>
|
||||||
<p class={styles.searchDescription} innerHTML={t("We couldn't find anything for your request")} />
|
<p class={styles.searchDescription} innerHTML={t("We couldn't find anything for your request")} />
|
||||||
</Show>
|
</Show>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
|
@ -60,8 +60,8 @@ export const InviteMembers = (props: Props) => {
|
||||||
})
|
})
|
||||||
const start = page * PAGE_SIZE
|
const start = page * PAGE_SIZE
|
||||||
const end = start + PAGE_SIZE
|
const end = start + PAGE_SIZE
|
||||||
const authors = authorsToInvite().map((author) => ({ ...author, selected: false }))
|
const authors = authorsToInvite()?.map((author) => ({ ...author, selected: false }))
|
||||||
return authors.slice(start, end)
|
return authors?.slice(start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
const [pages, infiniteScrollLoader, { end }] = createInfiniteScroll(fetcher)
|
const [pages, infiniteScrollLoader, { end }] = createInfiniteScroll(fetcher)
|
||||||
|
|
|
@ -22,7 +22,7 @@ const [topMonthArticles, setTopMonthArticles] = createSignal<Shout[]>([])
|
||||||
const articlesByAuthor = createLazyMemo(() => {
|
const articlesByAuthor = createLazyMemo(() => {
|
||||||
return Object.values(articleEntities()).reduce(
|
return Object.values(articleEntities()).reduce(
|
||||||
(acc, article) => {
|
(acc, article) => {
|
||||||
article.authors.forEach((author) => {
|
article.authors?.forEach((author) => {
|
||||||
if (!acc[author.slug]) {
|
if (!acc[author.slug]) {
|
||||||
acc[author.slug] = []
|
acc[author.slug] = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,16 @@ export const byTopicStatDesc = (metric: keyof TopicStat) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const byScore = () => {
|
||||||
|
return (a, b) => {
|
||||||
|
const x = a?.score || 0
|
||||||
|
const y = b?.score || 0
|
||||||
|
if (x > y) return -1
|
||||||
|
if (x < y) return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const sortBy = (data, metric) => {
|
export const sortBy = (data, metric) => {
|
||||||
const x = [...data]
|
const x = [...data]
|
||||||
x.sort(typeof metric === 'function' ? metric : byStat(metric))
|
x.sort(typeof metric === 'function' ? metric : byStat(metric))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user