2024-06-24 17:50:27 +00:00
|
|
|
|
import { Meta, Title } from '@solidjs/meta'
|
|
|
|
|
import { A, useLocation, useMatch } from '@solidjs/router'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
import { clsx } from 'clsx'
|
2024-03-15 14:57:03 +00:00
|
|
|
|
import { For, Match, Show, Switch, createEffect, createMemo, createSignal, on, onMount } from 'solid-js'
|
2024-06-24 17:50:27 +00:00
|
|
|
|
import { useAuthors } from '~/context/authors'
|
|
|
|
|
import { useGraphQL } from '~/context/graphql'
|
|
|
|
|
import { useUI } from '~/context/ui'
|
|
|
|
|
import { useFeed } from '../../../context/feed'
|
2024-01-31 17:38:00 +00:00
|
|
|
|
import { useFollowing } from '../../../context/following'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
import { useLocalize } from '../../../context/localize'
|
2024-04-15 18:01:00 +00:00
|
|
|
|
import { useSession } from '../../../context/session'
|
2024-06-24 17:50:27 +00:00
|
|
|
|
import loadShoutsQuery from '../../../graphql/query/core/articles-load-by'
|
|
|
|
|
import getAuthorFollowersQuery from '../../../graphql/query/core/author-followers'
|
|
|
|
|
import getAuthorFollowsQuery from '../../../graphql/query/core/author-follows'
|
|
|
|
|
import loadReactionsBy from '../../../graphql/query/core/reactions-load-by'
|
2024-06-06 05:44:59 +00:00
|
|
|
|
import type { Author, Reaction, Shout, Topic } from '../../../graphql/schema/core.gen'
|
2023-12-13 10:39:31 +00:00
|
|
|
|
import { getImageUrl } from '../../../utils/getImageUrl'
|
|
|
|
|
import { getDescription } from '../../../utils/meta'
|
2023-05-17 10:41:50 +00:00
|
|
|
|
import { restoreScrollPosition, saveScrollPosition } from '../../../utils/scroll'
|
2024-06-06 05:44:59 +00:00
|
|
|
|
import { byCreated } from '../../../utils/sortby'
|
2023-05-17 10:41:50 +00:00
|
|
|
|
import { splitToPages } from '../../../utils/splitToPages'
|
2024-06-06 05:44:59 +00:00
|
|
|
|
import stylesArticle from '../../Article/Article.module.scss'
|
2023-05-17 10:41:50 +00:00
|
|
|
|
import { Comment } from '../../Article/Comment'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
import { AuthorCard } from '../../Author/AuthorCard'
|
2023-12-27 23:35:43 +00:00
|
|
|
|
import { AuthorShoutsRating } from '../../Author/AuthorShoutsRating'
|
2024-06-06 05:44:59 +00:00
|
|
|
|
import { Placeholder } from '../../Feed/Placeholder'
|
2023-11-14 15:10:00 +00:00
|
|
|
|
import { Row1 } from '../../Feed/Row1'
|
|
|
|
|
import { Row2 } from '../../Feed/Row2'
|
|
|
|
|
import { Row3 } from '../../Feed/Row3'
|
2024-02-04 11:25:21 +00:00
|
|
|
|
import { Loading } from '../../_shared/Loading'
|
|
|
|
|
import styles from './Author.module.scss'
|
2022-09-09 11:53:35 +00:00
|
|
|
|
|
2023-09-09 12:04:46 +00:00
|
|
|
|
type Props = {
|
2022-10-05 15:11:14 +00:00
|
|
|
|
authorSlug: string
|
2024-04-15 18:01:00 +00:00
|
|
|
|
shouts?: Shout[]
|
|
|
|
|
author?: Author
|
2022-09-22 09:37:49 +00:00
|
|
|
|
}
|
2024-06-06 05:44:59 +00:00
|
|
|
|
|
2022-10-28 21:21:47 +00:00
|
|
|
|
export const PRERENDERED_ARTICLES_COUNT = 12
|
2023-02-17 09:21:02 +00:00
|
|
|
|
const LOAD_MORE_PAGE_SIZE = 9
|
2022-10-28 21:21:47 +00:00
|
|
|
|
|
2023-09-09 12:04:46 +00:00
|
|
|
|
export const AuthorView = (props: Props) => {
|
2023-02-17 09:21:02 +00:00
|
|
|
|
const { t } = useLocalize()
|
2024-05-20 11:16:54 +00:00
|
|
|
|
const { followers: myFollowers, follows: myFollows } = useFollowing()
|
2024-06-24 17:50:27 +00:00
|
|
|
|
const { session } = useSession()
|
|
|
|
|
const me = createMemo<Author>(() => session()?.user?.app_data?.profile as Author)
|
|
|
|
|
const [slug, setSlug] = createSignal(props.authorSlug)
|
|
|
|
|
const { sortedFeed } = useFeed()
|
|
|
|
|
const { modal, hideModal } = useUI()
|
|
|
|
|
const loc = useLocation()
|
|
|
|
|
const matchAuthor = useMatch(() => '/author')
|
|
|
|
|
const matchComments = useMatch(() => '/author/:authorId/comments')
|
|
|
|
|
const matchAbout = useMatch(() => '/author/:authorId/about')
|
2022-10-28 21:21:47 +00:00
|
|
|
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
2023-09-06 22:58:54 +00:00
|
|
|
|
const [isBioExpanded, setIsBioExpanded] = createSignal(false)
|
2024-06-24 17:50:27 +00:00
|
|
|
|
const { loadAuthor, authorsEntities } = useAuthors()
|
|
|
|
|
const [author, setAuthor] = createSignal<Author>()
|
|
|
|
|
const [followers, setFollowers] = createSignal<Author[]>([] as Author[])
|
|
|
|
|
const [following, changeFollowing] = createSignal<Array<Author | Topic>>([] as Array<Author | Topic>) // flat AuthorFollowsResult
|
2023-09-06 22:58:54 +00:00
|
|
|
|
const [showExpandBioControl, setShowExpandBioControl] = createSignal(false)
|
2024-02-03 09:23:44 +00:00
|
|
|
|
const [commented, setCommented] = createSignal<Reaction[]>()
|
2024-06-24 17:50:27 +00:00
|
|
|
|
const { query } = useGraphQL()
|
2023-12-25 06:52:04 +00:00
|
|
|
|
|
2024-05-20 23:15:52 +00:00
|
|
|
|
// пагинация загрузки ленты постов
|
2022-10-28 21:21:47 +00:00
|
|
|
|
const loadMore = async () => {
|
|
|
|
|
saveScrollPosition()
|
2024-06-24 17:50:27 +00:00
|
|
|
|
const resp = await query(loadShoutsQuery, {
|
2023-04-20 14:01:15 +00:00
|
|
|
|
filters: { author: props.authorSlug },
|
2022-10-28 21:21:47 +00:00
|
|
|
|
limit: LOAD_MORE_PAGE_SIZE,
|
2024-06-26 08:22:05 +00:00
|
|
|
|
offset: sortedFeed().length
|
2022-10-28 21:21:47 +00:00
|
|
|
|
})
|
2024-06-24 17:50:27 +00:00
|
|
|
|
const hasMore = resp?.data?.load_shouts_by?.hasMore
|
2022-10-28 21:21:47 +00:00
|
|
|
|
setIsLoadMoreButtonVisible(hasMore)
|
|
|
|
|
restoreScrollPosition()
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
|
// 1 // проверяет не собственный ли это профиль, иначе - загружает
|
2024-05-20 23:15:52 +00:00
|
|
|
|
const [isFetching, setIsFetching] = createSignal(false)
|
|
|
|
|
createEffect(
|
2024-06-24 17:50:27 +00:00
|
|
|
|
on([() => session()?.user?.app_data?.profile, () => props.authorSlug || ''], async ([me, s]) => {
|
|
|
|
|
const my = s && me?.slug === s
|
2024-05-20 23:15:52 +00:00
|
|
|
|
if (my) {
|
|
|
|
|
console.debug('[Author] my profile precached')
|
2024-06-24 17:50:27 +00:00
|
|
|
|
if (me) {
|
|
|
|
|
setAuthor(me)
|
|
|
|
|
if (myFollowers()) setFollowers((myFollowers() || []) as Author[])
|
|
|
|
|
changeFollowing([...(myFollows?.topics || []), ...(myFollows?.authors || [])])
|
|
|
|
|
}
|
|
|
|
|
} else if (s && !isFetching()) {
|
|
|
|
|
setIsFetching(true)
|
|
|
|
|
setSlug(s)
|
|
|
|
|
await loadAuthor(s)
|
|
|
|
|
setIsFetching(false) // Сброс состояния загрузки после завершения
|
2024-05-20 23:15:52 +00:00
|
|
|
|
}
|
2024-06-26 08:22:05 +00:00
|
|
|
|
})
|
2024-06-24 17:50:27 +00:00
|
|
|
|
)
|
|
|
|
|
// 3 // after fetch loading following data
|
|
|
|
|
createEffect(
|
|
|
|
|
on(
|
|
|
|
|
[followers, () => authorsEntities()[slug()]],
|
|
|
|
|
async ([current, found]) => {
|
|
|
|
|
if (current) return
|
|
|
|
|
if (!found) return
|
|
|
|
|
setAuthor(found)
|
|
|
|
|
console.info(`[Author] profile for @${slug()} fetched`)
|
|
|
|
|
const followsResp = await query(getAuthorFollowsQuery, { slug: slug() }).toPromise()
|
|
|
|
|
const follows = followsResp?.data?.get_author_followers || {}
|
|
|
|
|
changeFollowing([...(follows?.authors || []), ...(follows?.topics || [])])
|
|
|
|
|
console.info(`[Author] follows for @${slug()} fetched`)
|
|
|
|
|
const followersResp = await query(getAuthorFollowersQuery, { slug: slug() }).toPromise()
|
|
|
|
|
setFollowers(followersResp?.data?.get_author_followers || [])
|
|
|
|
|
console.info(`[Author] followers for @${slug()} fetched`)
|
|
|
|
|
setIsFetching(false)
|
|
|
|
|
},
|
2024-06-26 08:22:05 +00:00
|
|
|
|
{ defer: true }
|
|
|
|
|
)
|
2024-05-20 23:15:52 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// догружает ленту и комментарии
|
|
|
|
|
createEffect(
|
2024-06-24 17:50:27 +00:00
|
|
|
|
on(
|
|
|
|
|
() => author() as Author,
|
|
|
|
|
async (profile: Author) => {
|
|
|
|
|
if (!commented() && profile) {
|
|
|
|
|
await loadMore()
|
2024-05-20 23:15:52 +00:00
|
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
|
const resp = await query(loadReactionsBy, {
|
2024-06-26 08:22:05 +00:00
|
|
|
|
by: { comment: true, created_by: profile.id }
|
2024-06-24 17:50:27 +00:00
|
|
|
|
}).toPromise()
|
|
|
|
|
const ccc = resp?.data?.load_reactions_by
|
|
|
|
|
if (ccc) setCommented(ccc)
|
|
|
|
|
}
|
2024-06-26 08:22:05 +00:00
|
|
|
|
}
|
2024-06-24 17:50:27 +00:00
|
|
|
|
// { defer: true },
|
2024-06-26 08:22:05 +00:00
|
|
|
|
)
|
2024-05-20 23:15:52 +00:00
|
|
|
|
)
|
|
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
|
let bioContainerRef: HTMLDivElement
|
|
|
|
|
let bioWrapperRef: HTMLDivElement
|
2024-05-20 23:15:52 +00:00
|
|
|
|
const checkBioHeight = () => {
|
2024-06-24 17:50:27 +00:00
|
|
|
|
if (bioContainerRef) {
|
|
|
|
|
setShowExpandBioControl(bioContainerRef.offsetHeight > bioWrapperRef.offsetHeight)
|
2024-05-20 23:15:52 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
|
onMount(() => {
|
2024-06-24 17:50:27 +00:00
|
|
|
|
if (!modal()) hideModal()
|
2024-01-31 12:34:15 +00:00
|
|
|
|
checkBioHeight()
|
|
|
|
|
})
|
|
|
|
|
|
2023-10-14 11:39:24 +00:00
|
|
|
|
const pages = createMemo<Shout[][]>(() =>
|
2024-06-26 08:22:05 +00:00
|
|
|
|
splitToPages(sortedFeed(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE)
|
2022-10-28 21:21:47 +00:00
|
|
|
|
)
|
|
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
|
const ogImage = createMemo(() =>
|
2024-03-15 16:42:55 +00:00
|
|
|
|
author()?.pic
|
2024-06-24 17:50:27 +00:00
|
|
|
|
? getImageUrl(author()?.pic || '', { width: 1200 })
|
2024-06-26 08:22:05 +00:00
|
|
|
|
: getImageUrl('production/image/logo_image.png')
|
2024-01-31 12:34:15 +00:00
|
|
|
|
)
|
2024-06-24 17:50:27 +00:00
|
|
|
|
const description = createMemo(() => getDescription(author()?.bio || ''))
|
2024-03-06 11:56:32 +00:00
|
|
|
|
const handleDeleteComment = (id: number) => {
|
2024-06-24 17:50:27 +00:00
|
|
|
|
setCommented((prev) => (prev || []).filter((comment) => comment.id !== id))
|
2024-03-06 11:56:32 +00:00
|
|
|
|
}
|
2023-12-13 10:39:31 +00:00
|
|
|
|
|
2022-09-09 11:53:35 +00:00
|
|
|
|
return (
|
2023-08-27 21:21:40 +00:00
|
|
|
|
<div class={styles.authorPage}>
|
2024-03-15 16:42:55 +00:00
|
|
|
|
<Show when={author()}>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Title>{author()?.name}</Title>
|
2024-01-31 12:34:15 +00:00
|
|
|
|
<Meta name="descprition" content={description()} />
|
|
|
|
|
<Meta name="og:type" content="profile" />
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Meta name="og:title" content={author()?.name || ''} />
|
2024-01-31 12:34:15 +00:00
|
|
|
|
<Meta name="og:image" content={ogImage()} />
|
|
|
|
|
<Meta name="og:description" content={description()} />
|
|
|
|
|
<Meta name="twitter:card" content="summary_large_image" />
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Meta name="twitter:title" content={author()?.name || ''} />
|
2024-01-31 12:34:15 +00:00
|
|
|
|
<Meta name="twitter:description" content={description()} />
|
|
|
|
|
<Meta name="twitter:image" content={ogImage()} />
|
|
|
|
|
</Show>
|
2023-02-17 09:21:02 +00:00
|
|
|
|
<div class="wide-container">
|
2024-03-15 16:42:55 +00:00
|
|
|
|
<Show when={author()} fallback={<Loading />}>
|
2023-10-16 10:31:10 +00:00
|
|
|
|
<>
|
|
|
|
|
<div class={styles.authorHeader}>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<AuthorCard
|
|
|
|
|
author={author() as Author}
|
|
|
|
|
followers={followers() || []}
|
|
|
|
|
flatFollows={following() || []}
|
|
|
|
|
/>
|
2022-09-09 11:53:35 +00:00
|
|
|
|
</div>
|
2023-10-16 10:31:10 +00:00
|
|
|
|
<div class={clsx(styles.groupControls, 'row')}>
|
|
|
|
|
<div class="col-md-16">
|
|
|
|
|
<ul class="view-switcher">
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<li classList={{ 'view-switcher__item--selected': !!matchAuthor() }}>
|
|
|
|
|
<A href={`/author/${props.authorSlug}`}>{t('Publications')}</A>
|
|
|
|
|
<Show when={author()?.stat}>
|
|
|
|
|
<span class="view-switcher__counter">{author()?.stat?.shouts || 0}</span>
|
2023-12-24 17:29:16 +00:00
|
|
|
|
</Show>
|
2023-10-16 10:31:10 +00:00
|
|
|
|
</li>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<li classList={{ 'view-switcher__item--selected': !!matchComments() }}>
|
|
|
|
|
<A href={`/author/${props.authorSlug}/comments`}>{t('Comments')}</A>
|
|
|
|
|
<Show when={author()?.stat}>
|
|
|
|
|
<span class="view-switcher__counter">{author()?.stat?.comments || 0}</span>
|
2023-12-24 17:29:16 +00:00
|
|
|
|
</Show>
|
2023-10-16 10:31:10 +00:00
|
|
|
|
</li>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<li classList={{ 'view-switcher__item--selected': !!matchAbout() }}>
|
|
|
|
|
<A onClick={() => checkBioHeight()} href={`/author/${props.authorSlug}`}>
|
2024-07-03 17:38:43 +00:00
|
|
|
|
{t('About the author')}
|
2024-06-24 17:50:27 +00:00
|
|
|
|
</A>
|
2023-10-16 10:31:10 +00:00
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
<div class={clsx('col-md-8', styles.additionalControls)}>
|
2024-03-15 16:42:55 +00:00
|
|
|
|
<Show when={author()?.stat?.rating || author()?.stat?.rating === 0}>
|
2023-12-27 23:14:33 +00:00
|
|
|
|
<div class={styles.ratingContainer}>
|
2023-12-28 00:30:09 +00:00
|
|
|
|
{t('All posts rating')}
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<AuthorShoutsRating author={author() as Author} class={styles.ratingControl} />
|
2023-12-27 23:14:33 +00:00
|
|
|
|
</div>
|
|
|
|
|
</Show>
|
2023-10-16 10:31:10 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
</Show>
|
2023-02-17 09:21:02 +00:00
|
|
|
|
</div>
|
2022-09-09 11:53:35 +00:00
|
|
|
|
|
2023-05-04 19:57:02 +00:00
|
|
|
|
<Switch>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Match when={matchAbout()}>
|
2023-02-17 09:21:02 +00:00
|
|
|
|
<div class="wide-container">
|
2023-09-06 22:58:54 +00:00
|
|
|
|
<div class="row">
|
|
|
|
|
<div class="col-md-20 col-lg-18">
|
|
|
|
|
<div
|
2024-06-24 17:50:27 +00:00
|
|
|
|
ref={(el) => (bioWrapperRef = el)}
|
2023-09-06 22:58:54 +00:00
|
|
|
|
class={styles.longBio}
|
|
|
|
|
classList={{ [styles.longBioExpanded]: isBioExpanded() }}
|
|
|
|
|
>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<div ref={(el) => (bioContainerRef = el)} innerHTML={author()?.about || ''} />
|
2023-09-06 22:58:54 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<Show when={showExpandBioControl()}>
|
|
|
|
|
<button
|
|
|
|
|
class={clsx('button button--subscribe-topic', styles.longBioExpandedControl)}
|
|
|
|
|
onClick={() => setIsBioExpanded(!isBioExpanded())}
|
|
|
|
|
>
|
|
|
|
|
{t('Show more')}
|
|
|
|
|
</button>
|
|
|
|
|
</Show>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2023-02-17 09:21:02 +00:00
|
|
|
|
</div>
|
|
|
|
|
</Match>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Match when={matchComments()}>
|
2024-06-05 17:49:31 +00:00
|
|
|
|
<Show when={me()?.slug === props.authorSlug && !me().stat?.comments}>
|
2024-05-18 22:03:06 +00:00
|
|
|
|
<div class="wide-container">
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Placeholder type={loc?.pathname} mode="profile" />
|
2024-05-18 22:03:06 +00:00
|
|
|
|
</div>
|
|
|
|
|
</Show>
|
2024-05-11 17:27:57 +00:00
|
|
|
|
|
2023-02-17 09:21:02 +00:00
|
|
|
|
<div class="wide-container">
|
2023-05-17 21:10:15 +00:00
|
|
|
|
<div class="row">
|
|
|
|
|
<div class="col-md-20 col-lg-18">
|
|
|
|
|
<ul class={stylesArticle.comments}>
|
2024-02-29 15:05:05 +00:00
|
|
|
|
<For each={commented()?.sort(byCreated).reverse()}>
|
2024-03-06 12:02:32 +00:00
|
|
|
|
{(comment) => (
|
2024-03-06 11:56:32 +00:00
|
|
|
|
<Comment
|
|
|
|
|
comment={comment}
|
|
|
|
|
class={styles.comment}
|
|
|
|
|
showArticleLink={true}
|
|
|
|
|
onDelete={(id) => handleDeleteComment(id)}
|
|
|
|
|
/>
|
2024-03-06 12:02:32 +00:00
|
|
|
|
)}
|
2023-05-17 21:10:15 +00:00
|
|
|
|
</For>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2023-02-17 09:21:02 +00:00
|
|
|
|
</div>
|
|
|
|
|
</Match>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Match when={matchAuthor()}>
|
2024-06-05 17:49:31 +00:00
|
|
|
|
<Show when={me()?.slug === props.authorSlug && !me().stat?.shouts}>
|
2024-05-11 17:27:57 +00:00
|
|
|
|
<div class="wide-container">
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Placeholder type={loc?.pathname} mode="profile" />
|
2024-05-11 17:27:57 +00:00
|
|
|
|
</div>
|
2023-08-27 21:21:40 +00:00
|
|
|
|
</Show>
|
|
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Show when={sortedFeed().length > 0}>
|
|
|
|
|
<Row1 article={sortedFeed()[0]} noauthor={true} nodate={true} />
|
2023-08-27 21:21:40 +00:00
|
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Show when={sortedFeed().length > 1}>
|
2024-06-06 05:44:59 +00:00
|
|
|
|
<Switch>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Match when={sortedFeed().length === 2}>
|
|
|
|
|
<Row2 articles={sortedFeed()} isEqual={true} noauthor={true} nodate={true} />
|
2024-06-06 05:44:59 +00:00
|
|
|
|
</Match>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Match when={sortedFeed().length === 3}>
|
|
|
|
|
<Row3 articles={sortedFeed()} noauthor={true} nodate={true} />
|
2024-06-06 05:44:59 +00:00
|
|
|
|
</Match>
|
2024-06-24 17:50:27 +00:00
|
|
|
|
<Match when={sortedFeed().length > 3}>
|
2024-06-06 05:44:59 +00:00
|
|
|
|
<For each={pages()}>
|
|
|
|
|
{(page) => (
|
|
|
|
|
<>
|
|
|
|
|
<Row1 article={page[0]} noauthor={true} nodate={true} />
|
|
|
|
|
<Row2 articles={page.slice(1, 3)} isEqual={true} noauthor={true} />
|
|
|
|
|
<Row1 article={page[3]} noauthor={true} nodate={true} />
|
|
|
|
|
<Row2 articles={page.slice(4, 6)} isEqual={true} noauthor={true} />
|
|
|
|
|
<Row1 article={page[6]} noauthor={true} nodate={true} />
|
|
|
|
|
<Row2 articles={page.slice(7, 9)} isEqual={true} noauthor={true} />
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</For>
|
|
|
|
|
</Match>
|
|
|
|
|
</Switch>
|
2024-05-11 17:27:57 +00:00
|
|
|
|
</Show>
|
2023-02-17 09:21:02 +00:00
|
|
|
|
|
2024-05-11 17:27:57 +00:00
|
|
|
|
<Show when={isLoadMoreButtonVisible()}>
|
|
|
|
|
<p class="load-more-container">
|
|
|
|
|
<button class="button" onClick={loadMore}>
|
|
|
|
|
{t('Load more')}
|
|
|
|
|
</button>
|
|
|
|
|
</p>
|
|
|
|
|
</Show>
|
2023-02-17 09:21:02 +00:00
|
|
|
|
</Show>
|
|
|
|
|
</Match>
|
|
|
|
|
</Switch>
|
2022-09-09 11:53:35 +00:00
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|