diff --git a/src/components/Pages/AuthorPage.tsx b/src/components/Pages/AuthorPage.tsx
index 0eab1346..d8d73f6c 100644
--- a/src/components/Pages/AuthorPage.tsx
+++ b/src/components/Pages/AuthorPage.tsx
@@ -1,8 +1,8 @@
import { MainLayout } from '../Layouts/MainLayout'
-import { AuthorView } from '../Views/Author'
+import { AuthorView, PRERENDERED_ARTICLES_COUNT } from '../Views/Author'
import type { PageProps } from '../types'
import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js'
-import { loadArticlesForAuthors, resetSortedArticles } from '../../stores/zine/articles'
+import { loadAuthorArticles, resetSortedArticles } from '../../stores/zine/articles'
import { useRouter } from '../../stores/router'
import { loadAuthor } from '../../stores/zine/authors'
import { Loading } from '../Loading'
@@ -27,7 +27,7 @@ export const AuthorPage = (props: PageProps) => {
return
}
- await loadArticlesForAuthors({ authorSlugs: [slug()] })
+ await loadAuthorArticles({ authorSlug: slug(), limit: PRERENDERED_ARTICLES_COUNT })
await loadAuthor({ slug: slug() })
setIsLoaded(true)
diff --git a/src/components/Pages/FeedPage.tsx b/src/components/Pages/FeedPage.tsx
index 13c18136..7aef8fbf 100644
--- a/src/components/Pages/FeedPage.tsx
+++ b/src/components/Pages/FeedPage.tsx
@@ -1,30 +1,14 @@
import { MainLayout } from '../Layouts/MainLayout'
import { FeedView } from '../Views/Feed'
-import type { PageProps } from '../types'
-import { createSignal, onCleanup, onMount, Show } from 'solid-js'
-import { loadRecentArticles, resetSortedArticles } from '../../stores/zine/articles'
-import { Loading } from '../Loading'
-
-export const FeedPage = (props: PageProps) => {
- const [isLoaded, setIsLoaded] = createSignal(Boolean(props.feedArticles))
-
- onMount(async () => {
- if (isLoaded()) {
- return
- }
-
- await loadRecentArticles({ limit: 50, offset: 0 })
-
- setIsLoaded(true)
- })
+import { onCleanup } from 'solid-js'
+import { resetSortedArticles } from '../../stores/zine/articles'
+export const FeedPage = () => {
onCleanup(() => resetSortedArticles())
return (
- }>
-
-
+
)
}
diff --git a/src/components/Pages/HomePage.tsx b/src/components/Pages/HomePage.tsx
index f8430e03..392280bb 100644
--- a/src/components/Pages/HomePage.tsx
+++ b/src/components/Pages/HomePage.tsx
@@ -1,4 +1,4 @@
-import { HomeView } from '../Views/Home'
+import { HomeView, PRERENDERED_ARTICLES_COUNT } from '../Views/Home'
import { MainLayout } from '../Layouts/MainLayout'
import type { PageProps } from '../types'
import { createSignal, onCleanup, onMount, Show } from 'solid-js'
@@ -14,7 +14,7 @@ export const HomePage = (props: PageProps) => {
return
}
- await loadPublishedArticles({ limit: 5, offset: 0 })
+ await loadPublishedArticles({ limit: PRERENDERED_ARTICLES_COUNT, offset: 0 })
await loadRandomTopics()
setIsLoaded(true)
diff --git a/src/components/Pages/TopicPage.tsx b/src/components/Pages/TopicPage.tsx
index 7cbaa1b5..16e0c95a 100644
--- a/src/components/Pages/TopicPage.tsx
+++ b/src/components/Pages/TopicPage.tsx
@@ -1,8 +1,8 @@
import { MainLayout } from '../Layouts/MainLayout'
-import { TopicView } from '../Views/Topic'
+import { PRERENDERED_ARTICLES_COUNT, TopicView } from '../Views/Topic'
import type { PageProps } from '../types'
import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js'
-import { loadArticlesForTopics, resetSortedArticles } from '../../stores/zine/articles'
+import { loadTopicArticles, resetSortedArticles } from '../../stores/zine/articles'
import { useRouter } from '../../stores/router'
import { loadTopic } from '../../stores/zine/topics'
import { Loading } from '../Loading'
@@ -27,7 +27,7 @@ export const TopicPage = (props: PageProps) => {
return
}
- await loadArticlesForTopics({ topicSlugs: [slug()] })
+ await loadTopicArticles({ topicSlug: slug(), limit: PRERENDERED_ARTICLES_COUNT, offset: 0 })
await loadTopic({ slug: slug() })
setIsLoaded(true)
diff --git a/src/components/Views/Author.tsx b/src/components/Views/Author.tsx
index 4c84b7c5..52cd189f 100644
--- a/src/components/Views/Author.tsx
+++ b/src/components/Views/Author.tsx
@@ -1,17 +1,18 @@
-import { Show, createMemo } from 'solid-js'
+import { Show, createMemo, createSignal, For, onMount } from 'solid-js'
import type { Author, Shout } from '../../graphql/types.gen'
-import Row2 from '../Feed/Row2'
-import Row3 from '../Feed/Row3'
-// import Beside from '../Feed/Beside'
-import AuthorFull from '../Author/Full'
+import { Row2 } from '../Feed/Row2'
+import { Row3 } from '../Feed/Row3'
+import { AuthorFull } from '../Author/Full'
import { t } from '../../utils/intl'
import { useAuthorsStore } from '../../stores/zine/authors'
-import { useArticlesStore } from '../../stores/zine/articles'
+import { loadAuthorArticles, useArticlesStore } from '../../stores/zine/articles'
import '../../styles/Topic.scss'
import { useTopicsStore } from '../../stores/zine/topics'
import { useRouter } from '../../stores/router'
-import Beside from '../Feed/Beside'
+import { Beside } from '../Feed/Beside'
+import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
+import { splitToPages } from '../../utils/splitToPages'
// TODO: load reactions on client
type AuthorProps = {
@@ -26,16 +27,37 @@ type AuthorPageSearchParams = {
by: '' | 'viewed' | 'rating' | 'commented' | 'recent'
}
+export const PRERENDERED_ARTICLES_COUNT = 12
+const LOAD_MORE_PAGE_SIZE = 9 // Row3 + Row3 + Row3
+
export const AuthorView = (props: AuthorProps) => {
const { sortedArticles } = useArticlesStore({
sortedArticles: props.authorArticles
})
const { authorEntities } = useAuthorsStore({ authors: [props.author] })
const { topicsByAuthor } = useTopicsStore()
+ const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
const author = createMemo(() => authorEntities()[props.authorSlug])
const { searchParams, changeSearchParam } = useRouter
()
+ const loadMore = async () => {
+ saveScrollPosition()
+ const { hasMore } = await loadAuthorArticles({
+ authorSlug: author().slug,
+ limit: LOAD_MORE_PAGE_SIZE,
+ offset: sortedArticles().length
+ })
+ setIsLoadMoreButtonVisible(hasMore)
+ restoreScrollPosition()
+ }
+
+ onMount(async () => {
+ if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) {
+ loadMore()
+ }
+ })
+
const title = createMemo(() => {
const m = searchParams().by
if (m === 'viewed') return t('Top viewed')
@@ -44,6 +66,10 @@ export const AuthorView = (props: AuthorProps) => {
return t('Top recent')
})
+ const pages = createMemo(() =>
+ splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE)
+ )
+
return (
{t('Loading')}
}>
@@ -83,31 +109,39 @@ export const AuthorView = (props: AuthorProps) => {
diff --git a/src/components/Views/Feed.tsx b/src/components/Views/Feed.tsx
index af1c07a2..c791331c 100644
--- a/src/components/Views/Feed.tsx
+++ b/src/components/Views/Feed.tsx
@@ -1,5 +1,4 @@
-import { createMemo, For, Show } from 'solid-js'
-import type { Shout, Reaction } from '../../graphql/types.gen'
+import { createMemo, createSignal, For, onMount, Show } from 'solid-js'
import '../../styles/Feed.scss'
import stylesBeside from '../../components/Feed/Beside.module.scss'
import { Icon } from '../Nav/Icon'
@@ -17,11 +16,6 @@ import { useAuthorsStore } from '../../stores/zine/authors'
import { useTopicsStore } from '../../stores/zine/topics'
import { useTopAuthorsStore } from '../../stores/zine/topAuthors'
-interface FeedProps {
- articles: Shout[]
- reactions?: Reaction[]
-}
-
// const AUTHORSHIP_REACTIONS = [
// ReactionKind.Accept,
// ReactionKind.Reject,
@@ -29,9 +23,11 @@ interface FeedProps {
// ReactionKind.Ask
// ]
-export const FeedView = (props: FeedProps) => {
+export const FEED_PAGE_SIZE = 20
+
+export const FeedView = () => {
// state
- const { sortedArticles } = useArticlesStore({ sortedArticles: props.articles })
+ const { sortedArticles } = useArticlesStore()
const reactions = useReactionsStore()
const { sortedAuthors } = useAuthorsStore()
const { topTopics } = useTopicsStore()
@@ -40,6 +36,8 @@ export const FeedView = (props: FeedProps) => {
const topReactions = createMemo(() => sortBy(reactions(), byCreated))
+ const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
+
// const expectingFocus = createMemo