X-Git-Url: http://these/git/?a=blobdiff_plain;f=src%2Fshared%2Fcomponents%2Fcomment%2Fcomment-node.tsx;h=c6b37fdb2636f8d1589704d5c3b687082c7236f6;hb=9869b911cf480ee88c7b1e7d2f689cc2e1c65157;hp=15c68f7517b95f8da7220e919652f39380a7b2ce;hpb=a07fc75972b3d7763a7122bbebd8924e4ac4344c;p=lemmy-ui.git diff --git a/src/shared/components/comment/comment-node.tsx b/src/shared/components/comment/comment-node.tsx index 15c68f7..c6b37fd 100644 --- a/src/shared/components/comment/comment-node.tsx +++ b/src/shared/components/comment/comment-node.tsx @@ -1,3 +1,11 @@ +import { + colorList, + getCommentParentId, + myAuth, + myAuthRequired, + showScores, +} from "@utils/app"; +import { futureDaysToUnixTime, numToSI } from "@utils/helpers"; import { amCommunityCreator, canAdmin, @@ -7,6 +15,9 @@ import { 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 { @@ -37,32 +48,22 @@ import { SaveComment, TransferCommunity, } from "lemmy-js-client"; -import moment from "moment"; -import { i18n } from "../../i18next"; +import deepEqual from "lodash.isequal"; +import { commentTreeMaxDepth } from "../../config"; import { BanType, CommentNodeI, CommentViewType, PurgeType, - VoteType, + VoteContentType, } from "../../interfaces"; -import { UserService } from "../../services"; -import { - colorList, - commentTreeMaxDepth, - futureDaysToUnixTime, - getCommentParentId, - mdToHtml, - mdToHtmlNoImages, - myAuth, - myAuthRequired, - newVote, - numToSI, - setupTippy, - showScores, -} from "../../utils"; +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"; import { CommentForm } from "./comment-form"; @@ -196,10 +197,21 @@ export class CommentNode extends Component { return this.commentView.comment.id; } + get hasBadges(): boolean { + const cv = this.commentView; + + return ( + this.isPostCreator || + isMod(cv.creator.id, this.props.moderators) || + isAdmin(cv.creator.id, this.props.admins) || + cv.creator.bot_account + ); + } + componentWillReceiveProps( nextProps: Readonly<{ children?: InfernoNode } & CommentNodeProps> ): void { - if (this.props != nextProps) { + if (!deepEqual(this.props, nextProps)) { this.setState({ showReply: false, showEdit: false, @@ -243,8 +255,8 @@ export class CommentNode extends Component { const purgeTypeText = this.state.purgeType == PurgeType.Comment - ? i18n.t("purge_comment") - : `${i18n.t("purge")} ${cv.creator.name}`; + ? I18NextService.i18n.t("purge_comment") + : `${I18NextService.i18n.t("purge")} ${cv.creator.name}`; const canMod_ = canMod( cv.creator.id, @@ -283,7 +295,7 @@ export class CommentNode extends Component { node.comment_view.counts.child_count > 0; return ( -
  • +
  • { classes="icon-inline" /> - - - + + + {cv.comment.distinguished && ( - - )} - {this.isPostCreator && ( -
    - {i18n.t("creator")} -
    - )} - {isMod_ && ( -
    - {i18n.t("mod")} -
    - )} - {isAdmin_ && ( -
    - {i18n.t("admin")} -
    - )} - {cv.creator.bot_account && ( -
    - {i18n.t("bot_account").toLowerCase()} -
    + )} + + + {this.props.showCommunity && ( <> - {i18n.t("to")} + {I18NextService.i18n.t("to")} • @@ -344,7 +345,9 @@ export class CommentNode extends Component { )} - {this.linkBtn(true)} + + {this.getLinkButton(true)} + {cv.comment.language_id !== 0 && ( { @@ -356,29 +359,18 @@ export class CommentNode extends Component { )} {/* This is an expanding spacer for mobile */}
    + {showScores() && ( <> - - {this.state.upvoteLoading ? ( - - ) : ( - - {numToSI(this.commentView.counts.score)} - - )} - + {numToSI(this.commentView.counts.score)} + • )} @@ -420,21 +412,21 @@ export class CommentNode extends Component { } /> )} -
    - {this.props.showContext && this.linkBtn()} +
    + {this.props.showContext && this.getLinkButton()} {this.props.markable && ( - {this.props.enableDownvotes && ( - - )} + @@ -517,8 +463,8 @@ export class CommentNode extends Component { @@ -529,7 +475,9 @@ export class CommentNode extends Component { @@ -539,10 +487,12 @@ export class CommentNode extends Component { this, this.handleShowReportDialog )} - data-tippy-content={i18n.t( + data-tippy-content={I18NextService.i18n.t( + "show_report_dialog" + )} + aria-label={I18NextService.i18n.t( "show_report_dialog" )} - aria-label={i18n.t("show_report_dialog")} > @@ -552,8 +502,10 @@ export class CommentNode extends Component { this, this.handleBlockPerson )} - data-tippy-content={i18n.t("block_user")} - aria-label={i18n.t("block_user")} + data-tippy-content={I18NextService.i18n.t( + "block_user" + )} + aria-label={I18NextService.i18n.t("block_user")} > {this.state.blockPersonLoading ? ( @@ -567,10 +519,14 @@ export class CommentNode extends Component { className="btn btn-link btn-animate text-muted" onClick={linkEvent(this, this.handleSaveComment)} data-tippy-content={ - cv.saved ? i18n.t("unsave") : i18n.t("save") + cv.saved + ? I18NextService.i18n.t("unsave") + : I18NextService.i18n.t("save") } aria-label={ - cv.saved ? i18n.t("unsave") : i18n.t("save") + cv.saved + ? I18NextService.i18n.t("unsave") + : I18NextService.i18n.t("save") } > {this.state.saveLoading ? ( @@ -587,8 +543,10 @@ export class CommentNode extends Component { @@ -615,13 +575,13 @@ export class CommentNode extends Component { )} data-tippy-content={ !cv.comment.deleted - ? i18n.t("delete") - : i18n.t("restore") + ? I18NextService.i18n.t("delete") + : I18NextService.i18n.t("restore") } aria-label={ !cv.comment.deleted - ? i18n.t("delete") - : i18n.t("restore") + ? I18NextService.i18n.t("delete") + : I18NextService.i18n.t("restore") } > {this.state.deleteLoading ? ( @@ -645,13 +605,13 @@ export class CommentNode extends Component { )} data-tippy-content={ !cv.comment.distinguished - ? i18n.t("distinguish") - : i18n.t("undistinguish") + ? I18NextService.i18n.t("distinguish") + : I18NextService.i18n.t("undistinguish") } aria-label={ !cv.comment.distinguished - ? i18n.t("distinguish") - : i18n.t("undistinguish") + ? I18NextService.i18n.t("distinguish") + : I18NextService.i18n.t("undistinguish") } > { this, this.handleModRemoveShow )} - aria-label={i18n.t("remove")} + aria-label={I18NextService.i18n.t("remove")} > - {i18n.t("remove")} + {I18NextService.i18n.t("remove")} ) : ( )} @@ -707,9 +667,13 @@ export class CommentNode extends Component { this, this.handleModBanFromCommunityShow )} - aria-label={i18n.t("ban_from_community")} + aria-label={I18NextService.i18n.t( + "ban_from_community" + )} > - {i18n.t("ban_from_community")} + {I18NextService.i18n.t( + "ban_from_community" + )} ) : ( ))} @@ -737,21 +701,25 @@ export class CommentNode extends Component { )} aria-label={ isMod_ - ? i18n.t("remove_as_mod") - : i18n.t("appoint_as_mod") + ? I18NextService.i18n.t("remove_as_mod") + : I18NextService.i18n.t( + "appoint_as_mod" + ) } > {isMod_ - ? i18n.t("remove_as_mod") - : i18n.t("appoint_as_mod")} + ? I18NextService.i18n.t("remove_as_mod") + : I18NextService.i18n.t("appoint_as_mod")} ) : ( <> ))} @@ -792,17 +760,21 @@ export class CommentNode extends Component { this, this.handleShowConfirmTransferCommunity )} - aria-label={i18n.t("transfer_community")} + aria-label={I18NextService.i18n.t( + "transfer_community" + )} > - {i18n.t("transfer_community")} + {I18NextService.i18n.t("transfer_community")} ) : ( <> ))} @@ -842,9 +814,11 @@ export class CommentNode extends Component { this, this.handlePurgePersonShow )} - aria-label={i18n.t("purge_user")} + aria-label={I18NextService.i18n.t( + "purge_user" + )} > - {i18n.t("purge_user")} + {I18NextService.i18n.t("purge_user")} {!isBanned(cv.creator) ? ( @@ -864,9 +840,11 @@ export class CommentNode extends Component { this, this.handleModBanShow )} - aria-label={i18n.t("ban_from_site")} + aria-label={I18NextService.i18n.t( + "ban_from_site" + )} > - {i18n.t("ban_from_site")} + {I18NextService.i18n.t("ban_from_site")} ) : ( )} @@ -897,18 +877,24 @@ export class CommentNode extends Component { )} aria-label={ isAdmin_ - ? i18n.t("remove_as_admin") - : i18n.t("appoint_as_admin") + ? I18NextService.i18n.t( + "remove_as_admin" + ) + : I18NextService.i18n.t( + "appoint_as_admin" + ) } > {isAdmin_ - ? i18n.t("remove_as_admin") - : i18n.t("appoint_as_admin")} + ? I18NextService.i18n.t("remove_as_admin") + : I18NextService.i18n.t( + "appoint_as_admin" + )} ) : ( <> ))} @@ -963,7 +949,7 @@ export class CommentNode extends Component { ) : ( <> - {i18n.t("x_more_replies", { + {I18NextService.i18n.t("x_more_replies", { count: node.comment_view.counts.child_count, formattedCount: numToSI( node.comment_view.counts.child_count @@ -985,22 +971,22 @@ export class CommentNode extends Component { className="visually-hidden" htmlFor={`mod-remove-reason-${cv.comment.id}`} > - {i18n.t("reason")} + {I18NextService.i18n.t("reason")} )} @@ -1013,23 +999,23 @@ export class CommentNode extends Component { className="visually-hidden" htmlFor={`report-reason-${cv.comment.id}`} > - {i18n.t("reason")} + {I18NextService.i18n.t("reason")} )} @@ -1040,13 +1026,13 @@ export class CommentNode extends Component { className="col-form-label" htmlFor={`mod-ban-reason-${cv.comment.id}`} > - {i18n.t("reason")} + {I18NextService.i18n.t("reason")} @@ -1054,13 +1040,13 @@ export class CommentNode extends Component { className="col-form-label" htmlFor={`mod-ban-expires-${cv.comment.id}`} > - {i18n.t("expires")} + {I18NextService.i18n.t("expires")} @@ -1076,9 +1062,9 @@ export class CommentNode extends Component {
    @@ -1086,19 +1072,19 @@ export class CommentNode extends Component { {/* TODO hold off on expires until later */} {/*
    */} {/* */} - {/* */} + {/* */} {/*
    */}
    @@ -1110,13 +1096,13 @@ export class CommentNode extends Component {
    @@ -1203,7 +1189,7 @@ export class CommentNode extends Component { } } - linkBtn(small = false) { + getLinkButton(small = false) { const cv = this.commentView; const classnames = classNames("btn btn-link btn-animate text-muted", { @@ -1211,8 +1197,8 @@ export class CommentNode extends Component { }); const title = this.props.showContext - ? i18n.t("show_context") - : i18n.t("link"); + ? I18NextService.i18n.t("show_context") + : I18NextService.i18n.t("link"); // The context button should show the parent comment by default const parentCommentId = getCommentParentId(cv.comment) ?? cv.comment.id; @@ -1257,17 +1243,17 @@ export class CommentNode extends Component { } get pointsTippy(): string { - const points = i18n.t("number_of_points", { + const points = I18NextService.i18n.t("number_of_points", { count: Number(this.commentView.counts.score), formattedCount: numToSI(this.commentView.counts.score), }); - const upvotes = i18n.t("number_of_upvotes", { + const upvotes = I18NextService.i18n.t("number_of_upvotes", { count: Number(this.commentView.counts.upvotes), formattedCount: numToSI(this.commentView.counts.upvotes), }); - const downvotes = i18n.t("number_of_downvotes", { + const downvotes = I18NextService.i18n.t("number_of_downvotes", { count: Number(this.commentView.counts.downvotes), formattedCount: numToSI(this.commentView.counts.downvotes), }); @@ -1276,15 +1262,17 @@ export class CommentNode extends Component { } get expandText(): string { - return this.state.collapsed ? i18n.t("expand") : i18n.t("collapse"); + return this.state.collapsed + ? I18NextService.i18n.t("expand") + : I18NextService.i18n.t("collapse"); } get commentUnlessRemoved(): string { const comment = this.commentView.comment; return comment.removed - ? `*${i18n.t("removed")}*` + ? `*${I18NextService.i18n.t("removed")}*` : comment.deleted - ? `*${i18n.t("deleted")}*` + ? `*${I18NextService.i18n.t("deleted")}*` : comment.content; } @@ -1412,9 +1400,9 @@ export class CommentNode extends Component { } 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) { @@ -1441,24 +1429,6 @@ export class CommentNode extends Component { }); } - handleUpvote(i: CommentNode) { - i.setState({ upvoteLoading: true }); - i.props.onCommentVote({ - comment_id: i.commentId, - score: newVote(VoteType.Upvote, i.commentView.my_vote), - auth: myAuthRequired(), - }); - } - - handleDownvote(i: CommentNode) { - i.setState({ downvoteLoading: true }); - i.props.onCommentVote({ - comment_id: i.commentId, - score: newVote(VoteType.Downvote, i.commentView.my_vote), - auth: myAuthRequired(), - }); - } - handleBlockPerson(i: CommentNode) { i.setState({ blockPersonLoading: true }); i.props.onBlockPerson({