isMod,
} from "@utils/roles";
import classNames from "classnames";
+import isBefore from "date-fns/isBefore";
+import parseISO from "date-fns/parseISO";
+import subMinutes from "date-fns/subMinutes";
import { Component, InfernoNode, linkEvent } from "inferno";
import { Link } from "inferno-router";
import {
SaveComment,
TransferCommunity,
} from "lemmy-js-client";
-import moment from "moment";
+import deepEqual from "lodash.isequal";
import { commentTreeMaxDepth } from "../../config";
import {
BanType,
CommentNodeI,
CommentViewType,
PurgeType,
+ VoteContentType,
} from "../../interfaces";
import { mdToHtml, mdToHtmlNoImages } from "../../markdown";
import { I18NextService, UserService } from "../../services";
import { setupTippy } from "../../tippy";
import { Icon, PurgeWarning, Spinner } from "../common/icon";
import { MomentTime } from "../common/moment-time";
+import { UserBadges } from "../common/user-badges";
import { VoteButtonsCompact } from "../common/vote-buttons";
import { CommunityLink } from "../community/community-link";
import { PersonListing } from "../person/person-listing";
moderators?: CommunityModeratorView[];
admins?: PersonView[];
noBorder?: boolean;
- noIndent?: boolean;
+ isTopLevel?: boolean;
viewOnly?: boolean;
locked?: boolean;
markable?: boolean;
componentWillReceiveProps(
nextProps: Readonly<{ children?: InfernoNode } & CommentNodeProps>
): void {
- if (this.props != nextProps) {
+ if (!deepEqual(this.props, nextProps)) {
this.setState({
showReply: false,
showEdit: false,
mark: this.isCommentNew || this.commentView.comment.distinguished,
})}
>
- <div
- className={classNames({
- "ms-2": !this.props.noIndent,
- })}
- >
+ <div className="ms-2">
<div className="d-flex flex-wrap align-items-center text-muted small">
<button
- className="btn btn-sm text-muted me-2"
+ className="btn btn-sm btn-link text-muted me-2"
onClick={linkEvent(this, this.handleCommentCollapse)}
aria-label={this.expandText}
data-tippy-content={this.expandText}
classes="icon-inline"
/>
</button>
- <span className="me-2">
- <PersonListing person={cv.creator} />
- </span>
+
+ <PersonListing person={cv.creator} />
+
{cv.comment.distinguished && (
- <Icon icon="shield" inline classes={`text-danger me-2`} />
- )}
- {this.isPostCreator && (
- <div className="badge text-bg-light d-none d-sm-inline me-2">
- {I18NextService.i18n.t("creator")}
- </div>
- )}
- {isMod_ && (
- <div className="badge text-bg-light d-none d-sm-inline me-2">
- {I18NextService.i18n.t("mod")}
- </div>
- )}
- {isAdmin_ && (
- <div className="badge text-bg-light d-none d-sm-inline me-2">
- {I18NextService.i18n.t("admin")}
- </div>
- )}
- {cv.creator.bot_account && (
- <div className="badge text-bg-light d-none d-sm-inline me-2">
- {I18NextService.i18n.t("bot_account").toLowerCase()}
- </div>
+ <Icon icon="shield" inline classes="text-danger ms-1" />
)}
+
+ <UserBadges
+ classNames="ms-1"
+ isPostCreator={this.isPostCreator}
+ isMod={isMod_}
+ isAdmin={isAdmin_}
+ isBot={cv.creator.bot_account}
+ />
+
{this.props.showCommunity && (
<>
<span className="mx-1">{I18NextService.i18n.t("to")}</span>
</Link>
</>
)}
- {this.linkBtn(true)}
+
+ {this.getLinkButton(true)}
+
{cv.comment.language_id !== 0 && (
<span className="badge text-bg-light d-none d-sm-inline me-2">
{
{showScores() && (
<>
<span
- className="me-1 font-weight-bold"
+ className="me-1 fw-bold"
aria-label={I18NextService.i18n.t("number_of_points", {
count: Number(this.commentView.counts.score),
formattedCount: numToSI(this.commentView.counts.score),
}
/>
)}
- <div className="d-flex justify-content-between justify-content-lg-start flex-wrap text-muted font-weight-bold">
- {this.props.showContext && this.linkBtn()}
+ <div className="d-flex justify-content-between justify-content-lg-start flex-wrap text-muted fw-bold">
+ {this.props.showContext && this.getLinkButton()}
{this.props.markable && (
<button
className="btn btn-link btn-animate text-muted"
{UserService.Instance.myUserInfo && !this.props.viewOnly && (
<>
<VoteButtonsCompact
+ voteContentType={VoteContentType.Comment}
id={this.commentView.comment.id}
onVote={this.props.onCommentVote}
enableDownvotes={this.props.enableDownvotes}
allLanguages={this.props.allLanguages}
siteLanguages={this.props.siteLanguages}
hideImages={this.props.hideImages}
- isChild={!this.props.noIndent}
+ isChild={!this.props.isTopLevel}
depth={this.props.node.depth + 1}
finished={this.props.finished}
onCommentReplyRead={this.props.onCommentReplyRead}
}
}
- linkBtn(small = false) {
+ getLinkButton(small = false) {
const cv = this.commentView;
const classnames = classNames("btn btn-link btn-animate text-muted", {
}
get isCommentNew(): boolean {
- const now = moment.utc().subtract(10, "minutes");
- const then = moment.utc(this.commentView.comment.published);
- return now.isBefore(then);
+ const now = subMinutes(new Date(), 10);
+ const then = parseISO(this.commentView.comment.published);
+ return isBefore(now, then);
}
handleCommentCollapse(i: CommentNode) {
comment_id: i.commentId,
removed: !i.commentView.comment.removed,
auth: myAuthRequired(),
+ reason: i.state.removeReason,
});
}