..
Some checks failed
deploy / test (push) Failing after 56s
deploy / deploy (push) Has been skipped

This commit is contained in:
Untone 2023-12-25 07:01:52 +03:00
parent 4d9a563a02
commit 90ebaa0099
6 changed files with 75 additions and 38 deletions

View File

@ -87,12 +87,14 @@ export const ArticleCard = (props: ArticleCardProps) => {
const { t, lang, formatDate } = useLocalize() const { t, lang, formatDate } = useLocalize()
const { author } = useSession() const { author } = useSession()
const mainTopicSlug = props.article.main_topic || '' const mainTopicSlug = props.article.main_topic || ''
const mainTopic = props.article.topics.find((tpc: Topic) => tpc.slug === mainTopicSlug) const mainTopic = props.article.topics?.find((tpc: Topic) => tpc.slug === mainTopicSlug)
const mainTopicTitle = const mainTopicTitle =
mainTopicSlug && lang() === 'en' ? mainTopicSlug.replace('-', ' ') : mainTopic.title mainTopicSlug && lang() === 'en' ? mainTopicSlug.replace('-', ' ') : mainTopic?.title || ''
const formattedDate = createMemo<string>(() => { const formattedDate = createMemo<string>(() => {
return formatDate(new Date(props.article.created_at * 1000)) let r = ''
if (props.article.created_at) r = formatDate(new Date(props.article.created_at * 1000))
return r
}) })
const { title, subtitle } = getTitleAndSubtitle(props.article) const { title, subtitle } = getTitleAndSubtitle(props.article)

View File

@ -25,6 +25,7 @@ import { Sidebar } from '../../Feed/Sidebar'
import styles from './Feed.module.scss' import styles from './Feed.module.scss'
import stylesBeside from '../../Feed/Beside.module.scss' import stylesBeside from '../../Feed/Beside.module.scss'
import stylesTopic from '../../Feed/CardTopic.module.scss' import stylesTopic from '../../Feed/CardTopic.module.scss'
import { useSession } from '../../../context/session'
export const FEED_PAGE_SIZE = 20 export const FEED_PAGE_SIZE = 20
const UNRATED_ARTICLES_COUNT = 5 const UNRATED_ARTICLES_COUNT = 5
@ -129,7 +130,14 @@ export const FeedView = (props: Props) => {
onMount(() => { onMount(() => {
loadMore() loadMore()
// eslint-disable-next-line promise/catch-or-return // eslint-disable-next-line promise/catch-or-return
Promise.all([loadUnratedArticles(), loadTopComments()]).finally(() => setIsRightColumnLoaded(true)) Promise.all([loadTopComments()]).finally(() => setIsRightColumnLoaded(true))
})
const { session } = useSession()
createEffect(() => {
if (session()?.access_token && !unratedArticles()) {
loadUnratedArticles()
}
}) })
createEffect( createEffect(

View File

@ -1,13 +1,14 @@
import type { SearchResult } from '../../graphql/schema/core.gen' import type { SearchResult } from '../../graphql/schema/core.gen'
import { Show, For, createSignal } from 'solid-js' import { Show, For, createSignal, createEffect, onMount } from 'solid-js'
import '../../styles/Search.scss' import '../../styles/Search.scss'
import { useLocalize } from '../../context/localize' import { useLocalize } from '../../context/localize'
import { useRouter } from '../../stores/router' import { useRouter } from '../../stores/router'
import { loadShouts, useArticlesStore } from '../../stores/zine/articles' import { loadShoutsSearch, useArticlesStore } from '../../stores/zine/articles'
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll' import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
import { ArticleCard } from '../Feed/ArticleCard' import { ArticleCard } from '../Feed/ArticleCard'
import { apiClient } from '../../graphql/client/core'
type SearchPageSearchParams = { type SearchPageSearchParams = {
by: '' | 'relevance' | 'rating' by: '' | 'relevance' | 'rating'
@ -35,16 +36,33 @@ export const SearchView = (props: Props) => {
const loadMore = async () => { const loadMore = async () => {
saveScrollPosition() saveScrollPosition()
const { hasMore } = await loadShouts({ if (query()) {
filters: {}, console.log(query())
const { hasMore } = await loadShoutsSearch({
text: query(),
offset: offset(), offset: offset(),
limit: LOAD_MORE_PAGE_SIZE, limit: LOAD_MORE_PAGE_SIZE,
}) })
setIsLoadMoreButtonVisible(hasMore) setIsLoadMoreButtonVisible(hasMore)
setOffset(offset() + LOAD_MORE_PAGE_SIZE) setOffset(offset() + LOAD_MORE_PAGE_SIZE)
} else {
console.warn('[SaerchView] no query found')
}
restoreScrollPosition() restoreScrollPosition()
} }
onMount(async () => {
const q = window.location.pathname.replace('/search/', '') || props.query
setQuery(q)
if (sortedArticles() && !sortedArticles()[0].created_at) {
// TODO: fill up articles data structures in search results
console.info('[SearchView] poor articles data structure found')
await loadMore()
}
})
// TODO: use score from the search results to sort by relevance
return ( return (
<div class="search-page wide-container"> <div class="search-page wide-container">
<form action="/search" class="search-form row"> <form action="/search" class="search-form row">
@ -94,21 +112,15 @@ export const SearchView = (props: Props) => {
)} )}
</For> </For>
<Show when={isLoadMoreButtonVisible()}>
<div class="col-md-6"> <div class="col-md-6">
<a href="#" class="search__show-more"> <a href={`/search/${query()}`} onClick={loadMore} class="search__show-more">
<span class="search__show-more-inner">{t('Load more')}</span> <span class="search__show-more-inner">{t('Load more')}</span>
</a> </a>
</div> </div>
</div>
</div>
<Show when={isLoadMoreButtonVisible()}>
<p class="load-more-container">
<button class="button" onClick={loadMore}>
{t('Load more')}
</button>
</p>
</Show> </Show>
</div>
</div>
</Show> </Show>
</div> </div>
) )

View File

@ -195,8 +195,8 @@ export const apiClient = {
return resp.data.load_shouts_by return resp.data.load_shouts_by
}, },
getShoutsSearch: async (args: QueryLoad_Shouts_SearchArgs) => { getShoutsSearch: async ({ text, limit, offset }: QueryLoad_Shouts_SearchArgs) => {
const resp = await publicGraphQLClient.query(shoutsLoadSearch, args).toPromise() const resp = await publicGraphQLClient.query(shoutsLoadSearch, { text, limit, offset }).toPromise()
if (resp.error) console.error(resp) if (resp.error) console.error(resp)
return resp.data.load_shouts_search return resp.data.load_shouts_search

View File

@ -6,6 +6,19 @@ export default gql`
score score
title title
slug slug
created_at
cover
topics {
slug
title
}
authors {
slug
name
pic
created_at
last_seen
}
} }
} }
` `

View File

@ -85,7 +85,8 @@ const addArticles = (...args: Shout[][]) => {
const authorsByTopic = allArticles.reduce( const authorsByTopic = allArticles.reduce(
(acc, article) => { (acc, article) => {
const { authors, topics } = article const { authors, topics } = article
if (topics) {
// TODO: check if data can be consistent without topics and authors in article
topics.forEach((topic) => { topics.forEach((topic) => {
if (!acc[topic.slug]) { if (!acc[topic.slug]) {
acc[topic.slug] = [] acc[topic.slug] = []
@ -97,6 +98,7 @@ const addArticles = (...args: Shout[][]) => {
} }
}) })
}) })
}
return acc return acc
}, },