web/front/CommentList.tsx
import React from 'react'
import { useRouter } from 'next/router'
import Link from 'next/link'
import lodash from 'lodash'
import Comment from 'front/Comment'
import Pagination from 'front/Pagination'
import UserLinkWithImage from 'front/UserLinkWithImage'
import {
DiscussionIcon,
TimeIcon,
UnlistedIcon,
UserIcon,
} from 'front'
import { getCommentSlug, TRI_ALL, TRI_FALSE } from 'front/js'
import { articleLimit } from 'front/config'
import routes from 'front/routes'
import ShowBody from 'front/ShowBody'
import { formatDate } from 'ourbigbook'
import { encodeGetParams, QUERY_FALSE_VAL, QUERY_TRUE_VAL } from 'ourbigbook/web_api'
import { CommentType } from 'front/types/CommentType'
import { UserType } from 'front/types/UserType'
export type CommentListProps = {
comments?: CommentType[];
commentsCount?: number;
hasUnlisted?: boolean;
list?: boolean;
loggedInUser?: UserType;
page: number;
showAuthor?: boolean;
showBody?: boolean;
showBodyControl?: boolean;
showControls?: boolean;
showFullBody?: boolean;
showFullSlug?: boolean;
}
const CommentList = ({
comments,
commentsCount,
hasUnlisted,
list,
loggedInUser,
page,
showAuthor=true,
showBody=true,
showBodyControl=true,
showControls=true,
showFullBody=false,
showFullSlug=true,
}: CommentListProps) => {
const router = useRouter();
const { pathname, query } = router
let showBodyInit
if (query.body === QUERY_TRUE_VAL) {
showBodyInit = true
} else if (query.body === QUERY_FALSE_VAL) {
showBodyInit = false
} else {
showBodyInit = showBody
}
const [showBodyState, setShowBodyState] = React.useState(showBodyInit)
const resetShowBodyGetString = encodeGetParams(lodash.omit(query, 'body'))
React.useEffect(() => {
// Reset on tab change.
setShowBodyState(showBodyInit)
}, [pathname, resetShowBodyGetString, showBodyInit])
let pagination
if (showControls) {
pagination = <Pagination {...{
itemsCount: commentsCount,
itemsPerPage: articleLimit,
currentPage: page,
what: 'comments'
}} />
} else {
pagination = <></>
}
return (
<div className="comment-list">
{ commentsCount === 0
? <div className="article-preview content-not-ourbigbook">
There are currently no matching comments.
</div>
: <div className="list-nav-container">
{(showControls && showBodyControl) &&
<div className="content-not-ourbigbook controls">
{<ShowBody {...{ setShowBodyState, showBody, showBodyState }}/>}
</div>
}
<div className="content-not-ourbigbook">
<div className={`list-container${showBodyState ? ' show-body' : ''}`}>
{showBodyState
? <>
{comments?.map((comment: CommentType) => <Comment
key={showFullSlug ? getCommentSlug(comment) : comment.number}
{...{
comment,
loggedInUser,
showFullBody,
showFullSlug,
}} />
)}
</>
: <table className="list">
<thead>
<tr>
{showAuthor &&
<th className="shrink"><UserIcon /> Author</th>
}
<th className="shrink"><span className="icon">#</span> id</th>
{showFullSlug &&
<th className="expand"><DiscussionIcon /> Issue</th>
}
<th className="shrink"><TimeIcon /> Created</th>
</tr>
</thead>
<tbody>
{comments.map(comment => {
const issue = comment?.issue
const article = issue?.article
let slug
if (showFullSlug) {
slug = getCommentSlug(comment)
} else {
slug = comment.number
}
return <tr key={slug}>
{showAuthor &&
<td className="shrink">
<UserLinkWithImage showUsername={false} user={comment.author} />
</td>
}
<td className="shrink bold">
{showFullSlug
? <Link href={routes.issueComment(article.slug, issue.number, comment.number)}>
{slug}
</Link>
: <>{slug}</>
}
</td>
{showFullSlug &&
<td className="shrink bold">
<Link href={routes.issue(article.slug, issue.number)}>
<span
className="ourbigbook-title"
dangerouslySetInnerHTML={{ __html: issue.titleRender }}
/>
</Link>
</td>
}
<td className="shrink">{formatDate(comment.createdAt)}</td>
</tr>
})}
</tbody>
</table>
}
</div>
</div>
{pagination}
</div>
}
{hasUnlisted === true &&
<p className="content-not-ourbigbook">
<UnlistedIcon />{' '}
{list === true
? <>
There are unlisted comments,{' '}
<Link href={{ pathname, query: { ...query, listed: TRI_ALL } }}>
also show them
</Link>
{' '}or{' '}
<Link href={{ pathname, query: { ...query, listed: TRI_FALSE } }}>
only show them
</Link>.
</>
: <>
{list === false ? 'Only unlisted comments are being shown' : 'Unlisted comments are being shown'},
{' '}
<Link href={{ pathname, query: lodash.omit(query, 'listed') }}>
click here to show only listed comments
</Link>.
</>
}
</p>
}
</div>
)
}
export default CommentList;