Files
5chan/src/views/post/post.tsx
T

101 lines
3.5 KiB
TypeScript
Raw Normal View History

import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
2025-03-07 11:29:04 +01:00
import { Comment, Role, useComment, useEditedComment, useSubplebbit } from '@plebbit/plebbit-react-hooks';
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
2024-04-08 17:32:12 +02:00
import { useLocation, useParams } from 'react-router-dom';
import { isAllView } from '../../lib/utils/view-utils';
import { useResolvedSubplebbitAddress } from '../../hooks/use-resolved-subplebbit-address';
import useIsMobile from '../../hooks/use-is-mobile';
import ErrorDisplay from '../../components/error-display/error-display';
import PostDesktop from '../../components/post-desktop';
import PostMobile from '../../components/post-mobile';
import styles from './post.module.css';
export interface PostProps {
index?: number;
isHidden?: boolean;
2024-12-24 17:13:12 +01:00
hasThumbnail?: boolean;
post?: any;
postReplyCount?: number;
reply?: any;
roles?: Role[];
showAllReplies?: boolean;
showReplies?: boolean;
}
export const Post = ({ post, showAllReplies = false, showReplies = true }: PostProps) => {
const subplebbit = useSubplebbitsStore((state) => state.subplebbits[post?.subplebbitAddress]);
const isMobile = useIsMobile();
let comment = post;
// handle pending mod or author edit
const { editedComment } = useEditedComment({ comment });
if (editedComment) {
comment = editedComment;
}
return (
<div className={styles.thread}>
<div className={styles.postContainer}>
{isMobile ? (
<PostMobile post={comment} roles={subplebbit?.roles} showAllReplies={showAllReplies} showReplies={showReplies} />
) : (
<PostDesktop post={comment} roles={subplebbit?.roles} showAllReplies={showAllReplies} showReplies={showReplies} />
)}
</div>
</div>
);
};
2024-04-02 17:00:36 +02:00
const PostPage = () => {
const { t } = useTranslation();
2024-04-02 17:00:36 +02:00
const params = useParams();
2024-05-09 16:04:24 +02:00
const location = useLocation();
const { commentCid } = params;
const subplebbitAddress = useResolvedSubplebbitAddress();
2024-10-29 17:40:09 +01:00
const isInAllView = isAllView(location.pathname);
2024-04-08 17:32:12 +02:00
2024-06-15 12:37:45 +02:00
const comment = useComment({ commentCid });
2025-03-07 11:29:04 +01:00
const subplebbit = useSubplebbit({ subplebbitAddress });
2025-12-23 19:21:48 +01:00
const { shortAddress, title } = subplebbit || {};
2024-06-15 12:37:45 +02:00
// if the comment is a reply, return the post comment instead, then the reply will be highlighted in the thread
2024-06-04 21:35:22 +02:00
const postComment = useComment({ commentCid: comment?.postCid });
2024-07-02 15:39:20 +02:00
let post: Comment;
2024-06-04 21:35:22 +02:00
if (comment.parentCid) {
post = postComment;
} else {
post = comment;
}
2024-06-15 12:37:45 +02:00
const { error, replyCount } = post || {};
2024-04-02 17:00:36 +02:00
useEffect(() => {
window.scrollTo(0, 0);
}, []);
2024-07-02 15:39:20 +02:00
useEffect(() => {
const boardTitle = title ? title : shortAddress || subplebbitAddress;
const postTitle = post?.title?.slice(0, 30) || post?.content?.slice(0, 30);
2025-10-17 23:30:35 +02:00
const postDucumentTitle = (postTitle ? postTitle.trim() + '... - ' : '') + boardTitle + ' - 5chan';
document.title = isInAllView ? `${t('all')} - 5chan` : postDucumentTitle;
}, [title, shortAddress, subplebbitAddress, post?.title, post?.content, isInAllView, t]);
2024-07-02 15:39:20 +02:00
// probably not necessary to show the error to the user if the post loaded successfully
const shouldShowErrorToUser = post?.error && ((post?.replyCount > 0 && post?.replies?.length === 0) || (post?.state === 'failed' && post?.error));
2024-04-02 17:00:36 +02:00
return (
<div className={styles.content}>
{shouldShowErrorToUser && (
<div className={styles.error}>
<ErrorDisplay error={error} />
</div>
)}
<Post post={post} showAllReplies={true} />
2024-04-02 17:00:36 +02:00
</div>
);
};
export default PostPage;