2024-04-08 14:48:58 +00:00
|
|
|
import type {
|
|
|
|
Author,
|
|
|
|
Reaction,
|
|
|
|
Shout,
|
|
|
|
Topic,
|
|
|
|
} from "../../../graphql/schema/core.gen";
|
2023-11-14 15:10:00 +00:00
|
|
|
|
2024-04-08 14:48:58 +00:00
|
|
|
import { getPagePath } from "@nanostores/router";
|
|
|
|
import { Meta, Title } from "@solidjs/meta";
|
|
|
|
import { clsx } from "clsx";
|
|
|
|
import {
|
|
|
|
For,
|
|
|
|
Match,
|
|
|
|
Show,
|
|
|
|
Switch,
|
|
|
|
createEffect,
|
|
|
|
createMemo,
|
|
|
|
createSignal,
|
|
|
|
onMount,
|
|
|
|
} from "solid-js";
|
2023-11-14 15:10:00 +00:00
|
|
|
|
2024-04-08 14:48:58 +00:00
|
|
|
import { useFollowing } from "../../../context/following";
|
|
|
|
import { useLocalize } from "../../../context/localize";
|
|
|
|
import { useSession } from "../../../context/session";
|
|
|
|
import { apiClient } from "../../../graphql/client/core";
|
|
|
|
import { router, useRouter } from "../../../stores/router";
|
|
|
|
import { loadShouts, useArticlesStore } from "../../../stores/zine/articles";
|
|
|
|
import { loadAuthor, useAuthorsStore } from "../../../stores/zine/authors";
|
|
|
|
import { getImageUrl } from "../../../utils/getImageUrl";
|
|
|
|
import { getDescription } from "../../../utils/meta";
|
|
|
|
import {
|
|
|
|
restoreScrollPosition,
|
|
|
|
saveScrollPosition,
|
|
|
|
} from "../../../utils/scroll";
|
|
|
|
import { splitToPages } from "../../../utils/splitToPages";
|
|
|
|
import { Comment } from "../../Article/Comment";
|
|
|
|
import { AuthorCard } from "../../Author/AuthorCard";
|
|
|
|
import { AuthorShoutsRating } from "../../Author/AuthorShoutsRating";
|
|
|
|
import { Row1 } from "../../Feed/Row1";
|
|
|
|
import { Row2 } from "../../Feed/Row2";
|
|
|
|
import { Row3 } from "../../Feed/Row3";
|
|
|
|
import { Loading } from "../../_shared/Loading";
|
2023-11-14 15:10:00 +00:00
|
|
|
|
2024-04-08 14:48:58 +00:00
|
|
|
import { MODALS, hideModal } from "../../../stores/ui";
|
|
|
|
import { byCreated } from "../../../utils/sortby";
|
|
|
|
import stylesArticle from "../../Article/Article.module.scss";
|
|
|
|
import styles from "./Author.module.scss";
|
2022-09-09 11:53:35 +00:00
|
|
|
|
2023-09-09 12:04:46 +00:00
|
|
|
type Props = {
|
2024-04-08 14:48:58 +00:00
|
|
|
authorSlug: string;
|
|
|
|
shouts?: Shout[];
|
|
|
|
author?: Author;
|
|
|
|
};
|
|
|
|
export const PRERENDERED_ARTICLES_COUNT = 12;
|
|
|
|
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) => {
|
2024-04-08 14:48:58 +00:00
|
|
|
const { t } = useLocalize();
|
|
|
|
const {
|
|
|
|
subscriptions,
|
|
|
|
followers: myFollowers,
|
|
|
|
loadSubscriptions,
|
|
|
|
} = useFollowing();
|
|
|
|
const { session } = useSession();
|
|
|
|
const { sortedArticles } = useArticlesStore({ shouts: props.shouts });
|
|
|
|
const { authorEntities } = useAuthorsStore({ authors: [props.author] });
|
|
|
|
const { page: getPage, searchParams } = useRouter();
|
|
|
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] =
|
|
|
|
createSignal(false);
|
|
|
|
const [isBioExpanded, setIsBioExpanded] = createSignal(false);
|
|
|
|
const [author, setAuthor] = createSignal<Author>();
|
|
|
|
const [followers, setFollowers] = createSignal([]);
|
|
|
|
const [following, setFollowing] = createSignal<Array<Author | Topic>>([]); // flat AuthorFollowsResult
|
|
|
|
const [showExpandBioControl, setShowExpandBioControl] = createSignal(false);
|
|
|
|
const [commented, setCommented] = createSignal<Reaction[]>();
|
|
|
|
const modal = MODALS[searchParams().m];
|
2023-12-25 06:52:04 +00:00
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
// current author
|
|
|
|
createEffect(() => {
|
2024-04-08 12:54:01 +00:00
|
|
|
if (props.authorSlug) {
|
2024-04-08 12:49:40 +00:00
|
|
|
if (session()?.user?.app_data?.profile?.slug === props.authorSlug) {
|
2024-04-08 14:48:58 +00:00
|
|
|
console.info("my own profile");
|
|
|
|
const { profile, authors, topics } = session().user.app_data;
|
|
|
|
setFollowers(myFollowers);
|
|
|
|
setAuthor(profile);
|
|
|
|
setFollowing([...authors, ...topics]);
|
2024-04-08 12:49:40 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
try {
|
2024-04-08 14:48:58 +00:00
|
|
|
const a = authorEntities()[props.authorSlug];
|
|
|
|
setAuthor(a);
|
|
|
|
// TODO: add following data retrieval
|
|
|
|
console.debug("[Author] expecting following data fetched");
|
2024-04-08 12:49:40 +00:00
|
|
|
} catch (error) {
|
2024-04-08 14:48:58 +00:00
|
|
|
console.debug(error);
|
2024-04-08 12:49:40 +00:00
|
|
|
}
|
2024-01-31 12:34:15 +00:00
|
|
|
}
|
2024-04-08 14:48:58 +00:00
|
|
|
});
|
2024-01-31 12:34:15 +00:00
|
|
|
|
2024-02-25 22:29:26 +00:00
|
|
|
createEffect(async () => {
|
2024-02-04 09:03:15 +00:00
|
|
|
if (author()?.id && !author().stat) {
|
2024-04-08 14:48:58 +00:00
|
|
|
const a = await loadAuthor({ slug: "", author_id: author().id });
|
|
|
|
console.debug("[AuthorView] loaded author:", a);
|
2023-12-24 17:29:16 +00:00
|
|
|
}
|
2024-04-08 14:48:58 +00:00
|
|
|
});
|
2023-12-24 17:29:16 +00:00
|
|
|
|
2024-04-08 14:48:58 +00:00
|
|
|
const bioContainerRef: { current: HTMLDivElement } = { current: null };
|
|
|
|
const bioWrapperRef: { current: HTMLDivElement } = { current: null };
|
2024-01-31 12:34:15 +00:00
|
|
|
|
2024-02-03 07:56:11 +00:00
|
|
|
const fetchData = async (slug) => {
|
2023-04-22 14:36:38 +00:00
|
|
|
try {
|
2024-02-03 07:56:11 +00:00
|
|
|
const [subscriptionsResult, followersResult] = await Promise.all([
|
2024-02-21 14:25:28 +00:00
|
|
|
apiClient.getAuthorFollows({ slug }),
|
2024-02-03 07:56:11 +00:00
|
|
|
apiClient.getAuthorFollowers({ slug }),
|
2024-04-08 14:48:58 +00:00
|
|
|
]);
|
2024-02-03 07:56:11 +00:00
|
|
|
|
2024-04-08 14:48:58 +00:00
|
|
|
const { authors, topics } = subscriptionsResult;
|
|
|
|
setFollowing([...(authors || []), ...(topics || [])]);
|
|
|
|
setFollowers(followersResult || []);
|
2024-02-03 07:56:11 +00:00
|
|
|
|
2024-04-08 14:48:58 +00:00
|
|
|
console.info("[components.Author] following data loaded");
|
2023-04-22 14:36:38 +00:00
|
|
|
} catch (error) {
|
2024-04-08 14:48:58 +00:00
|
|
|
console.error("[components.Author] fetch error", error);
|
2023-04-22 14:36:38 +00:00
|
|
|
}
|
2024-04-08 14:48:58 +00:00
|
|
|
};
|
2023-04-22 14:36:38 +00:00
|
|
|
|
2023-09-06 22:58:54 +00:00
|
|
|
const checkBioHeight = () => {
|
2023-09-15 09:30:50 +00:00
|
|
|
if (bioContainerRef.current) {
|
2024-04-08 14:48:58 +00:00
|
|
|
setShowExpandBioControl(
|
|
|
|
bioContainerRef.current.offsetHeight >
|
|
|
|
bioWrapperRef.current.offsetHeight,
|
|
|
|
);
|
2023-09-06 22:58:54 +00:00
|
|
|
}
|
2024-04-08 14:48:58 +00:00
|
|
|
};
|
2023-09-06 22:58:54 +00:00
|
|
|
|
2024-03-21 08:42:28 +00:00
|
|
|
onMount(() => {
|
2024-04-08 14:48:58 +00:00
|
|
|
fetchData(props.authorSlug);
|
2024-03-21 08:42:28 +00:00
|
|
|
|
|
|
|
if (!modal) {
|
2024-04-08 14:48:58 +00:00
|
|
|
hideModal();
|
2024-03-21 08:42:28 +00:00
|
|
|
}
|
2024-04-08 14:48:58 +00:00
|
|
|
});
|
2023-11-14 10:45:44 +00:00
|
|
|
|
2022-10-28 21:21:47 +00:00
|
|
|
const loadMore = async () => {
|
2024-04-08 14:48:58 +00:00
|
|
|
saveScrollPosition();
|
2022-11-18 02:23:04 +00:00
|
|
|
const { hasMore } = await loadShouts({
|
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,
|
2023-11-14 15:10:00 +00:00
|
|
|
offset: sortedArticles().length,
|
2024-04-08 14:48:58 +00:00
|
|
|
});
|
|
|
|
setIsLoadMoreButtonVisible(hasMore);
|
|
|
|
restoreScrollPosition();
|
|
|
|
};
|
2022-10-28 21:21:47 +00:00
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
onMount(() => {
|
2024-04-08 14:48:58 +00:00
|
|
|
checkBioHeight();
|
2024-01-31 12:34:15 +00:00
|
|
|
|
|
|
|
// pagination
|
|
|
|
if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) {
|
2024-04-08 14:48:58 +00:00
|
|
|
loadMore();
|
|
|
|
loadSubscriptions();
|
2024-01-31 12:34:15 +00:00
|
|
|
}
|
2024-04-08 14:48:58 +00:00
|
|
|
});
|
2024-01-31 12:34:15 +00:00
|
|
|
|
2023-10-14 11:39:24 +00:00
|
|
|
const pages = createMemo<Shout[][]>(() =>
|
2024-04-08 14:48:58 +00:00
|
|
|
splitToPages(
|
|
|
|
sortedArticles(),
|
|
|
|
PRERENDERED_ARTICLES_COUNT,
|
|
|
|
LOAD_MORE_PAGE_SIZE,
|
|
|
|
),
|
|
|
|
);
|
2022-10-28 21:21:47 +00:00
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
const fetchComments = async (commenter: Author) => {
|
|
|
|
const data = await apiClient.getReactionsBy({
|
2024-02-03 09:23:44 +00:00
|
|
|
by: { comment: false, created_by: commenter.id },
|
2024-04-08 14:48:58 +00:00
|
|
|
});
|
|
|
|
setCommented(data);
|
|
|
|
};
|
2023-04-20 14:01:15 +00:00
|
|
|
|
2024-01-31 15:15:23 +00:00
|
|
|
createEffect(() => {
|
2024-03-06 11:56:32 +00:00
|
|
|
if (author()) {
|
2024-04-08 14:48:58 +00:00
|
|
|
fetchComments(author());
|
2024-01-31 15:15:23 +00:00
|
|
|
}
|
2024-04-08 14:48:58 +00:00
|
|
|
});
|
2023-09-09 12:04:46 +00:00
|
|
|
|
2024-01-31 12:34:15 +00:00
|
|
|
const ogImage = createMemo(() =>
|
|
|
|
author()?.pic
|
|
|
|
? getImageUrl(author()?.pic, { width: 1200 })
|
2024-04-08 14:48:58 +00:00
|
|
|
: getImageUrl("production/image/logo_image.png"),
|
|
|
|
);
|
|
|
|
const description = createMemo(() => getDescription(author()?.bio));
|
2024-03-06 11:56:32 +00:00
|
|
|
const handleDeleteComment = (id: number) => {
|
2024-04-08 14:48:58 +00:00
|
|
|
setCommented((prev) => prev.filter((comment) => comment.id !== id));
|
|
|
|
};
|
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-01-31 12:34:15 +00:00
|
|
|
<Show when={author()}>
|
2024-02-03 09:23:44 +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" />
|
|
|
|
<Meta name="og:title" content={author().name} />
|
|
|
|
<Meta name="og:image" content={ogImage()} />
|
|
|
|
<Meta name="og:description" content={description()} />
|
|
|
|
<Meta name="twitter:card" content="summary_large_image" />
|
|
|
|
<Meta name="twitter:title" content={author().name} />
|
|
|
|
<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">
|
2023-10-16 10:31:10 +00:00
|
|
|
<Show when={author()} fallback={<Loading />}>
|
|
|
|
<>
|
|
|
|
<div class={styles.authorHeader}>
|
2024-04-08 14:48:58 +00:00
|
|
|
<AuthorCard
|
|
|
|
author={author()}
|
|
|
|
followers={followers() || []}
|
|
|
|
following={following() || []}
|
|
|
|
/>
|
2022-09-09 11:53:35 +00:00
|
|
|
</div>
|
2024-04-08 14:48:58 +00:00
|
|
|
<div class={clsx(styles.groupControls, "row")}>
|
2023-10-16 10:31:10 +00:00
|
|
|
<div class="col-md-16">
|
|
|
|
<ul class="view-switcher">
|
2024-04-08 14:48:58 +00:00
|
|
|
<li
|
|
|
|
classList={{
|
|
|
|
"view-switcher__item--selected":
|
|
|
|
getPage().route === "author",
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<a
|
|
|
|
href={getPagePath(router, "author", {
|
|
|
|
slug: props.authorSlug,
|
|
|
|
})}
|
|
|
|
>
|
|
|
|
{t("Publications")}
|
2023-10-16 10:31:10 +00:00
|
|
|
</a>
|
2023-12-24 17:29:16 +00:00
|
|
|
<Show when={author().stat}>
|
2024-04-08 14:48:58 +00:00
|
|
|
<span class="view-switcher__counter">
|
|
|
|
{author().stat.shouts}
|
|
|
|
</span>
|
2023-12-24 17:29:16 +00:00
|
|
|
</Show>
|
2023-10-16 10:31:10 +00:00
|
|
|
</li>
|
2024-04-08 14:48:58 +00:00
|
|
|
<li
|
|
|
|
classList={{
|
|
|
|
"view-switcher__item--selected":
|
|
|
|
getPage().route === "authorComments",
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<a
|
|
|
|
href={getPagePath(router, "authorComments", {
|
|
|
|
slug: props.authorSlug,
|
|
|
|
})}
|
|
|
|
>
|
|
|
|
{t("Comments")}
|
2023-10-16 10:31:10 +00:00
|
|
|
</a>
|
2023-12-24 17:29:16 +00:00
|
|
|
<Show when={author().stat}>
|
2024-04-08 14:48:58 +00:00
|
|
|
<span class="view-switcher__counter">
|
|
|
|
{author().stat.comments}
|
|
|
|
</span>
|
2023-12-24 17:29:16 +00:00
|
|
|
</Show>
|
2023-10-16 10:31:10 +00:00
|
|
|
</li>
|
2024-04-08 14:48:58 +00:00
|
|
|
<li
|
|
|
|
classList={{
|
|
|
|
"view-switcher__item--selected":
|
|
|
|
getPage().route === "authorAbout",
|
|
|
|
}}
|
|
|
|
>
|
2023-10-16 10:31:10 +00:00
|
|
|
<a
|
|
|
|
onClick={() => checkBioHeight()}
|
2024-04-08 14:48:58 +00:00
|
|
|
href={getPagePath(router, "authorAbout", {
|
|
|
|
slug: props.authorSlug,
|
|
|
|
})}
|
2023-10-16 10:31:10 +00:00
|
|
|
>
|
2024-04-08 14:48:58 +00:00
|
|
|
{t("Profile")}
|
2023-10-16 10:31:10 +00:00
|
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
2024-04-08 14:48:58 +00:00
|
|
|
<div class={clsx("col-md-8", styles.additionalControls)}>
|
|
|
|
<Show
|
|
|
|
when={author()?.stat?.rating || author()?.stat?.rating === 0}
|
|
|
|
>
|
2023-12-27 23:14:33 +00:00
|
|
|
<div class={styles.ratingContainer}>
|
2024-04-08 14:48:58 +00:00
|
|
|
{t("All posts rating")}
|
|
|
|
<AuthorShoutsRating
|
|
|
|
author={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-04-08 14:48:58 +00:00
|
|
|
<Match when={getPage().route === "authorAbout"}>
|
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
|
2023-09-18 16:33:22 +00:00
|
|
|
ref={(el) => (bioWrapperRef.current = el)}
|
2023-09-06 22:58:54 +00:00
|
|
|
class={styles.longBio}
|
|
|
|
classList={{ [styles.longBioExpanded]: isBioExpanded() }}
|
|
|
|
>
|
2024-04-08 14:48:58 +00:00
|
|
|
<div
|
|
|
|
ref={(el) => (bioContainerRef.current = el)}
|
|
|
|
innerHTML={author().about}
|
|
|
|
/>
|
2023-09-06 22:58:54 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<Show when={showExpandBioControl()}>
|
|
|
|
<button
|
2024-04-08 14:48:58 +00:00
|
|
|
class={clsx(
|
|
|
|
"button button--subscribe-topic",
|
|
|
|
styles.longBioExpandedControl,
|
|
|
|
)}
|
2023-09-06 22:58:54 +00:00
|
|
|
onClick={() => setIsBioExpanded(!isBioExpanded())}
|
|
|
|
>
|
2024-04-08 14:48:58 +00:00
|
|
|
{t("Show more")}
|
2023-09-06 22:58:54 +00:00
|
|
|
</button>
|
|
|
|
</Show>
|
|
|
|
</div>
|
|
|
|
</div>
|
2023-02-17 09:21:02 +00:00
|
|
|
</div>
|
|
|
|
</Match>
|
2024-04-08 14:48:58 +00:00
|
|
|
<Match when={getPage().route === "authorComments"}>
|
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-04-08 14:48:58 +00:00
|
|
|
<Match when={getPage().route === "author"}>
|
2023-08-27 21:21:40 +00:00
|
|
|
<Show when={sortedArticles().length === 1}>
|
2023-10-10 19:45:35 +00:00
|
|
|
<Row1 article={sortedArticles()[0]} noauthor={true} nodate={true} />
|
2023-08-27 21:21:40 +00:00
|
|
|
</Show>
|
|
|
|
|
|
|
|
<Show when={sortedArticles().length === 2}>
|
2024-04-08 14:48:58 +00:00
|
|
|
<Row2
|
|
|
|
articles={sortedArticles()}
|
|
|
|
isEqual={true}
|
|
|
|
noauthor={true}
|
|
|
|
nodate={true}
|
|
|
|
/>
|
2023-08-27 21:21:40 +00:00
|
|
|
</Show>
|
2023-02-17 09:21:02 +00:00
|
|
|
|
2023-08-27 21:21:40 +00:00
|
|
|
<Show when={sortedArticles().length === 3}>
|
2023-10-10 19:45:35 +00:00
|
|
|
<Row3 articles={sortedArticles()} noauthor={true} nodate={true} />
|
2023-08-27 21:21:40 +00:00
|
|
|
</Show>
|
|
|
|
|
|
|
|
<Show when={sortedArticles().length > 3}>
|
2023-10-10 19:45:35 +00:00
|
|
|
<Row1 article={sortedArticles()[0]} noauthor={true} nodate={true} />
|
2024-04-08 14:48:58 +00:00
|
|
|
<Row2
|
|
|
|
articles={sortedArticles().slice(1, 3)}
|
|
|
|
isEqual={true}
|
|
|
|
noauthor={true}
|
|
|
|
/>
|
2023-10-10 19:45:35 +00:00
|
|
|
<Row1 article={sortedArticles()[3]} noauthor={true} nodate={true} />
|
2024-04-08 14:48:58 +00:00
|
|
|
<Row2
|
|
|
|
articles={sortedArticles().slice(4, 6)}
|
|
|
|
isEqual={true}
|
|
|
|
noauthor={true}
|
|
|
|
/>
|
2023-10-10 19:45:35 +00:00
|
|
|
<Row1 article={sortedArticles()[6]} noauthor={true} nodate={true} />
|
2024-04-08 14:48:58 +00:00
|
|
|
<Row2
|
|
|
|
articles={sortedArticles().slice(7, 9)}
|
|
|
|
isEqual={true}
|
|
|
|
noauthor={true}
|
|
|
|
/>
|
2023-08-27 21:21:40 +00:00
|
|
|
|
2023-10-14 11:39:24 +00:00
|
|
|
<For each={pages()}>
|
|
|
|
{(page) => (
|
2023-08-27 21:21:40 +00:00
|
|
|
<>
|
2023-10-14 11:39:24 +00:00
|
|
|
<Row1 article={page[0]} noauthor={true} nodate={true} />
|
2024-04-08 14:48:58 +00:00
|
|
|
<Row2
|
|
|
|
articles={page.slice(1, 3)}
|
|
|
|
isEqual={true}
|
|
|
|
noauthor={true}
|
|
|
|
/>
|
2023-10-14 11:39:24 +00:00
|
|
|
<Row1 article={page[3]} noauthor={true} nodate={true} />
|
2024-04-08 14:48:58 +00:00
|
|
|
<Row2
|
|
|
|
articles={page.slice(4, 6)}
|
|
|
|
isEqual={true}
|
|
|
|
noauthor={true}
|
|
|
|
/>
|
2023-10-14 11:39:24 +00:00
|
|
|
<Row1 article={page[6]} noauthor={true} nodate={true} />
|
2024-04-08 14:48:58 +00:00
|
|
|
<Row2
|
|
|
|
articles={page.slice(7, 9)}
|
|
|
|
isEqual={true}
|
|
|
|
noauthor={true}
|
|
|
|
/>
|
2023-08-27 21:21:40 +00:00
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</For>
|
|
|
|
</Show>
|
2023-02-17 09:21:02 +00:00
|
|
|
|
|
|
|
<Show when={isLoadMoreButtonVisible()}>
|
|
|
|
<p class="load-more-container">
|
|
|
|
<button class="button" onClick={loadMore}>
|
2024-04-08 14:48:58 +00:00
|
|
|
{t("Load more")}
|
2023-02-17 09:21:02 +00:00
|
|
|
</button>
|
|
|
|
</p>
|
|
|
|
</Show>
|
|
|
|
</Match>
|
|
|
|
</Switch>
|
2022-09-09 11:53:35 +00:00
|
|
|
</div>
|
2024-04-08 14:48:58 +00:00
|
|
|
);
|
|
|
|
};
|