2022-09-07 10:00:28 +03:00
|
|
|
import { FC, useEffect, useState } from 'react';
|
2022-11-02 07:10:55 +03:00
|
|
|
import { Col, Pagination, Row, Skeleton } from 'antd';
|
2023-03-13 09:03:22 +03:00
|
|
|
import { ErrorBoundary } from 'react-error-boundary';
|
2022-09-03 21:38:52 +03:00
|
|
|
import { Follower } from '../../../../interfaces/follower';
|
2022-09-07 10:00:28 +03:00
|
|
|
import { SingleFollower } from '../SingleFollower/SingleFollower';
|
2022-10-10 06:31:07 +03:00
|
|
|
import styles from './FollowerCollection.module.scss';
|
|
|
|
import { FollowButton } from '../../../action-buttons/FollowButton';
|
2023-03-13 09:03:22 +03:00
|
|
|
import { ComponentError } from '../../ComponentError/ComponentError';
|
2022-07-12 04:29:58 +03:00
|
|
|
|
2022-10-10 06:31:07 +03:00
|
|
|
export type FollowerCollectionProps = {
|
|
|
|
name: string;
|
2022-11-18 08:30:57 +03:00
|
|
|
onFollowButtonClick: () => void;
|
2022-10-10 06:31:07 +03:00
|
|
|
};
|
|
|
|
|
2022-11-18 08:30:57 +03:00
|
|
|
export const FollowerCollection: FC<FollowerCollectionProps> = ({ name, onFollowButtonClick }) => {
|
2022-07-12 07:06:57 +03:00
|
|
|
const ENDPOINT = '/api/followers';
|
2022-07-12 04:29:58 +03:00
|
|
|
const ITEMS_PER_PAGE = 24;
|
|
|
|
|
2022-07-12 07:06:57 +03:00
|
|
|
const [followers, setFollowers] = useState<Follower[]>([]);
|
|
|
|
const [total, setTotal] = useState(0);
|
|
|
|
const [page, setPage] = useState(1);
|
2022-11-02 07:10:55 +03:00
|
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
|
2022-07-12 07:06:57 +03:00
|
|
|
const getFollowers = async () => {
|
|
|
|
try {
|
2023-03-18 07:10:56 +03:00
|
|
|
const response = await fetch(
|
|
|
|
`${ENDPOINT}?offset=${page * ITEMS_PER_PAGE}&limit=${ITEMS_PER_PAGE}`,
|
|
|
|
);
|
2023-01-13 01:45:53 +03:00
|
|
|
|
2022-07-12 07:06:57 +03:00
|
|
|
const data = await response.json();
|
2022-10-10 04:52:41 +03:00
|
|
|
const { results, total: totalResults } = data;
|
2022-07-12 07:06:57 +03:00
|
|
|
|
2022-10-10 04:52:41 +03:00
|
|
|
setFollowers(results);
|
|
|
|
setTotal(totalResults);
|
2023-02-09 06:57:30 +03:00
|
|
|
|
2022-12-30 09:59:53 +03:00
|
|
|
setLoading(false);
|
2022-07-12 07:06:57 +03:00
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
getFollowers();
|
|
|
|
}, [page]);
|
|
|
|
|
2022-07-12 04:29:58 +03:00
|
|
|
const noFollowers = (
|
2022-12-12 08:06:20 +03:00
|
|
|
<div className={styles.noFollowers} id="followers-collection">
|
2022-10-10 06:31:07 +03:00
|
|
|
<h2>Be the first follower!</h2>
|
|
|
|
<p>
|
|
|
|
{name !== 'Owncast' ? name : 'This server'} is a part of the{' '}
|
|
|
|
<a href="https://owncast.online/join-fediverse">Fediverse</a>, an interconnected network of
|
|
|
|
independent users and servers.
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
By following {name !== 'Owncast' ? name : 'this server'} you'll be able to get updates
|
2022-12-15 10:20:11 +03:00
|
|
|
from the stream, share it with others, and show your appreciation when it goes live, all
|
2022-10-10 06:31:07 +03:00
|
|
|
from your own Fediverse account.
|
|
|
|
</p>
|
2022-11-18 08:30:57 +03:00
|
|
|
<FollowButton onClick={onFollowButtonClick} />
|
2022-10-10 06:31:07 +03:00
|
|
|
</div>
|
2022-07-12 04:29:58 +03:00
|
|
|
);
|
|
|
|
|
2022-11-02 07:10:55 +03:00
|
|
|
const loadingSkeleton = <Skeleton active paragraph={{ rows: 3 }} />;
|
|
|
|
|
|
|
|
if (loading) {
|
|
|
|
return loadingSkeleton;
|
|
|
|
}
|
|
|
|
|
2022-07-12 23:14:39 +03:00
|
|
|
if (!followers?.length) {
|
2022-07-12 04:29:58 +03:00
|
|
|
return noFollowers;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2023-03-13 09:03:22 +03:00
|
|
|
<ErrorBoundary
|
|
|
|
// eslint-disable-next-line react/no-unstable-nested-components
|
|
|
|
fallbackRender={({ error, resetErrorBoundary }) => (
|
|
|
|
<ComponentError
|
|
|
|
componentName="FollowerCollection"
|
|
|
|
message={error.message}
|
|
|
|
retryFunction={resetErrorBoundary}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
<div className={styles.followers} id="followers-collection">
|
|
|
|
<Row wrap gutter={[10, 10]} className={styles.followerRow}>
|
|
|
|
{followers.map(follower => (
|
|
|
|
<Col key={follower.link}>
|
|
|
|
<SingleFollower key={follower.link} follower={follower} />
|
|
|
|
</Col>
|
|
|
|
))}
|
|
|
|
</Row>
|
2022-07-12 04:29:58 +03:00
|
|
|
|
2023-03-13 09:03:22 +03:00
|
|
|
<Pagination
|
|
|
|
className={styles.pagination}
|
|
|
|
current={page}
|
|
|
|
pageSize={ITEMS_PER_PAGE}
|
|
|
|
defaultPageSize={ITEMS_PER_PAGE}
|
|
|
|
total={total}
|
|
|
|
showSizeChanger={false}
|
|
|
|
onChange={p => {
|
|
|
|
setPage(p);
|
|
|
|
}}
|
|
|
|
hideOnSinglePage
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</ErrorBoundary>
|
2022-07-12 04:29:58 +03:00
|
|
|
);
|
2022-09-07 10:00:28 +03:00
|
|
|
};
|