load-wrapper-debug

This commit is contained in:
Untone 2024-07-15 19:51:52 +03:00
parent 789a7497a3
commit f6f012449d
5 changed files with 55 additions and 22 deletions

View File

@ -1,6 +1,6 @@
import { A, createAsync, useLocation, useNavigate, useSearchParams } from '@solidjs/router' import { A, createAsync, useLocation, useNavigate, useSearchParams } from '@solidjs/router'
import { clsx } from 'clsx' import { clsx } from 'clsx'
import { For, Show, createEffect, createMemo, createSignal, on } from 'solid-js' import { For, Show, createEffect, createMemo, createSignal, on, onMount } from 'solid-js'
import { DropDown } from '~/components/_shared/DropDown' import { DropDown } from '~/components/_shared/DropDown'
import { Option } from '~/components/_shared/DropDown/DropDown' import { Option } from '~/components/_shared/DropDown/DropDown'
import { Icon } from '~/components/_shared/Icon' import { Icon } from '~/components/_shared/Icon'
@ -8,6 +8,7 @@ import { InviteMembers } from '~/components/_shared/InviteMembers'
import { Loading } from '~/components/_shared/Loading' import { Loading } from '~/components/_shared/Loading'
import { ShareModal } from '~/components/_shared/ShareModal' import { ShareModal } from '~/components/_shared/ShareModal'
import { useAuthors } from '~/context/authors' import { useAuthors } from '~/context/authors'
import { useFeed } from '~/context/feed'
import { useGraphQL } from '~/context/graphql' import { useGraphQL } from '~/context/graphql'
import { useLocalize } from '~/context/localize' import { useLocalize } from '~/context/localize'
import { useReactions } from '~/context/reactions' import { useReactions } from '~/context/reactions'
@ -32,8 +33,9 @@ import styles from './Feed.module.scss'
export const FEED_PAGE_SIZE = 20 export const FEED_PAGE_SIZE = 20
export type PeriodType = 'week' | 'month' | 'year' export type PeriodType = 'week' | 'month' | 'year'
export type FeedProps = { export type FeedProps = {
shouts: Shout[] shouts?: Shout[]
} }
export const FeedView = (props: FeedProps) => { export const FeedView = (props: FeedProps) => {
@ -51,6 +53,7 @@ export const FeedView = (props: FeedProps) => {
const [isLoading, setIsLoading] = createSignal(false) const [isLoading, setIsLoading] = createSignal(false)
const [isRightColumnLoaded, setIsRightColumnLoaded] = createSignal(false) const [isRightColumnLoaded, setIsRightColumnLoaded] = createSignal(false)
const { session } = useSession() const { session } = useSession()
const { nonfeaturedFeed, setNonFeaturedFeed } = useFeed()
const { loadReactionsBy } = useReactions() const { loadReactionsBy } = useReactions()
const { topTopics } = useTopics() const { topTopics } = useTopics()
const { topAuthors } = useAuthors() const { topAuthors } = useAuthors()
@ -64,16 +67,25 @@ export const FeedView = (props: FeedProps) => {
setTopComments(comments.sort(byCreated).reverse()) setTopComments(comments.sort(byCreated).reverse())
} }
onMount(
() =>
props.shouts &&
Array.isArray(props.shouts) &&
setNonFeaturedFeed((prev) => [...prev, ...(props.shouts || [])]) && console.info(nonfeaturedFeed())
)
createEffect( createEffect(
on( on(
() => props.shouts, () => nonfeaturedFeed(),
(sss: Shout[]) => { (sss?: Shout[]) => {
if (sss) { if (sss && Array.isArray(sss)) {
setIsLoading(true) setIsLoading(true)
setNonFeaturedFeed((prev) => [...prev, ...sss])
Promise.all([ Promise.all([
loadTopComments(), loadTopComments(),
loadReactionsBy({ by: { shouts: sss.map((s: Shout) => s.slug) } }) loadReactionsBy({ by: { shouts: sss.map((s: Shout) => s.slug) } })
]).finally(() => { ]).finally(() => {
console.debug('[views.feed] finally loaded reactions, data loading finished')
setIsRightColumnLoaded(true) setIsRightColumnLoaded(true)
setIsLoading(false) setIsLoading(false)
}) })
@ -101,7 +113,7 @@ export const FeedView = (props: FeedProps) => {
<Placeholder type={loc?.pathname} mode="feed" /> <Placeholder type={loc?.pathname} mode="feed" />
</Show> </Show>
<Show when={(session() || loc?.pathname === 'feed') && props.shouts.length}> <Show when={(session() || loc?.pathname === 'feed') && nonfeaturedFeed()?.length}>
<div class={styles.filtersContainer}> <div class={styles.filtersContainer}>
<ul class={clsx('view-switcher', styles.feedFilter)}> <ul class={clsx('view-switcher', styles.feedFilter)}>
<li <li
@ -154,8 +166,8 @@ export const FeedView = (props: FeedProps) => {
</div> </div>
<Show when={!isLoading()} fallback={<Loading />}> <Show when={!isLoading()} fallback={<Loading />}>
<Show when={props.shouts.length > 0}> <Show when={(nonfeaturedFeed() || []).length > 0}>
<For each={props.shouts.slice(0, 4)}> <For each={(nonfeaturedFeed() || []).slice(0, 4)}>
{(article) => ( {(article) => (
<ArticleCard <ArticleCard
onShare={(shared) => handleShare(shared)} onShare={(shared) => handleShare(shared)}
@ -187,7 +199,7 @@ export const FeedView = (props: FeedProps) => {
</ul> </ul>
</div> </div>
<For each={props.shouts.slice(4)}> <For each={(nonfeaturedFeed() || []).slice(4)}>
{(article) => ( {(article) => (
<ArticleCard article={article} settings={{ isFeedMode: true }} desktopCoverSize="M" /> <ArticleCard article={article} settings={{ isFeedMode: true }} desktopCoverSize="M" />
)} )}

View File

@ -24,9 +24,10 @@ export const LoadMoreWrapper = (props: LoadMoreProps) => {
saveScrollPosition() saveScrollPosition()
const newItems = await props.loadFunction(offset()) const newItems = await props.loadFunction(offset())
if (!Array.isArray(newItems)) return if (!Array.isArray(newItems)) return
console.debug('[_share] load more items', newItems)
setItems((prev) => [...prev, ...newItems]) setItems((prev) => [...prev, ...newItems])
setOffset((prev) => prev + props.pageSize) setOffset((prev) => prev + props.pageSize)
setIsLoadMoreButtonVisible(newItems.length >= props.pageSize) setIsLoadMoreButtonVisible(newItems.length >= props.pageSize - 1)
setIsLoading(false) setIsLoading(false)
restoreScrollPosition() restoreScrollPosition()
} }

View File

@ -18,8 +18,6 @@ export const PRERENDERED_ARTICLES_COUNT = 5
type FeedContextType = { type FeedContextType = {
sortedFeed: Accessor<Shout[]> sortedFeed: Accessor<Shout[]>
articleEntities: Accessor<{ [articleSlug: string]: Shout }> articleEntities: Accessor<{ [articleSlug: string]: Shout }>
topFeed: Accessor<Shout[]>
topMonthFeed: Accessor<Shout[]>
feedByAuthor: Accessor<{ [authorSlug: string]: Shout[] }> feedByAuthor: Accessor<{ [authorSlug: string]: Shout[] }>
feedByTopic: Accessor<{ [topicSlug: string]: Shout[] }> feedByTopic: Accessor<{ [topicSlug: string]: Shout[] }>
feedByLayout: Accessor<{ [layout: string]: Shout[] }> feedByLayout: Accessor<{ [layout: string]: Shout[] }>
@ -33,12 +31,26 @@ type FeedContextType = {
options: QueryLoad_Shouts_SearchArgs options: QueryLoad_Shouts_SearchArgs
) => Promise<{ hasMore: boolean; newShouts: Shout[] }> ) => Promise<{ hasMore: boolean; newShouts: Shout[] }>
resetSortedFeed: () => void resetSortedFeed: () => void
loadTopMonthFeed: () => Promise<void>
loadTopFeed: () => Promise<void>
seen: Accessor<{ [slug: string]: number }> seen: Accessor<{ [slug: string]: number }>
addSeen: (slug: string) => void addSeen: (slug: string) => void
// featured
nonfeaturedFeed: Accessor<Shout[] | undefined>
setNonFeaturedFeed: Setter<Shout[]>
// featured
featuredFeed: Accessor<Shout[] | undefined> featuredFeed: Accessor<Shout[] | undefined>
setFeaturedFeed: Setter<Shout[]> setFeaturedFeed: Setter<Shout[]>
// top month
loadTopMonthFeed: () => Promise<void>
topMonthFeed: Accessor<Shout[]>
// top rated
loadTopFeed: () => Promise<void>
topFeed: Accessor<Shout[]>
// expo
expoFeed: Accessor<Shout[] | undefined> expoFeed: Accessor<Shout[] | undefined>
setExpoFeed: Setter<Shout[]> setExpoFeed: Setter<Shout[]>
} }
@ -50,6 +62,7 @@ export const useFeed = () => useContext(FeedContext)
export const FeedProvider = (props: { children: JSX.Element }) => { export const FeedProvider = (props: { children: JSX.Element }) => {
const [sortedFeed, setSortedFeed] = createSignal<Shout[]>([]) const [sortedFeed, setSortedFeed] = createSignal<Shout[]>([])
const [articleEntities, setArticleEntities] = createSignal<{ [articleSlug: string]: Shout }>({}) const [articleEntities, setArticleEntities] = createSignal<{ [articleSlug: string]: Shout }>({})
const [nonfeaturedFeed, setNonFeaturedFeed] = createSignal<Shout[]>([])
const [featuredFeed, setFeaturedFeed] = createSignal<Shout[]>([]) const [featuredFeed, setFeaturedFeed] = createSignal<Shout[]>([])
const [expoFeed, setExpoFeed] = createSignal<Shout[]>([]) const [expoFeed, setExpoFeed] = createSignal<Shout[]>([])
const [topFeed, setTopFeed] = createSignal<Shout[]>([]) const [topFeed, setTopFeed] = createSignal<Shout[]>([])
@ -246,7 +259,9 @@ export const FeedProvider = (props: { children: JSX.Element }) => {
featuredFeed, featuredFeed,
setFeaturedFeed, setFeaturedFeed,
expoFeed, expoFeed,
setExpoFeed setExpoFeed,
nonfeaturedFeed,
setNonFeaturedFeed
}} }}
> >
{props.children} {props.children}

View File

@ -52,11 +52,10 @@ const fetchHomeTopData = async () => {
order_by: 'likes_stat', order_by: 'likes_stat',
limit: 10 limit: 10
}) })
return { const topRatedShouts = await topRatedLoader()
topRatedShouts: await topRatedLoader(), const topMonthShouts = await topMonthLoader()
topMonthShouts: await topMonthLoader(), const topCommentedShouts = await topCommentedLoader()
topCommentedShouts: await topCommentedLoader() return { topCommentedShouts, topMonthShouts, topRatedShouts } as Partial<HomeViewProps>
} as Partial<HomeViewProps>
} }
export const route = { export const route = {
@ -91,6 +90,7 @@ export default function HomePage(props: RouteSectionProps<HomeViewProps>) {
const offset = prev?.featuredShouts?.length || 0 const offset = prev?.featuredShouts?.length || 0
const featuredShoutsLoader = featuredLoader(offset) const featuredShoutsLoader = featuredLoader(offset)
const loaded = await featuredShoutsLoader() const loaded = await featuredShoutsLoader()
setFeaturedFeed((prev) => [...prev, ...loaded||[]])
const featuredShouts = [ const featuredShouts = [
...(prev?.featuredShouts || []), ...(prev?.featuredShouts || []),
...(loaded || props.data?.featuredShouts || []) ...(loaded || props.data?.featuredShouts || [])

View File

@ -5,6 +5,7 @@ import { AUTHORS_PER_PAGE } from '~/components/Views/AllAuthors/AllAuthors'
import { Feed } from '~/components/Views/Feed' import { Feed } from '~/components/Views/Feed'
import { LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper' import { LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper'
import { PageLayout } from '~/components/_shared/PageLayout' import { PageLayout } from '~/components/_shared/PageLayout'
import { useFeed } from '~/context/feed'
import { useLocalize } from '~/context/localize' import { useLocalize } from '~/context/localize'
import { ReactionsProvider } from '~/context/reactions' import { ReactionsProvider } from '~/context/reactions'
import { loadShouts } from '~/graphql/api/public' import { loadShouts } from '~/graphql/api/public'
@ -59,8 +60,8 @@ export const route = {
export default (props: RouteSectionProps<Shout[]>) => { export default (props: RouteSectionProps<Shout[]>) => {
const [searchParams] = useSearchParams<FeedSearchParams>() const [searchParams] = useSearchParams<FeedSearchParams>()
const { t } = useLocalize() const { t } = useLocalize()
const {setNonFeaturedFeed} = useFeed()
const [offset, setOffset] = createSignal<number>(0) const [offset, setOffset] = createSignal<number>(0)
const shouts = createAsync(async () => ({ ...props.data }) || (await loadMore()))
const loadMore = async () => { const loadMore = async () => {
const newOffset = offset() + SHOUTS_PER_PAGE const newOffset = offset() + SHOUTS_PER_PAGE
setOffset(newOffset) setOffset(newOffset)
@ -74,8 +75,12 @@ export default (props: RouteSectionProps<Shout[]>) => {
const period = searchParams?.by || 'month' const period = searchParams?.by || 'month'
options.filters = { after: getFromDate(period as FeedPeriod) } options.filters = { after: getFromDate(period as FeedPeriod) }
} }
return await fetchPublishedShouts(newOffset) const result = await fetchPublishedShouts(newOffset)
result && setNonFeaturedFeed(result)
return
} }
const shouts = createAsync(async () => props.data || await loadMore())
return ( return (
<PageLayout <PageLayout
withPadding={true} withPadding={true}