loadmore+feed+my
This commit is contained in:
parent
4fe2768329
commit
8cce8d897e
|
@ -8,7 +8,6 @@ import { InviteMembers } from '~/components/_shared/InviteMembers'
|
|||
import { Loading } from '~/components/_shared/Loading'
|
||||
import { ShareModal } from '~/components/_shared/ShareModal'
|
||||
import { useAuthors } from '~/context/authors'
|
||||
import { useFeed } from '~/context/feed'
|
||||
import { useGraphQL } from '~/context/graphql'
|
||||
import { useLocalize } from '~/context/localize'
|
||||
import { useReactions } from '~/context/reactions'
|
||||
|
@ -35,8 +34,9 @@ export const FEED_PAGE_SIZE = 20
|
|||
export type PeriodType = 'week' | 'month' | 'year'
|
||||
|
||||
export type FeedProps = {
|
||||
shouts?: Shout[]
|
||||
mode?: '' | 'likes' | 'hot'
|
||||
shouts: Shout[]
|
||||
mode?: 'followed' | 'discussed' | 'coauthored' | 'unrated'
|
||||
order?: '' | 'likes' | 'hot'
|
||||
}
|
||||
|
||||
export const FeedView = (props: FeedProps) => {
|
||||
|
@ -54,7 +54,6 @@ export const FeedView = (props: FeedProps) => {
|
|||
const [isLoading, setIsLoading] = createSignal(false)
|
||||
const [isRightColumnLoaded, setIsRightColumnLoaded] = createSignal(false)
|
||||
const { session } = useSession()
|
||||
const { feed, setFeed } = useFeed()
|
||||
const { loadReactionsBy } = useReactions()
|
||||
const { topTopics } = useTopics()
|
||||
const { topAuthors } = useAuthors()
|
||||
|
@ -68,13 +67,13 @@ export const FeedView = (props: FeedProps) => {
|
|||
setTopComments(comments.sort(byCreated).reverse())
|
||||
}
|
||||
|
||||
// post-load
|
||||
createEffect(
|
||||
on(
|
||||
feed,
|
||||
() => props.shouts,
|
||||
(sss?: Shout[]) => {
|
||||
if (sss && Array.isArray(sss)) {
|
||||
setIsLoading(true)
|
||||
setFeed((prev) => [...prev, ...sss])
|
||||
Promise.all([
|
||||
loadTopComments(),
|
||||
loadReactionsBy({ by: { shouts: sss.map((s: Shout) => s.slug) } })
|
||||
|
@ -107,15 +106,15 @@ export const FeedView = (props: FeedProps) => {
|
|||
<Placeholder type={loc?.pathname} mode="feed" />
|
||||
</Show>
|
||||
|
||||
<Show when={(session() || loc?.pathname === 'feed') && feed()?.length}>
|
||||
<Show when={(session() || loc?.pathname === 'feed') && props.shouts?.length}>
|
||||
<div class={styles.filtersContainer}>
|
||||
<ul class={clsx('view-switcher', styles.feedFilter)}>
|
||||
<li class={clsx({ 'view-switcher__item--selected': !props.mode })}>
|
||||
<li class={clsx({ 'view-switcher__item--selected': !props.order })}>
|
||||
<A href={loc.pathname}>{t('Recent')}</A>
|
||||
</li>
|
||||
<li
|
||||
class={clsx({
|
||||
'view-switcher__item--selected': props.mode === 'likes'
|
||||
'view-switcher__item--selected': props.order === 'likes'
|
||||
})}
|
||||
>
|
||||
<A class="link" href={'/feed/likes'}>
|
||||
|
@ -124,7 +123,7 @@ export const FeedView = (props: FeedProps) => {
|
|||
</li>
|
||||
<li
|
||||
class={clsx({
|
||||
'view-switcher__item--selected': props.mode === 'hot'
|
||||
'view-switcher__item--selected': props.order === 'hot'
|
||||
})}
|
||||
>
|
||||
<A class="link" href={'/feed/hot'}>
|
||||
|
@ -153,8 +152,8 @@ export const FeedView = (props: FeedProps) => {
|
|||
</div>
|
||||
|
||||
<Show when={!isLoading()} fallback={<Loading />}>
|
||||
<Show when={(feed() || []).length > 0}>
|
||||
<For each={(feed() || []).slice(0, 4)}>
|
||||
<Show when={(props.shouts || []).length > 0}>
|
||||
<For each={(props.shouts || []).slice(0, 4)}>
|
||||
{(article) => (
|
||||
<ArticleCard
|
||||
onShare={(shared) => handleShare(shared)}
|
||||
|
@ -186,7 +185,7 @@ export const FeedView = (props: FeedProps) => {
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<For each={(feed() || []).slice(4)}>
|
||||
<For each={(props.shouts || []).slice(4)}>
|
||||
{(article) => (
|
||||
<ArticleCard article={article} settings={{ isFeedMode: true }} desktopCoverSize="M" />
|
||||
)}
|
||||
|
|
|
@ -113,7 +113,7 @@ export default function HomePage(props: RouteSectionProps<HomeViewProps>) {
|
|||
<Show when={(featuredFeed() || []).length > 0} fallback={<Loading />}>
|
||||
<LoadMoreWrapper loadFunction={loadMoreFeatured} pageSize={SHOUTS_PER_PAGE}>
|
||||
<HomeView
|
||||
featuredShouts={featuredFeed() || shouts() as Shout[]}
|
||||
featuredShouts={featuredFeed() || (shouts() as Shout[])}
|
||||
topMonthShouts={topMonthFeed() as Shout[]}
|
||||
topViewedShouts={topViewedFeed() as Shout[]}
|
||||
topRatedShouts={topRatedFeed() as Shout[]}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { RouteSectionProps, createAsync, useSearchParams } from '@solidjs/router'
|
||||
import { Client } from '@urql/core'
|
||||
import { createEffect } from 'solid-js'
|
||||
import { createEffect, createMemo } from 'solid-js'
|
||||
import { AUTHORS_PER_PAGE } from '~/components/Views/AllAuthors/AllAuthors'
|
||||
import { Feed } from '~/components/Views/Feed'
|
||||
import { FeedProps } from '~/components/Views/Feed/Feed'
|
||||
import { LoadMoreItems, LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper'
|
||||
import { PageLayout } from '~/components/_shared/PageLayout'
|
||||
import { useFeed } from '~/context/feed'
|
||||
|
@ -60,7 +61,7 @@ export const route = {
|
|||
export default (props: RouteSectionProps<{ shouts: Shout[]; topics: Topic[] }>) => {
|
||||
const [searchParams] = useSearchParams<FeedSearchParams>() // ?period=month
|
||||
const { t } = useLocalize()
|
||||
const { setFeed } = useFeed()
|
||||
const { feed, setFeed } = useFeed()
|
||||
|
||||
// preload all topics
|
||||
const { addTopics, sortedTopics } = useTopics()
|
||||
|
@ -106,6 +107,17 @@ export default (props: RouteSectionProps<{ shouts: Shout[]; topics: Topic[] }>)
|
|||
return (await loadMoreFeed()) as Shout[]
|
||||
})
|
||||
|
||||
const order = createMemo(() => {
|
||||
const paramOrderPattern = /^(hot|likes)$/
|
||||
return (
|
||||
(paramOrderPattern.test(props.params.order)
|
||||
? props.params.order === 'hot'
|
||||
? 'last_comment'
|
||||
: props.params.order
|
||||
: 'created_at') || 'created_at'
|
||||
)
|
||||
})
|
||||
|
||||
return (
|
||||
<PageLayout
|
||||
withPadding={true}
|
||||
|
@ -115,7 +127,7 @@ export default (props: RouteSectionProps<{ shouts: Shout[]; topics: Topic[] }>)
|
|||
>
|
||||
<LoadMoreWrapper loadFunction={loadMoreFeed} pageSize={AUTHORS_PER_PAGE}>
|
||||
<ReactionsProvider>
|
||||
<Feed />
|
||||
<Feed shouts={feed() || (shouts() as Shout[])} order={order() as FeedProps['order']} />
|
||||
</ReactionsProvider>
|
||||
</LoadMoreWrapper>
|
||||
</PageLayout>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { RouteSectionProps, useSearchParams } from '@solidjs/router'
|
||||
import { createEffect } from 'solid-js'
|
||||
import { createEffect, createMemo } from 'solid-js'
|
||||
import { AUTHORS_PER_PAGE } from '~/components/Views/AllAuthors/AllAuthors'
|
||||
import { Feed } from '~/components/Views/Feed'
|
||||
import { FeedProps } from '~/components/Views/Feed/Feed'
|
||||
import { LoadMoreItems, LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper'
|
||||
import { PageLayout } from '~/components/_shared/PageLayout'
|
||||
import { useFeed } from '~/context/feed'
|
||||
|
@ -52,7 +53,7 @@ const getFromDate = (period: FeedPeriod): number => {
|
|||
export default (props: RouteSectionProps<{ shouts: Shout[]; topics: Topic[] }>) => {
|
||||
const [searchParams] = useSearchParams<FeedSearchParams>() // ?period=month
|
||||
const { t } = useLocalize()
|
||||
const { setFeed } = useFeed()
|
||||
const { setFeed, feed } = useFeed()
|
||||
// TODO: use const { requireAuthentication } = useSession()
|
||||
const client = useGraphQL()
|
||||
|
||||
|
@ -62,27 +63,32 @@ export default (props: RouteSectionProps<{ shouts: Shout[]; topics: Topic[] }>)
|
|||
!sortedTopics() && props.data.topics && addTopics(props.data.topics)
|
||||
})
|
||||
|
||||
// load more my feed
|
||||
const loadMoreMyFeed = async (offset?: number) => {
|
||||
// /feed/my/:mode:
|
||||
// /feed/my/:mode:
|
||||
const mode = createMemo(() => {
|
||||
const paramModePattern = /^(followed|discussed|liked|coauthored|unrated)$/
|
||||
const mode =
|
||||
props.params.mode && paramModePattern.test(props.params.mode) ? props.params.mode : 'followed'
|
||||
const gqlHandler = feeds[mode as keyof typeof feeds]
|
||||
return props.params.mode && paramModePattern.test(props.params.mode) ? props.params.mode : 'followed'
|
||||
})
|
||||
|
||||
// /feed/my/:mode:/:order: - select order setting
|
||||
const order = createMemo(() => {
|
||||
const paramOrderPattern = /^(hot|likes)$/
|
||||
const order =
|
||||
return (
|
||||
(paramOrderPattern.test(props.params.order)
|
||||
? props.params.order === 'hot'
|
||||
? 'last_comment'
|
||||
: props.params.order
|
||||
: 'created_at') || 'created_at'
|
||||
)
|
||||
})
|
||||
|
||||
// load more my feed
|
||||
const loadMoreMyFeed = async (offset?: number) => {
|
||||
const gqlHandler = feeds[mode() as keyof typeof feeds]
|
||||
|
||||
// /feed/my/:mode:/:order: - select order setting
|
||||
const options: LoadShoutsOptions = {
|
||||
limit: 20,
|
||||
offset,
|
||||
order_by: order
|
||||
order_by: order()
|
||||
}
|
||||
|
||||
// ?period=month - time period filter
|
||||
|
@ -106,7 +112,11 @@ export default (props: RouteSectionProps<{ shouts: Shout[]; topics: Topic[] }>)
|
|||
>
|
||||
<LoadMoreWrapper loadFunction={loadMoreMyFeed} pageSize={AUTHORS_PER_PAGE}>
|
||||
<ReactionsProvider>
|
||||
<Feed />
|
||||
<Feed
|
||||
shouts={feed() || []}
|
||||
mode={(mode() || 'followed') as FeedProps['mode']}
|
||||
order={order() as FeedProps['order']}
|
||||
/>
|
||||
</ReactionsProvider>
|
||||
</LoadMoreWrapper>
|
||||
</PageLayout>
|
||||
|
|
Loading…
Reference in New Issue
Block a user