From: Jay Sitter Date: Thu, 22 Jun 2023 17:36:38 +0000 (-0400) Subject: feat: Move vote buttons to separate component X-Git-Url: http://these/git/%7Bthis.props.banner%7D?a=commitdiff_plain;h=7c13b8dba16452d777dc96494ef90349bc35bf8c;p=lemmy-ui.git feat: Move vote buttons to separate component --- diff --git a/src/shared/components/common/vote-buttons.tsx b/src/shared/components/common/vote-buttons.tsx new file mode 100644 index 0000000..2bbddad --- /dev/null +++ b/src/shared/components/common/vote-buttons.tsx @@ -0,0 +1,207 @@ +import { showScores } from "@utils/app"; +import { numToSI } from "@utils/helpers"; +import { Component, linkEvent } from "inferno"; +import { CommentAggregates, PostAggregates } from "lemmy-js-client"; +import { I18NextService } from "../../services"; +import { Icon, Spinner } from "../common/icon"; +import { PostListing } from "../post/post-listing"; + +interface VoteButtonsProps { + postListing: PostListing; + enableDownvotes?: boolean; + upvoteLoading?: boolean; + downvoteLoading?: boolean; + handleUpvote: (i: PostListing) => void; + handleDownvote: (i: PostListing) => void; + counts: CommentAggregates | PostAggregates; + my_vote?: number; +} + +interface VoteButtonsState { + upvoteLoading: boolean; + downvoteLoading: boolean; +} + +export class VoteButtonsCompact extends Component< + VoteButtonsProps, + VoteButtonsState +> { + state: VoteButtonsState = { + upvoteLoading: false, + downvoteLoading: false, + }; + + constructor(props: any, context: any) { + super(props, context); + } + + get pointsTippy(): string { + const points = I18NextService.i18n.t("number_of_points", { + count: Number(this.props.counts.score), + formattedCount: Number(this.props.counts.score), + }); + + const upvotes = I18NextService.i18n.t("number_of_upvotes", { + count: Number(this.props.counts.upvotes), + formattedCount: Number(this.props.counts.upvotes), + }); + + const downvotes = I18NextService.i18n.t("number_of_downvotes", { + count: Number(this.props.counts.downvotes), + formattedCount: Number(this.props.counts.downvotes), + }); + + return `${points} • ${upvotes} • ${downvotes}`; + } + + get tippy() { + return showScores() ? { "data-tippy-content": this.pointsTippy } : {}; + } + + render() { + return ( + <> +
+ + + {numToSI(this.props.counts.score)} + + {this.props.enableDownvotes && ( + + )} +
+ + ); + } +} + +export class VoteButtons extends Component { + state: VotesState = { + upvoteLoading: false, + downvoteLoading: false, + }; + + constructor(props: any, context: any) { + super(props, context); + } + + get pointsTippy(): string { + const points = I18NextService.i18n.t("number_of_points", { + count: Number(this.props.counts.score), + formattedCount: Number(this.props.counts.score), + }); + + const upvotes = I18NextService.i18n.t("number_of_upvotes", { + count: Number(this.props.counts.upvotes), + formattedCount: Number(this.props.counts.upvotes), + }); + + const downvotes = I18NextService.i18n.t("number_of_downvotes", { + count: Number(this.props.counts.downvotes), + formattedCount: Number(this.props.counts.downvotes), + }); + + return `${points} • ${upvotes} • ${downvotes}`; + } + + get tippy() { + return showScores() ? { "data-tippy-content": this.pointsTippy } : {}; + } + + render() { + return ( +
+ + {showScores() ? ( +
+ {numToSI(this.props.counts.score)} +
+ ) : ( +
+ )} + {this.props.enableDownvotes && ( + + )} +
+ ); + } +} diff --git a/src/shared/components/post/post-listing.tsx b/src/shared/components/post/post-listing.tsx index 4d0951b..7eed489 100644 --- a/src/shared/components/post/post-listing.tsx +++ b/src/shared/components/post/post-listing.tsx @@ -1,11 +1,10 @@ -import { myAuthRequired, newVote, showScores } from "@utils/app"; +import { myAuthRequired, newVote } from "@utils/app"; import { canShare, share } from "@utils/browser"; import { getExternalHost, getHttpBase } from "@utils/env"; import { capitalizeFirstLetter, futureDaysToUnixTime, hostname, - numToSI, } from "@utils/helpers"; import { isImage, isVideo } from "@utils/media"; import { @@ -51,6 +50,7 @@ import { setupTippy } from "../../tippy"; import { Icon, PurgeWarning, Spinner } from "../common/icon"; import { MomentTime } from "../common/moment-time"; import { PictrsImage } from "../common/pictrs-image"; +import { VoteButtons, VoteButtonsCompact } from "../common/vote-buttons"; import { CommunityLink } from "../community/community-link"; import { PersonListing } from "../person/person-listing"; import { MetadataCard } from "./metadata-card"; @@ -413,55 +413,6 @@ export class PostListing extends Component { ); } - voteBar() { - return ( -
- - {showScores() ? ( -
- {numToSI(this.postView.counts.score)} -
- ) : ( -
- )} - {this.props.enableDownvotes && ( - - )} -
- ); - } - get postLink() { const post = this.postView.post; return ( @@ -641,7 +592,16 @@ export class PostListing extends Component { )} - {mobile && !this.props.viewOnly && this.mobileVotes} + {mobile && !this.props.viewOnly && ( + + )} {UserService.Instance.myUserInfo && !this.props.viewOnly && this.postActions()} @@ -679,7 +639,6 @@ export class PostListing extends Component { return ( <> {this.saveButton} - {this.crossPostButton} {/** * If there is a URL, or if the post has a body and we were told not to @@ -704,6 +663,11 @@ export class PostListing extends Component {
    +
  • {this.crossPostButton}
  • +
  • +
    +
  • + {!this.myPost ? ( <>
  • {this.reportButton}
  • @@ -770,69 +734,6 @@ export class PostListing extends Component { : pv.unread_comments; } - get mobileVotes() { - // TODO: make nicer - const tippy = showScores() - ? { "data-tippy-content": this.pointsTippy } - : {}; - return ( - <> -
    - - {this.props.enableDownvotes && ( - - )} -
    - - ); - } - get saveButton() { const saved = this.postView.saved; const label = saved @@ -861,7 +762,7 @@ export class PostListing extends Component { get crossPostButton() { return ( { data-tippy-content={I18NextService.i18n.t("cross_post")} aria-label={I18NextService.i18n.t("cross_post")} > - + + {I18NextService.i18n.t("cross_post")} ); } @@ -931,7 +833,6 @@ export class PostListing extends Component {