This commit is contained in:
tonyrewin 2022-09-09 15:18:09 +03:00
parent 44e0d11832
commit 4c59293678
5 changed files with 78 additions and 64 deletions

View File

@ -1,5 +1,5 @@
import { createEffect, createMemo, For, Show } from 'solid-js'
import { Shout, Topic, Author, Reaction, ReactionKind } from '../../graphql/types.gen'
import { createMemo, For, Show } from 'solid-js'
import { Shout, Reaction, ReactionKind, Topic, Author } from '../../graphql/types.gen'
import '../../styles/Feed.scss'
import Icon from '../Nav/Icon'
import { byCreated, sortBy } from '../../utils/sortby'
@ -9,10 +9,13 @@ import { t } from '../../utils/intl'
import { useStore } from '@nanostores/solid'
import { session } from '../../stores/auth'
import CommentCard from '../Article/Comment'
import { loadRecentArticles, useArticlesStore } from '../../stores/zine/articles'
import { loadMoreAll, useArticlesStore } from '../../stores/zine/articles'
import { useReactionsStore } from '../../stores/zine/reactions'
import { useAuthorsStore } from '../../stores/zine/authors'
import { FeedSidebar } from '../Feed/Sidebar'
import { useTopicsStore } from '../../stores/zine/topics'
import { unique } from '../../utils'
import { AuthorCard } from '../Author/Card'
interface FeedProps {
recentArticles: Shout[]
@ -27,19 +30,23 @@ const AUTHORSHIP_REACTIONS = [
]
export const FeedPage = (props: FeedProps) => {
const [getPage, setPage] = createSignal(1)
// state
const { getSortedArticles: articles } = useArticlesStore({ sortedArticles: props.articles })
const { getSortedArticles: articles } = useArticlesStore({ sortedArticles: props.recentArticles })
const reactions = useReactionsStore(props.reactions)
const {
// getAuthorEntities: authorsBySlug,
getSortedAuthors: authors
} = useAuthorsStore() // test if it catches preloaded authors
const auth = useStore(session)
const topics = createMemo(() => {
const ttt = []
articles().forEach((s: Shout) => s.topics.forEach((tpc: Topic) => ttt.push(tpc)))
return unique(ttt)
})
const { getSortedTopics } = useTopicsStore({ topics: topics() })
// derived
const topReactions = createMemo(() => sortBy(reactions(), byCreated))
const topAuthors = createMemo(() => sortBy(authors(), 'shouts'))
// note this became synthetic
// methods
@ -49,19 +56,11 @@ export const FeedPage = (props: FeedProps) => {
// TODO: list of articles where you are co-author
// TODO: preload proposals
// TODO: (maybe?) and changes history
console.debug(reactions().filter((r) => r.kind in AUTHORSHIP_REACTIONS))
const loadMore = () => {
setPage(getPage() + 1)
//const size = props['size'] || 50
//const page = (props.page || 1) + 1
// TODO: loadFeed({ page, size })
}
createEffect(() => {
loadRecentArticles({ page: getPage() })
console.debug(reactions().filter((r) => r.kind in AUTHORSHIP_REACTIONS)) // 2 community self-regulating mechanics
// TODO: query all new posts to be rated for publishing
// TODO: query all reactions where user is in authors list
return []
})
return (
<>
<div class="container feed">
@ -88,8 +87,8 @@ export const FeedPage = (props: FeedProps) => {
</li>
</ul>
<Show when={getSortedArticles().length > 0}>
<For each={getSortedArticles().slice(0, 4)}>
<Show when={articles().length > 0}>
<For each={articles().slice(0, 4)}>
{(article) => <ArticleCard article={article} settings={{ isFeedMode: true }} />}
</For>
@ -101,18 +100,17 @@ export const FeedPage = (props: FeedProps) => {
</a>
</div>
{/*FIXME NOW*/}
{/*<ul class="beside-column">*/}
{/* <For each={topAuthors()}>*/}
{/* {(author) => (*/}
{/* <li>*/}
{/* <AuthorCard author={author} compact={true} hasLink={true} />*/}
{/* </li>*/}
{/* )}*/}
{/* </For>*/}
{/*</ul>*/}
<ul class="beside-column">
<For each={topAuthors()}>
{(author: Author) => (
<li>
<AuthorCard author={author} compact={true} hasLink={true} />
</li>
)}
</For>
</ul>
<For each={getSortedArticles().slice(4)}>
<For each={articles().slice(4)}>
{(article) => <ArticleCard article={article} settings={{ isFeedMode: true }} />}
</For>
</Show>
@ -129,10 +127,10 @@ export const FeedPage = (props: FeedProps) => {
{(c: Reaction) => <CommentCard comment={c} compact={true} />}
</For>
</section>
<Show when={getTopTopics().length > 0}>
<Show when={getSortedTopics().length > 0}>
<section class="feed-topics">
<h4>{t('Topics')}</h4>
<For each={getTopTopics()}>
<For each={getSortedTopics().slice(0, 5)}>
{(topic) => <TopicCard topic={topic} subscribeButtonBottom={true} />}
</For>
</section>
@ -140,7 +138,7 @@ export const FeedPage = (props: FeedProps) => {
</aside>
</div>
<p class="load-more-container">
<button class="button" onClick={loadMore}>
<button class="button" onClick={loadMoreAll}>
{t('Load more')}
</button>
</p>

View File

@ -23,7 +23,7 @@ import {
topCommented
} from '../../stores/zine/top'
import { useTopicsStore } from '../../stores/zine/topics'
import { useArticlesStore } from '../../stores/zine/articles'
import { loadMorePublished, useArticlesStore } from '../../stores/zine/articles'
type HomeProps = {
randomTopics: Topic[]
@ -86,12 +86,6 @@ export const HomePage = (props: HomeProps) => {
console.info('[home] mounted')
})
const loadMore = () => {
const size = props['size'] || 50
const page = (props.page || 1) + 1
console.log('[home] try to load ' + page + ' page with ' + size + ' items')
// FIXME: loadPublished({ page, size })
}
return (
<Suspense fallback={t('Loading')}>
<Show when={Boolean(articles())}>
@ -145,7 +139,7 @@ export const HomePage = (props: HomeProps) => {
<Row3 articles={articles().slice(31, 34) as []} />
<p class="load-more-container">
<button class="button" onClick={loadMore}>
<button class="button" onClick={loadMorePublished}>
{t('Load more')}
</button>
</p>

View File

@ -44,8 +44,8 @@ router.listen((r) => setResource(r.path))
// signals
const [pageState, setPage] = createSignal()
const [sizeState, setSize] = createSignal()
const [getPage, setPage] = createSignal<number>(1)
const [getSize, setSize] = createSignal<number>(10)
export type SortBy =
| 'rating'
@ -109,8 +109,8 @@ const updateParams = () => {
// get request search query params
const paramsDict = {
by: by(), // sort name
page: pageState(), // page number
size: sizeState() // entries per page
page: getPage(), // page number
size: getSize() // entries per page
// TODO: add q for /search
}
console.log('[router] updated url with stored params')
@ -138,4 +138,4 @@ if (!isServer) {
createEffect(() => router.open(window.location.pathname), [window.location])
}
export { slug, route, setPage, setSize, by, setBy, resource }
export { slug, route, setPage, getPage, getSize, setSize, by, setBy, resource }

View File

@ -3,6 +3,7 @@ import type { Shout } from '../../graphql/types.gen'
import type { WritableAtom } from 'nanostores'
import { useStore } from '@nanostores/solid'
import { apiClient } from '../../utils/apiClient'
import { getPage, setPage } from '../router'
let articleEntitiesStore: WritableAtom<Record<string, Shout>>
let sortedArticlesStore: WritableAtom<Shout[]>
@ -69,8 +70,13 @@ const addArticles = (articles: Shout[]) => {
}
}
export const loadRecentArticles = async ({ page }: { page: number }): Promise<void> => {
const newArticles = await apiClient.getRecentArticles({ page })
export const loadRecentAllArticles = async ({ page }: { page: number }): Promise<void> => {
const newArticles = await apiClient.getRecentAllArticles({ page, size: 50 })
addArticles(newArticles)
}
export const loadRecentPublishedArticles = async ({ page }: { page: number }): Promise<void> => {
const newArticles = await apiClient.getRecentPublishedArticles({ page, size: 50 })
addArticles(newArticles)
}
@ -88,3 +94,13 @@ export const useArticlesStore = ({ sortedArticles }: InitialState) => {
return { getArticleEntities, getSortedArticles, getArticlesByTopics, getArticlesByAuthors }
}
export const loadMoreAll = () => {
setPage(getPage() + 1)
loadRecentAllArticles({ page: getPage() + 1 })
}
export const loadMorePublished = () => {
setPage(getPage() + 1)
loadRecentPublishedArticles({ page: getPage() + 1 })
}

View File

@ -45,11 +45,6 @@ export const apiClient = {
const response = await publicGraphQLClient.query(articlesTopMonth, { page: 1, size: 10 }).toPromise()
return response.data.articlesTopMonth
},
getRecentPublishedArticles: async () => {
const response = await publicGraphQLClient.query(articlesRecentPublished, {}).toPromise()
return response.data.recentPublished
},
getRandomTopics: async () => {
const response = await publicGraphQLClient.query(topicsRandomQuery, {}).toPromise()
@ -74,7 +69,7 @@ export const apiClient = {
return response.data.searchQuery
},
getRecentArticles: async ({
getRecentAllArticles: async ({
page = 1,
size = FEED_PAGE_SIZE
}: {
@ -90,6 +85,22 @@ export const apiClient = {
return response.data.recentAll
},
getRecentPublishedArticles: async ({
page = 1,
size = FEED_PAGE_SIZE
}: {
page?: number
size?: number
}): Promise<Shout[]> => {
const response = await publicGraphQLClient
.query(articlesRecentPublished, {
page,
size
})
.toPromise()
return response.data.recentAll
},
getArticlesForTopics: async ({
topicSlugs,
page = 1,
@ -181,12 +192,6 @@ export const apiClient = {
},
// feeds
getPublishedShouts: async ({ page, size }: { page: number; size: number }) => {
const response = await publicGraphQLClient.query(articlesRecentPublished, { page, size }).toPromise()
return response.data.recentPublished
},
getAllTopics: async () => {
const response = await publicGraphQLClient.query(topicsAll, {}).toPromise()
return response.data.topicsAll
@ -203,6 +208,9 @@ export const apiClient = {
return response.data?.getShoutBySlug
},
// reactions
getReactionsForShouts: async ({
shoutSlugs,
page = 1,
@ -242,8 +250,6 @@ export const apiClient = {
return response.data.reactionsByShout
},
// reactions
createReaction: async ({ reaction }) => {
const response = await privateGraphQLClient
.mutation(reactionCreate, { reaction })