random topic (#343)
* test * test * index random topic --------- Co-authored-by: Igor Lobanov <igor.lobanov@onetwotrip.com>
This commit is contained in:
parent
4a2f95aa55
commit
d113d9ca8a
|
@ -1,6 +1,6 @@
|
|||
import type { Shout } from '../../graphql/types.gen'
|
||||
import type { Shout, Topic } from '../../graphql/types.gen'
|
||||
|
||||
import { createMemo, createSignal, For, onMount, Show } from 'solid-js'
|
||||
import { batch, createMemo, createSignal, For, onMount, Show } from 'solid-js'
|
||||
|
||||
import { useLocalize } from '../../context/localize'
|
||||
import {
|
||||
|
@ -11,6 +11,7 @@ import {
|
|||
} from '../../stores/zine/articles'
|
||||
import { useTopAuthorsStore } from '../../stores/zine/topAuthors'
|
||||
import { useTopicsStore } from '../../stores/zine/topics'
|
||||
import { apiClient } from '../../utils/apiClient'
|
||||
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
||||
import { splitToPages } from '../../utils/splitToPages'
|
||||
import { ArticleCardSwiper } from '../_shared/SolidSwiper/ArticleCardSwiper'
|
||||
|
@ -31,26 +32,24 @@ type Props = {
|
|||
|
||||
export const PRERENDERED_ARTICLES_COUNT = 5
|
||||
export const RANDOM_TOPICS_COUNT = 12
|
||||
export const RANDOM_TOPIC_SHOUTS_COUNT = 7
|
||||
const CLIENT_LOAD_ARTICLES_COUNT = 29
|
||||
const LOAD_MORE_PAGE_SIZE = 16 // Row1 + Row3 + Row2 + Beside (3 + 1) + Row1 + Row 2 + Row3
|
||||
|
||||
export const HomeView = (props: Props) => {
|
||||
const {
|
||||
sortedArticles,
|
||||
articlesByLayout,
|
||||
topArticles,
|
||||
topCommentedArticles,
|
||||
topMonthArticles,
|
||||
topViewedArticles,
|
||||
} = useArticlesStore({
|
||||
shouts: props.shouts,
|
||||
})
|
||||
const { sortedArticles, topArticles, topCommentedArticles, topMonthArticles, topViewedArticles } =
|
||||
useArticlesStore({
|
||||
shouts: props.shouts,
|
||||
})
|
||||
|
||||
const { topTopics } = useTopicsStore()
|
||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||
const { topAuthors } = useTopAuthorsStore()
|
||||
const { t } = useLocalize()
|
||||
|
||||
const [randomTopic, setRandomTopic] = createSignal<Topic>(null)
|
||||
const [randomTopicArticles, setRandomTopicArticles] = createSignal<Shout[]>([])
|
||||
|
||||
onMount(async () => {
|
||||
loadTopArticles()
|
||||
loadTopMonthArticles()
|
||||
|
@ -63,22 +62,12 @@ export const HomeView = (props: Props) => {
|
|||
|
||||
setIsLoadMoreButtonVisible(hasMore)
|
||||
}
|
||||
})
|
||||
|
||||
const randomLayout = createMemo(() => {
|
||||
const filledLayouts = Object.keys(articlesByLayout()).filter(
|
||||
// FIXME: is 7 ok? or more complex logic needed?
|
||||
(layout) => articlesByLayout()[layout].length > 7,
|
||||
)
|
||||
|
||||
const selectedRandomLayout =
|
||||
filledLayouts.length > 0 ? filledLayouts[Math.floor(Math.random() * filledLayouts.length)] : ''
|
||||
|
||||
return (
|
||||
<Show when={Boolean(selectedRandomLayout)}>
|
||||
<Group articles={articlesByLayout()[selectedRandomLayout]} header={''} />
|
||||
</Show>
|
||||
)
|
||||
const { topic, shouts } = await apiClient.getRandomTopicShouts(RANDOM_TOPIC_SHOUTS_COUNT)
|
||||
batch(() => {
|
||||
setRandomTopic(topic)
|
||||
setRandomTopicArticles(shouts)
|
||||
})
|
||||
})
|
||||
|
||||
const loadMore = async () => {
|
||||
|
@ -135,7 +124,9 @@ export const HomeView = (props: Props) => {
|
|||
header={<h2>{t('Top commented')}</h2>}
|
||||
nodate={true}
|
||||
/>
|
||||
{randomLayout()}
|
||||
<Show when={randomTopic()}>
|
||||
<Group articles={randomTopicArticles()} header={''} />
|
||||
</Show>
|
||||
<Show when={topArticles()}>
|
||||
<ArticleCardSwiper title={t('Favorite')} slides={topArticles()} />
|
||||
</Show>
|
||||
|
|
62
src/graphql/query/articles-load-random-topic.ts
Normal file
62
src/graphql/query/articles-load-random-topic.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
import { gql } from '@urql/core'
|
||||
|
||||
export default gql`
|
||||
query LoadRandomTopicShoutsQuery($limit: Int!) {
|
||||
loadRandomTopicShouts(limit: $limit) {
|
||||
topic {
|
||||
id
|
||||
title
|
||||
body
|
||||
slug
|
||||
pic
|
||||
# community
|
||||
stat {
|
||||
shouts
|
||||
authors
|
||||
followers
|
||||
# viewed
|
||||
}
|
||||
}
|
||||
shouts {
|
||||
id
|
||||
title
|
||||
lead
|
||||
description
|
||||
subtitle
|
||||
slug
|
||||
layout
|
||||
cover
|
||||
lead
|
||||
# community
|
||||
mainTopic
|
||||
topics {
|
||||
id
|
||||
title
|
||||
body
|
||||
slug
|
||||
stat {
|
||||
shouts
|
||||
authors
|
||||
followers
|
||||
}
|
||||
}
|
||||
authors {
|
||||
id
|
||||
name
|
||||
slug
|
||||
userpic
|
||||
createdAt
|
||||
bio
|
||||
}
|
||||
createdAt
|
||||
publishedAt
|
||||
stat {
|
||||
viewed
|
||||
reacted
|
||||
rating
|
||||
commented
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
|
@ -373,6 +373,7 @@ export type Query = {
|
|||
loadMySubscriptions?: Maybe<MySubscriptionsQueryResult>
|
||||
loadNotifications: NotificationsQueryResult
|
||||
loadRandomTopShouts: Array<Maybe<Shout>>
|
||||
loadRandomTopicShouts: RandomTopicShoutsQueryResult
|
||||
loadReactionsBy: Array<Maybe<Reaction>>
|
||||
loadRecipients: Result
|
||||
loadShout?: Maybe<Shout>
|
||||
|
@ -430,6 +431,10 @@ export type QueryLoadRandomTopShoutsArgs = {
|
|||
params?: InputMaybe<LoadRandomTopShoutsParams>
|
||||
}
|
||||
|
||||
export type QueryLoadRandomTopicShoutsArgs = {
|
||||
limit: Scalars['Int']['input']
|
||||
}
|
||||
|
||||
export type QueryLoadReactionsByArgs = {
|
||||
by: ReactionBy
|
||||
limit?: InputMaybe<Scalars['Int']['input']>
|
||||
|
@ -504,6 +509,11 @@ export type QueryUserFollowersArgs = {
|
|||
slug: Scalars['String']['input']
|
||||
}
|
||||
|
||||
export type RandomTopicShoutsQueryResult = {
|
||||
shouts: Array<Maybe<Shout>>
|
||||
topic: Topic
|
||||
}
|
||||
|
||||
export type Rating = {
|
||||
rater: Scalars['String']['output']
|
||||
value: Scalars['Int']['output']
|
||||
|
|
|
@ -47,21 +47,6 @@ const articlesByTopic = createLazyMemo(() => {
|
|||
)
|
||||
})
|
||||
|
||||
const articlesByLayout = createLazyMemo(() => {
|
||||
return Object.values(articleEntities()).reduce(
|
||||
(acc, article) => {
|
||||
if (!acc[article.layout]) {
|
||||
acc[article.layout] = []
|
||||
}
|
||||
|
||||
acc[article.layout].push(article)
|
||||
|
||||
return acc
|
||||
},
|
||||
{} as { [layout: string]: Shout[] },
|
||||
)
|
||||
})
|
||||
|
||||
const topViewedArticles = createLazyMemo(() => {
|
||||
const result = Object.values(articleEntities())
|
||||
result.sort(byStat('viewed'))
|
||||
|
@ -226,7 +211,6 @@ export const useArticlesStore = (initialState: InitialState = {}) => {
|
|||
articleEntities,
|
||||
sortedArticles,
|
||||
articlesByAuthor,
|
||||
articlesByLayout,
|
||||
articlesByTopic,
|
||||
topMonthArticles,
|
||||
topArticles,
|
||||
|
|
|
@ -44,6 +44,7 @@ import updateProfile from '../graphql/mutation/update-profile'
|
|||
import shoutLoad from '../graphql/query/article-load'
|
||||
import shoutsLoadBy from '../graphql/query/articles-load-by'
|
||||
import articlesLoadRandomTop from '../graphql/query/articles-load-random-top'
|
||||
import articlesLoadRandomTopic from '../graphql/query/articles-load-random-topic'
|
||||
import articlesLoadUnrated from '../graphql/query/articles-load-unrated'
|
||||
import authCheckEmailQuery from '../graphql/query/auth-check-email'
|
||||
import authLoginQuery from '../graphql/query/auth-login'
|
||||
|
@ -359,6 +360,16 @@ export const apiClient = {
|
|||
return resp.data.loadRandomTopShouts
|
||||
},
|
||||
|
||||
getRandomTopicShouts: async (limit: number): Promise<{ topic: Topic; shouts: Shout[] }> => {
|
||||
const resp = await graphQLClient.query(articlesLoadRandomTopic, { limit }).toPromise()
|
||||
|
||||
if (resp.error) {
|
||||
console.error(resp)
|
||||
}
|
||||
|
||||
return resp.data.loadRandomTopicShouts
|
||||
},
|
||||
|
||||
getUnratedShouts: async (limit: number): Promise<Shout[]> => {
|
||||
const resp = await graphQLClient.query(articlesLoadUnrated, { limit }).toPromise()
|
||||
if (resp.error) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user