2024-07-18 09:22:28 +00:00
|
|
|
import { RouteSectionProps } from '@solidjs/router'
|
|
|
|
import { ErrorBoundary, createEffect, createMemo, createSignal, on } from 'solid-js'
|
2024-07-12 12:10:22 +00:00
|
|
|
import { AuthorView } from '~/components/Views/Author'
|
|
|
|
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
2024-07-16 00:14:08 +00:00
|
|
|
import { LoadMoreItems, LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper'
|
2024-07-12 12:10:22 +00:00
|
|
|
import { PageLayout } from '~/components/_shared/PageLayout'
|
|
|
|
import { useAuthors } from '~/context/authors'
|
2024-07-16 00:14:08 +00:00
|
|
|
import { useFeed } from '~/context/feed'
|
2024-07-12 12:10:22 +00:00
|
|
|
import { useLocalize } from '~/context/localize'
|
2024-07-16 00:14:08 +00:00
|
|
|
import { ReactionsProvider, useReactions } from '~/context/reactions'
|
|
|
|
import { loadAuthors, loadReactions, loadShouts, loadTopics } from '~/graphql/api/public'
|
2024-07-12 12:10:22 +00:00
|
|
|
import {
|
|
|
|
Author,
|
|
|
|
LoadShoutsOptions,
|
|
|
|
QueryLoad_Authors_ByArgs,
|
2024-07-18 09:22:28 +00:00
|
|
|
QueryLoad_Reactions_ByArgs,
|
|
|
|
Reaction,
|
|
|
|
ReactionKind,
|
2024-07-12 12:10:22 +00:00
|
|
|
Shout,
|
|
|
|
Topic
|
|
|
|
} from '~/graphql/schema/core.gen'
|
2024-07-13 12:25:25 +00:00
|
|
|
import { getImageUrl } from '~/lib/getThumbUrl'
|
2024-07-13 09:06:49 +00:00
|
|
|
import { SHOUTS_PER_PAGE } from '../../(main)'
|
2024-07-12 12:10:22 +00:00
|
|
|
|
|
|
|
const fetchAuthorShouts = async (slug: string, offset?: number) => {
|
|
|
|
const opts: LoadShoutsOptions = { filters: { author: slug }, limit: SHOUTS_PER_PAGE, offset }
|
|
|
|
const shoutsLoader = loadShouts(opts)
|
|
|
|
return await shoutsLoader()
|
|
|
|
}
|
|
|
|
|
2024-07-18 09:22:28 +00:00
|
|
|
const fetchAuthorComments = async (slug: string, offset?: number) => {
|
|
|
|
const opts: QueryLoad_Reactions_ByArgs = {
|
|
|
|
by: { comment: true, author: slug },
|
|
|
|
limit: SHOUTS_PER_PAGE,
|
|
|
|
offset
|
|
|
|
}
|
|
|
|
const shoutsLoader = loadReactions(opts)
|
|
|
|
return await shoutsLoader()
|
|
|
|
}
|
|
|
|
|
2024-07-12 12:10:22 +00:00
|
|
|
const fetchAllTopics = async () => {
|
|
|
|
const topicsFetcher = loadTopics()
|
|
|
|
return await topicsFetcher()
|
|
|
|
}
|
|
|
|
|
|
|
|
const fetchAuthor = async (slug: string) => {
|
2024-07-13 07:01:41 +00:00
|
|
|
const authorFetcher = loadAuthors({ by: { slug }, limit: 1, offset: 0 } as QueryLoad_Authors_ByArgs)
|
2024-07-12 12:10:22 +00:00
|
|
|
const aaa = await authorFetcher()
|
|
|
|
return aaa?.[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
export const route = {
|
|
|
|
load: async ({ params, location: { query } }: RouteSectionProps<{ articles: Shout[] }>) => {
|
|
|
|
const offset: number = Number.parseInt(query.offset, 10)
|
|
|
|
return {
|
|
|
|
author: await fetchAuthor(params.slug),
|
2024-07-16 00:14:08 +00:00
|
|
|
shouts: await fetchAuthorShouts(params.slug, offset),
|
2024-07-12 12:10:22 +00:00
|
|
|
topics: await fetchAllTopics()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-13 09:06:49 +00:00
|
|
|
export type AuthorPageProps = { articles?: Shout[]; author?: Author; topics?: Topic[] }
|
|
|
|
|
2024-07-13 09:45:10 +00:00
|
|
|
export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
2024-07-16 00:14:08 +00:00
|
|
|
const { addAuthor, authorsEntities } = useAuthors()
|
2024-07-18 09:22:28 +00:00
|
|
|
const [author, setAuthor] = createSignal<Author | undefined>(undefined)
|
2024-07-16 00:14:08 +00:00
|
|
|
|
2024-07-12 12:10:22 +00:00
|
|
|
const { t } = useLocalize()
|
|
|
|
const title = createMemo(() => `${author()?.name || ''}`)
|
|
|
|
|
|
|
|
createEffect(() => {
|
|
|
|
if (author()) {
|
|
|
|
console.debug('[routes] author/[slug] author loaded fx')
|
|
|
|
window?.gtag?.('event', 'page_view', {
|
|
|
|
page_title: author()?.name || '',
|
|
|
|
page_location: window?.location.href || '',
|
|
|
|
page_path: window?.location.pathname || ''
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
const cover = createMemo(() =>
|
|
|
|
author()?.pic
|
|
|
|
? getImageUrl(author()?.pic || '', { width: 1200 })
|
|
|
|
: getImageUrl('production/image/logo_image.png')
|
|
|
|
)
|
2024-07-13 07:01:41 +00:00
|
|
|
|
2024-07-18 09:22:28 +00:00
|
|
|
// author comments
|
|
|
|
const { addReactions, reactionEntities } = useReactions()
|
|
|
|
const commentsByAuthor = createMemo(() =>
|
|
|
|
Object.values(reactionEntities).filter(
|
|
|
|
(r: Reaction) => r.kind === ReactionKind.Comment && r.created_by.id === author()?.id
|
|
|
|
)
|
|
|
|
)
|
|
|
|
// author shouts
|
2024-07-16 00:14:08 +00:00
|
|
|
const { addFeed, feedByAuthor } = useFeed()
|
2024-07-18 09:22:28 +00:00
|
|
|
const shoutsByAuthor = createMemo(() => feedByAuthor()[props.params.slug])
|
|
|
|
|
|
|
|
createEffect(
|
|
|
|
on(
|
|
|
|
[() => props.params.slug || '', author],
|
|
|
|
async ([slug, profile]) => {
|
|
|
|
if (!profile) {
|
|
|
|
const loadedAuthor = authorsEntities()[slug] || (await fetchAuthor(slug))
|
|
|
|
if (loadedAuthor) {
|
|
|
|
addAuthor(loadedAuthor)
|
|
|
|
setAuthor(loadedAuthor)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ defer: true }
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
const loadAuthorDataMore = async (offset = 0) => {
|
|
|
|
if (props.params.tab === 'comments') {
|
|
|
|
const commentsOffset = commentsByAuthor().length
|
|
|
|
const loadedComments = await fetchAuthorComments(props.params.slug, commentsOffset)
|
|
|
|
loadedComments && addReactions(loadedComments)
|
|
|
|
return (loadedComments || []) as LoadMoreItems
|
|
|
|
}
|
|
|
|
const shoutsOffset = shoutsByAuthor().length
|
|
|
|
const loadedShouts = await fetchAuthorShouts(props.params.slug, shoutsOffset)
|
|
|
|
loadedShouts && addFeed(loadedShouts)
|
|
|
|
return (loadedShouts || []) as LoadMoreItems
|
2024-07-16 00:14:08 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 12:10:22 +00:00
|
|
|
return (
|
|
|
|
<ErrorBoundary fallback={(_err) => <FourOuFourView />}>
|
2024-07-16 00:14:08 +00:00
|
|
|
<PageLayout
|
|
|
|
title={`${t('Discours')} :: ${title()}`}
|
|
|
|
headerTitle={author()?.name || ''}
|
|
|
|
slug={author()?.slug}
|
|
|
|
desc={author()?.about || author()?.bio || ''}
|
|
|
|
cover={cover()}
|
|
|
|
>
|
|
|
|
<ReactionsProvider>
|
|
|
|
<LoadMoreWrapper
|
2024-07-18 09:22:28 +00:00
|
|
|
loadFunction={loadAuthorDataMore}
|
2024-07-16 00:14:08 +00:00
|
|
|
pageSize={SHOUTS_PER_PAGE}
|
2024-07-18 09:22:28 +00:00
|
|
|
hidden={!props.params.tab || props.params.tab !== 'comments'}
|
2024-07-16 00:14:08 +00:00
|
|
|
>
|
2024-07-12 12:10:22 +00:00
|
|
|
<AuthorView
|
|
|
|
author={author() as Author}
|
2024-07-18 09:22:28 +00:00
|
|
|
selectedTab={props.params.tab}
|
2024-07-13 09:36:23 +00:00
|
|
|
authorSlug={props.params.slug}
|
2024-07-18 09:22:28 +00:00
|
|
|
shouts={shoutsByAuthor()}
|
2024-07-12 12:10:22 +00:00
|
|
|
/>
|
2024-07-16 00:14:08 +00:00
|
|
|
</LoadMoreWrapper>
|
|
|
|
</ReactionsProvider>
|
|
|
|
</PageLayout>
|
2024-07-12 12:10:22 +00:00
|
|
|
</ErrorBoundary>
|
|
|
|
)
|
|
|
|
}
|