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}
/>
: }
/>
@@ -111,14 +108,13 @@ export const SearchModal = () => {
/>
-
-
+
+
{(article: Shout) => (
{
)}
- {/*
+
- */}
+
-
+
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))