From f77d7b28df2ccaf851cfa32490404c059584fab3 Mon Sep 17 00:00:00 2001 From: Untone Date: Thu, 25 Jan 2024 22:16:38 +0300 Subject: [PATCH] postmerge-2 --- src/components/Editor/Editor.tsx | 2 +- .../Nav/SearchModal/SearchModal.tsx | 76 +++++++++---------- .../_shared/InviteMembers/InviteMembers.tsx | 4 +- src/stores/zine/articles.ts | 2 +- src/utils/sortby.ts | 10 +++ 5 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx index dafaa7f0..211d22e8 100644 --- a/src/components/Editor/Editor.tsx +++ b/src/components/Editor/Editor.tsx @@ -356,7 +356,7 @@ export const Editor = (props: Props) => { }) onCleanup(() => { - editor().destroy() + editor()?.destroy() }) return ( diff --git a/src/components/Nav/SearchModal/SearchModal.tsx b/src/components/Nav/SearchModal/SearchModal.tsx index a0295f5f..3c786608 100644 --- a/src/components/Nav/SearchModal/SearchModal.tsx +++ b/src/components/Nav/SearchModal/SearchModal.tsx @@ -3,7 +3,6 @@ import type { Shout } from '../../../graphql/schema/core.gen' import { createSignal, Show, For } from 'solid-js' import { useLocalize } from '../../../context/localize' -import { apiClient } from '../../../graphql/client/core' import { Button } from '../../_shared/Button' import { Icon } from '../../_shared/Icon' 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 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 @@ -48,40 +50,38 @@ 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 [searchResultsList, setSearchResultsList] = createSignal<[] | null>([]) const [isLoading, setIsLoading] = createSignal(false) // const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) - const handleSearch = async () => { - const searchValue = inputValue() || '' + let searchEl: HTMLInputElement + const handleQueryChange = async (_ev) => { + setInputValue(searchEl.value) - if (Boolean(searchValue) && searchValue.length > 2) { - setIsLoading(true) + if (inputValue() && inputValue().length > 2) await loadMore() + } - try { - // TODO: use offset to load more - const response = await apiClient.getShoutsSearch({ - text: searchValue, - limit: FEED_PAGE_SIZE, - offset: 0, - }) - const searchResult = await response.json() - - if (searchResult.length > 0) { - const preparedSearchResultsList = prepareSearchResults(searchResult, searchValue) - - setSearchResultsList(preparedSearchResultsList) - } else { - setSearchResultsList(null) - } - } catch (error) { - console.log('search request failed', error) - } finally { - setIsLoading(false) - } + const loadMore = async () => { + setIsLoading(true) + saveScrollPosition() + if (inputValue() && inputValue().length > 2) { + console.log(inputValue()) + const { hasMore } = await loadShoutsSearch({ + text: inputValue(), + offset: offset(), + limit: FEED_PAGE_SIZE, + }) + setIsLoadMoreButtonVisible(hasMore) + setOffset(offset() + FEED_PAGE_SIZE) + } else { + console.warn('[SaerchView] no query found') } + restoreScrollPosition() + setIsLoading(false) } return ( @@ -90,16 +90,13 @@ export const SearchModal = () => { type="search" placeholder={t('Site search')} class={styles.searchInput} - onInput={(event) => { - setInputValue(event.target.value) - - handleSearch() - }} + onInput={handleQueryChange} + ref={searchEl} />

- */} + - +

diff --git a/src/components/_shared/InviteMembers/InviteMembers.tsx b/src/components/_shared/InviteMembers/InviteMembers.tsx index 408ffbdd..62940bde 100644 --- a/src/components/_shared/InviteMembers/InviteMembers.tsx +++ b/src/components/_shared/InviteMembers/InviteMembers.tsx @@ -60,8 +60,8 @@ export const InviteMembers = (props: Props) => { }) const start = page * PAGE_SIZE const end = start + PAGE_SIZE - const authors = authorsToInvite().map((author) => ({ ...author, selected: false })) - return authors.slice(start, end) + const authors = authorsToInvite()?.map((author) => ({ ...author, selected: false })) + return authors?.slice(start, end) } const [pages, infiniteScrollLoader, { end }] = createInfiniteScroll(fetcher) diff --git a/src/stores/zine/articles.ts b/src/stores/zine/articles.ts index c2293a27..f7cb9ae6 100644 --- a/src/stores/zine/articles.ts +++ b/src/stores/zine/articles.ts @@ -22,7 +22,7 @@ const [topMonthArticles, setTopMonthArticles] = createSignal([]) const articlesByAuthor = createLazyMemo(() => { return Object.values(articleEntities()).reduce( (acc, article) => { - article.authors.forEach((author) => { + article.authors?.forEach((author) => { if (!acc[author.slug]) { acc[author.slug] = [] } diff --git a/src/utils/sortby.ts b/src/utils/sortby.ts index 99112afd..f6d88df6 100644 --- a/src/utils/sortby.ts +++ b/src/utils/sortby.ts @@ -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) => { const x = [...data] x.sort(typeof metric === 'function' ? metric : byStat(metric))