fix feed
This commit is contained in:
parent
44e0d11832
commit
4c59293678
|
@ -1,5 +1,5 @@
|
||||||
import { createEffect, createMemo, For, Show } from 'solid-js'
|
import { createMemo, For, Show } from 'solid-js'
|
||||||
import { Shout, Topic, Author, Reaction, ReactionKind } from '../../graphql/types.gen'
|
import { Shout, Reaction, ReactionKind, Topic, Author } from '../../graphql/types.gen'
|
||||||
import '../../styles/Feed.scss'
|
import '../../styles/Feed.scss'
|
||||||
import Icon from '../Nav/Icon'
|
import Icon from '../Nav/Icon'
|
||||||
import { byCreated, sortBy } from '../../utils/sortby'
|
import { byCreated, sortBy } from '../../utils/sortby'
|
||||||
|
@ -9,10 +9,13 @@ import { t } from '../../utils/intl'
|
||||||
import { useStore } from '@nanostores/solid'
|
import { useStore } from '@nanostores/solid'
|
||||||
import { session } from '../../stores/auth'
|
import { session } from '../../stores/auth'
|
||||||
import CommentCard from '../Article/Comment'
|
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 { useReactionsStore } from '../../stores/zine/reactions'
|
||||||
import { useAuthorsStore } from '../../stores/zine/authors'
|
import { useAuthorsStore } from '../../stores/zine/authors'
|
||||||
import { FeedSidebar } from '../Feed/Sidebar'
|
import { FeedSidebar } from '../Feed/Sidebar'
|
||||||
|
import { useTopicsStore } from '../../stores/zine/topics'
|
||||||
|
import { unique } from '../../utils'
|
||||||
|
import { AuthorCard } from '../Author/Card'
|
||||||
|
|
||||||
interface FeedProps {
|
interface FeedProps {
|
||||||
recentArticles: Shout[]
|
recentArticles: Shout[]
|
||||||
|
@ -27,19 +30,23 @@ const AUTHORSHIP_REACTIONS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
export const FeedPage = (props: FeedProps) => {
|
export const FeedPage = (props: FeedProps) => {
|
||||||
const [getPage, setPage] = createSignal(1)
|
|
||||||
|
|
||||||
// state
|
// state
|
||||||
const { getSortedArticles: articles } = useArticlesStore({ sortedArticles: props.articles })
|
const { getSortedArticles: articles } = useArticlesStore({ sortedArticles: props.recentArticles })
|
||||||
const reactions = useReactionsStore(props.reactions)
|
const reactions = useReactionsStore(props.reactions)
|
||||||
const {
|
const {
|
||||||
// getAuthorEntities: authorsBySlug,
|
// getAuthorEntities: authorsBySlug,
|
||||||
getSortedAuthors: authors
|
getSortedAuthors: authors
|
||||||
} = useAuthorsStore() // test if it catches preloaded authors
|
} = useAuthorsStore() // test if it catches preloaded authors
|
||||||
const auth = useStore(session)
|
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
|
// derived
|
||||||
const topReactions = createMemo(() => sortBy(reactions(), byCreated))
|
const topReactions = createMemo(() => sortBy(reactions(), byCreated))
|
||||||
|
const topAuthors = createMemo(() => sortBy(authors(), 'shouts'))
|
||||||
// note this became synthetic
|
// note this became synthetic
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
|
@ -49,19 +56,11 @@ export const FeedPage = (props: FeedProps) => {
|
||||||
// TODO: list of articles where you are co-author
|
// TODO: list of articles where you are co-author
|
||||||
// TODO: preload proposals
|
// TODO: preload proposals
|
||||||
// TODO: (maybe?) and changes history
|
// TODO: (maybe?) and changes history
|
||||||
console.debug(reactions().filter((r) => r.kind in AUTHORSHIP_REACTIONS))
|
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
|
||||||
const loadMore = () => {
|
// TODO: query all reactions where user is in authors list
|
||||||
setPage(getPage() + 1)
|
return []
|
||||||
//const size = props['size'] || 50
|
|
||||||
//const page = (props.page || 1) + 1
|
|
||||||
// TODO: loadFeed({ page, size })
|
|
||||||
}
|
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
loadRecentArticles({ page: getPage() })
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div class="container feed">
|
<div class="container feed">
|
||||||
|
@ -88,8 +87,8 @@ export const FeedPage = (props: FeedProps) => {
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<Show when={getSortedArticles().length > 0}>
|
<Show when={articles().length > 0}>
|
||||||
<For each={getSortedArticles().slice(0, 4)}>
|
<For each={articles().slice(0, 4)}>
|
||||||
{(article) => <ArticleCard article={article} settings={{ isFeedMode: true }} />}
|
{(article) => <ArticleCard article={article} settings={{ isFeedMode: true }} />}
|
||||||
</For>
|
</For>
|
||||||
|
|
||||||
|
@ -101,18 +100,17 @@ export const FeedPage = (props: FeedProps) => {
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/*FIXME NOW*/}
|
<ul class="beside-column">
|
||||||
{/*<ul class="beside-column">*/}
|
<For each={topAuthors()}>
|
||||||
{/* <For each={topAuthors()}>*/}
|
{(author: Author) => (
|
||||||
{/* {(author) => (*/}
|
<li>
|
||||||
{/* <li>*/}
|
<AuthorCard author={author} compact={true} hasLink={true} />
|
||||||
{/* <AuthorCard author={author} compact={true} hasLink={true} />*/}
|
</li>
|
||||||
{/* </li>*/}
|
)}
|
||||||
{/* )}*/}
|
</For>
|
||||||
{/* </For>*/}
|
</ul>
|
||||||
{/*</ul>*/}
|
|
||||||
|
|
||||||
<For each={getSortedArticles().slice(4)}>
|
<For each={articles().slice(4)}>
|
||||||
{(article) => <ArticleCard article={article} settings={{ isFeedMode: true }} />}
|
{(article) => <ArticleCard article={article} settings={{ isFeedMode: true }} />}
|
||||||
</For>
|
</For>
|
||||||
</Show>
|
</Show>
|
||||||
|
@ -129,10 +127,10 @@ export const FeedPage = (props: FeedProps) => {
|
||||||
{(c: Reaction) => <CommentCard comment={c} compact={true} />}
|
{(c: Reaction) => <CommentCard comment={c} compact={true} />}
|
||||||
</For>
|
</For>
|
||||||
</section>
|
</section>
|
||||||
<Show when={getTopTopics().length > 0}>
|
<Show when={getSortedTopics().length > 0}>
|
||||||
<section class="feed-topics">
|
<section class="feed-topics">
|
||||||
<h4>{t('Topics')}</h4>
|
<h4>{t('Topics')}</h4>
|
||||||
<For each={getTopTopics()}>
|
<For each={getSortedTopics().slice(0, 5)}>
|
||||||
{(topic) => <TopicCard topic={topic} subscribeButtonBottom={true} />}
|
{(topic) => <TopicCard topic={topic} subscribeButtonBottom={true} />}
|
||||||
</For>
|
</For>
|
||||||
</section>
|
</section>
|
||||||
|
@ -140,7 +138,7 @@ export const FeedPage = (props: FeedProps) => {
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
<p class="load-more-container">
|
<p class="load-more-container">
|
||||||
<button class="button" onClick={loadMore}>
|
<button class="button" onClick={loadMoreAll}>
|
||||||
{t('Load more')}
|
{t('Load more')}
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -23,7 +23,7 @@ import {
|
||||||
topCommented
|
topCommented
|
||||||
} from '../../stores/zine/top'
|
} from '../../stores/zine/top'
|
||||||
import { useTopicsStore } from '../../stores/zine/topics'
|
import { useTopicsStore } from '../../stores/zine/topics'
|
||||||
import { useArticlesStore } from '../../stores/zine/articles'
|
import { loadMorePublished, useArticlesStore } from '../../stores/zine/articles'
|
||||||
|
|
||||||
type HomeProps = {
|
type HomeProps = {
|
||||||
randomTopics: Topic[]
|
randomTopics: Topic[]
|
||||||
|
@ -86,12 +86,6 @@ export const HomePage = (props: HomeProps) => {
|
||||||
console.info('[home] mounted')
|
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 (
|
return (
|
||||||
<Suspense fallback={t('Loading')}>
|
<Suspense fallback={t('Loading')}>
|
||||||
<Show when={Boolean(articles())}>
|
<Show when={Boolean(articles())}>
|
||||||
|
@ -145,7 +139,7 @@ export const HomePage = (props: HomeProps) => {
|
||||||
<Row3 articles={articles().slice(31, 34) as []} />
|
<Row3 articles={articles().slice(31, 34) as []} />
|
||||||
|
|
||||||
<p class="load-more-container">
|
<p class="load-more-container">
|
||||||
<button class="button" onClick={loadMore}>
|
<button class="button" onClick={loadMorePublished}>
|
||||||
{t('Load more')}
|
{t('Load more')}
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -44,8 +44,8 @@ router.listen((r) => setResource(r.path))
|
||||||
|
|
||||||
// signals
|
// signals
|
||||||
|
|
||||||
const [pageState, setPage] = createSignal()
|
const [getPage, setPage] = createSignal<number>(1)
|
||||||
const [sizeState, setSize] = createSignal()
|
const [getSize, setSize] = createSignal<number>(10)
|
||||||
|
|
||||||
export type SortBy =
|
export type SortBy =
|
||||||
| 'rating'
|
| 'rating'
|
||||||
|
@ -109,8 +109,8 @@ const updateParams = () => {
|
||||||
// get request search query params
|
// get request search query params
|
||||||
const paramsDict = {
|
const paramsDict = {
|
||||||
by: by(), // sort name
|
by: by(), // sort name
|
||||||
page: pageState(), // page number
|
page: getPage(), // page number
|
||||||
size: sizeState() // entries per page
|
size: getSize() // entries per page
|
||||||
// TODO: add q for /search
|
// TODO: add q for /search
|
||||||
}
|
}
|
||||||
console.log('[router] updated url with stored params')
|
console.log('[router] updated url with stored params')
|
||||||
|
@ -138,4 +138,4 @@ if (!isServer) {
|
||||||
createEffect(() => router.open(window.location.pathname), [window.location])
|
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 }
|
||||||
|
|
|
@ -3,6 +3,7 @@ import type { Shout } from '../../graphql/types.gen'
|
||||||
import type { WritableAtom } from 'nanostores'
|
import type { WritableAtom } from 'nanostores'
|
||||||
import { useStore } from '@nanostores/solid'
|
import { useStore } from '@nanostores/solid'
|
||||||
import { apiClient } from '../../utils/apiClient'
|
import { apiClient } from '../../utils/apiClient'
|
||||||
|
import { getPage, setPage } from '../router'
|
||||||
|
|
||||||
let articleEntitiesStore: WritableAtom<Record<string, Shout>>
|
let articleEntitiesStore: WritableAtom<Record<string, Shout>>
|
||||||
let sortedArticlesStore: WritableAtom<Shout[]>
|
let sortedArticlesStore: WritableAtom<Shout[]>
|
||||||
|
@ -69,8 +70,13 @@ const addArticles = (articles: Shout[]) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadRecentArticles = async ({ page }: { page: number }): Promise<void> => {
|
export const loadRecentAllArticles = async ({ page }: { page: number }): Promise<void> => {
|
||||||
const newArticles = await apiClient.getRecentArticles({ page })
|
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)
|
addArticles(newArticles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,3 +94,13 @@ export const useArticlesStore = ({ sortedArticles }: InitialState) => {
|
||||||
|
|
||||||
return { getArticleEntities, getSortedArticles, getArticlesByTopics, getArticlesByAuthors }
|
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 })
|
||||||
|
}
|
||||||
|
|
|
@ -45,11 +45,6 @@ export const apiClient = {
|
||||||
const response = await publicGraphQLClient.query(articlesTopMonth, { page: 1, size: 10 }).toPromise()
|
const response = await publicGraphQLClient.query(articlesTopMonth, { page: 1, size: 10 }).toPromise()
|
||||||
return response.data.articlesTopMonth
|
return response.data.articlesTopMonth
|
||||||
},
|
},
|
||||||
getRecentPublishedArticles: async () => {
|
|
||||||
const response = await publicGraphQLClient.query(articlesRecentPublished, {}).toPromise()
|
|
||||||
|
|
||||||
return response.data.recentPublished
|
|
||||||
},
|
|
||||||
getRandomTopics: async () => {
|
getRandomTopics: async () => {
|
||||||
const response = await publicGraphQLClient.query(topicsRandomQuery, {}).toPromise()
|
const response = await publicGraphQLClient.query(topicsRandomQuery, {}).toPromise()
|
||||||
|
|
||||||
|
@ -74,7 +69,7 @@ export const apiClient = {
|
||||||
|
|
||||||
return response.data.searchQuery
|
return response.data.searchQuery
|
||||||
},
|
},
|
||||||
getRecentArticles: async ({
|
getRecentAllArticles: async ({
|
||||||
page = 1,
|
page = 1,
|
||||||
size = FEED_PAGE_SIZE
|
size = FEED_PAGE_SIZE
|
||||||
}: {
|
}: {
|
||||||
|
@ -90,6 +85,22 @@ export const apiClient = {
|
||||||
|
|
||||||
return response.data.recentAll
|
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 ({
|
getArticlesForTopics: async ({
|
||||||
topicSlugs,
|
topicSlugs,
|
||||||
page = 1,
|
page = 1,
|
||||||
|
@ -181,12 +192,6 @@ export const apiClient = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// feeds
|
// feeds
|
||||||
|
|
||||||
getPublishedShouts: async ({ page, size }: { page: number; size: number }) => {
|
|
||||||
const response = await publicGraphQLClient.query(articlesRecentPublished, { page, size }).toPromise()
|
|
||||||
|
|
||||||
return response.data.recentPublished
|
|
||||||
},
|
|
||||||
getAllTopics: async () => {
|
getAllTopics: async () => {
|
||||||
const response = await publicGraphQLClient.query(topicsAll, {}).toPromise()
|
const response = await publicGraphQLClient.query(topicsAll, {}).toPromise()
|
||||||
return response.data.topicsAll
|
return response.data.topicsAll
|
||||||
|
@ -203,6 +208,9 @@ export const apiClient = {
|
||||||
|
|
||||||
return response.data?.getShoutBySlug
|
return response.data?.getShoutBySlug
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// reactions
|
||||||
|
|
||||||
getReactionsForShouts: async ({
|
getReactionsForShouts: async ({
|
||||||
shoutSlugs,
|
shoutSlugs,
|
||||||
page = 1,
|
page = 1,
|
||||||
|
@ -242,8 +250,6 @@ export const apiClient = {
|
||||||
return response.data.reactionsByShout
|
return response.data.reactionsByShout
|
||||||
},
|
},
|
||||||
|
|
||||||
// reactions
|
|
||||||
|
|
||||||
createReaction: async ({ reaction }) => {
|
createReaction: async ({ reaction }) => {
|
||||||
const response = await privateGraphQLClient
|
const response = await privateGraphQLClient
|
||||||
.mutation(reactionCreate, { reaction })
|
.mutation(reactionCreate, { reaction })
|
||||||
|
|
Loading…
Reference in New Issue
Block a user