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

127 lines
4.9 KiB
TypeScript
Raw Normal View History

import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
2024-07-02 15:39:20 +02:00
import { Comment, Role, useComment, useEditedComment, useSubplebbit } from '@plebbit/plebbit-react-hooks';
2024-04-08 17:32:12 +02:00
import { useLocation, useParams } from 'react-router-dom';
import { isDescriptionView, isRulesView, isSettingsView } from '../../lib/utils/view-utils';
import useIsMobile from '../../hooks/use-is-mobile';
import useReplyModal from '../../hooks/use-reply-modal';
import PostDesktop from '../../components/post-desktop';
import PostMobile from '../../components/post-mobile';
import ReplyModal from '../../components/reply-modal';
2024-05-09 16:04:24 +02:00
import SettingsModal from '../../components/settings-modal';
import SubplebbitDescription from '../../components/subplebbit-description';
import SubplebbitRules from '../../components/subplebbit-rules';
import styles from './post.module.css';
export interface PostProps {
index?: number;
isHidden?: boolean;
post?: any;
postReplyCount?: number;
reply?: any;
roles?: Role[];
showAllReplies?: boolean;
showReplies?: boolean;
openReplyModal?: (parentCid: string, postCid: string, subplebbitAddress: string) => void;
}
export const Post = ({ post, showAllReplies = false, showReplies = true, openReplyModal }: PostProps) => {
const subplebbit = useSubplebbit({ subplebbitAddress: 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} openReplyModal={openReplyModal} />
) : (
<PostDesktop post={comment} roles={subplebbit?.roles} showAllReplies={showAllReplies} showReplies={showReplies} openReplyModal={openReplyModal} />
)}
</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();
2024-04-08 17:32:12 +02:00
const { commentCid, subplebbitAddress } = params;
const isInSettigsView = isSettingsView(location.pathname, params);
2024-05-09 16:04:24 +02:00
const isInDescriptionView = isDescriptionView(location.pathname, params);
const isInRulesView = isRulesView(location.pathname, params);
2024-04-08 17:32:12 +02:00
const subplebbit = useSubplebbit({ subplebbitAddress });
const { createdAt, description, rules, shortAddress, suggested, title } = subplebbit;
2024-04-08 17:32:12 +02:00
const { activeCid, threadCid, closeModal, openReplyModal, showReplyModal, scrollY, subplebbitAddress: postSubplebbitAddress } = useReplyModal();
2024-06-15 12:37:45 +02:00
const comment = useComment({ commentCid });
// 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
2024-07-07 19:12:12 +02:00
const { error, deleted, locked, removed, replyCount } = post || {};
const isThreadClosed = deleted || locked || removed;
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);
document.title = (postTitle ? postTitle.trim() + '... - ' : '') + boardTitle + ' - plebchan';
}, [title, shortAddress, subplebbitAddress, post?.title, post?.content]);
2024-04-02 17:00:36 +02:00
return (
<div className={styles.content}>
{isInSettigsView && <SettingsModal />}
{activeCid && threadCid && postSubplebbitAddress && (
<ReplyModal
closeModal={closeModal}
parentCid={activeCid}
postCid={threadCid}
scrollY={scrollY}
showReplyModal={showReplyModal}
subplebbitAddress={postSubplebbitAddress}
/>
)}
2024-07-07 19:12:12 +02:00
{/* TODO: remove this replyCount error once api supports scrolling replies pages */}
{replyCount > 60 && <span className={styles.error}>Error: this thread has too many replies, some of them cannot be displayed right now.</span>}
{error && <span className={styles.error}>Error: {error.message}</span>}
2024-04-08 17:32:12 +02:00
{isInDescriptionView ? (
<SubplebbitDescription
avatarUrl={suggested?.avatarUrl}
createdAt={createdAt}
description={description}
2024-09-18 12:37:39 +02:00
replyCount={location.pathname.startsWith('/p/all/') ? 0 : rules?.length > 0 ? 1 : 0}
subplebbitAddress={subplebbitAddress}
shortAddress={shortAddress}
title={title}
/>
2024-04-08 17:32:12 +02:00
) : isInRulesView ? (
<SubplebbitRules createdAt={createdAt} rules={rules} subplebbitAddress={subplebbitAddress} />
2024-04-08 17:32:12 +02:00
) : (
<Post post={post} showAllReplies={true} openReplyModal={isThreadClosed ? () => alert(t('thread_closed_alert')) : openReplyModal} />
2024-04-08 17:32:12 +02:00
)}
2024-04-02 17:00:36 +02:00
</div>
);
};
export default PostPage;