]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/common/vote-buttons.tsx
Merge remote-tracking branch 'lemmy/main' into fix/wider-max-width-1536
[lemmy-ui.git] / src / shared / components / common / vote-buttons.tsx
index dce46f5bc664615d95c1513b714e9bca42be9b44..ff12125f21328f33fa5fed7e26e050081802b390 100644 (file)
@@ -1,19 +1,22 @@
-import { showScores } from "@utils/app";
+import { myAuthRequired, newVote, showScores } from "@utils/app";
 import { numToSI } from "@utils/helpers";
 import classNames from "classnames";
 import { Component, linkEvent } from "inferno";
-import { CommentAggregates, PostAggregates } from "lemmy-js-client";
+import {
+  CommentAggregates,
+  CreateCommentLike,
+  CreatePostLike,
+  PostAggregates,
+} from "lemmy-js-client";
+import { VoteContentType, VoteType } from "../../interfaces";
 import { I18NextService } from "../../services";
 import { Icon, Spinner } from "../common/icon";
-import { PostListing } from "../post/post-listing";
 
 interface VoteButtonsProps {
-  postListing: PostListing;
+  voteContentType: VoteContentType;
+  id: number;
+  onVote: (i: CreateCommentLike | CreatePostLike) => void;
   enableDownvotes?: boolean;
-  upvoteLoading?: boolean;
-  downvoteLoading?: boolean;
-  handleUpvote: (i: PostListing) => void;
-  handleDownvote: (i: PostListing) => void;
   counts: CommentAggregates | PostAggregates;
   my_vote?: number;
 }
@@ -23,6 +26,69 @@ interface VoteButtonsState {
   downvoteLoading: boolean;
 }
 
+const tippy = (counts: CommentAggregates | PostAggregates): string => {
+  const points = I18NextService.i18n.t("number_of_points", {
+    count: Number(counts.score),
+    formattedCount: Number(counts.score),
+  });
+
+  const upvotes = I18NextService.i18n.t("number_of_upvotes", {
+    count: Number(counts.upvotes),
+    formattedCount: Number(counts.upvotes),
+  });
+
+  const downvotes = I18NextService.i18n.t("number_of_downvotes", {
+    count: Number(counts.downvotes),
+    formattedCount: Number(counts.downvotes),
+  });
+
+  return `${points} • ${upvotes} • ${downvotes}`;
+};
+
+const handleUpvote = (i: VoteButtons) => {
+  i.setState({ upvoteLoading: true });
+
+  switch (i.props.voteContentType) {
+    case VoteContentType.Comment:
+      i.props.onVote({
+        comment_id: i.props.id,
+        score: newVote(VoteType.Upvote, i.props.my_vote),
+        auth: myAuthRequired(),
+      });
+      break;
+    case VoteContentType.Post:
+    default:
+      i.props.onVote({
+        post_id: i.props.id,
+        score: newVote(VoteType.Upvote, i.props.my_vote),
+        auth: myAuthRequired(),
+      });
+  }
+
+  i.setState({ upvoteLoading: false });
+};
+
+const handleDownvote = (i: VoteButtons) => {
+  i.setState({ downvoteLoading: true });
+  switch (i.props.voteContentType) {
+    case VoteContentType.Comment:
+      i.props.onVote({
+        comment_id: i.props.id,
+        score: newVote(VoteType.Downvote, i.props.my_vote),
+        auth: myAuthRequired(),
+      });
+      break;
+    case VoteContentType.Post:
+    default:
+      i.props.onVote({
+        post_id: i.props.id,
+        score: newVote(VoteType.Downvote, i.props.my_vote),
+        auth: myAuthRequired(),
+      });
+  }
+  i.setState({ downvoteLoading: false });
+};
+
 export class VoteButtonsCompact extends Component<
   VoteButtonsProps,
   VoteButtonsState
@@ -36,38 +102,16 @@ export class VoteButtonsCompact extends Component<
     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 (
       <div>
         <button
+          type="button"
           className={`btn-animate btn py-0 px-1 ${
             this.props.my_vote === 1 ? "text-info" : "text-muted"
           }`}
-          {...this.tippy}
-          onClick={linkEvent(this.props.postListing, this.props.handleUpvote)}
+          data-tippy-content={tippy(this.props.counts)}
+          onClick={linkEvent(thishandleUpvote)}
           aria-label={I18NextService.i18n.t("upvote")}
           aria-pressed={this.props.my_vote === 1}
         >
@@ -86,14 +130,12 @@ export class VoteButtonsCompact extends Component<
         </button>
         {this.props.enableDownvotes && (
           <button
+            type="button"
             className={`ms-2 btn-animate btn py-0 px-1 ${
               this.props.my_vote === -1 ? "text-danger" : "text-muted"
             }`}
-            onClick={linkEvent(
-              this.props.postListing,
-              this.props.handleDownvote
-            )}
-            {...this.tippy}
+            onClick={linkEvent(this, handleDownvote)}
+            data-tippy-content={tippy(this.props.counts)}
             aria-label={I18NextService.i18n.t("downvote")}
             aria-pressed={this.props.my_vote === -1}
           >
@@ -130,37 +172,15 @@ export class VoteButtons extends Component<VoteButtonsProps, VoteButtonsState> {
     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 (
-      <div className={`vote-bar col-1 pe-0 small text-center`}>
+      <div className="vote-bar pe-0 small text-center">
         <button
+          type="button"
           className={`btn-animate btn btn-link p-0 ${
             this.props.my_vote == 1 ? "text-info" : "text-muted"
           }`}
-          onClick={linkEvent(this.props.postListing, this.props.handleUpvote)}
+          onClick={linkEvent(thishandleUpvote)}
           data-tippy-content={I18NextService.i18n.t("upvote")}
           aria-label={I18NextService.i18n.t("upvote")}
           aria-pressed={this.props.my_vote === 1}
@@ -173,8 +193,8 @@ export class VoteButtons extends Component<VoteButtonsProps, VoteButtonsState> {
         </button>
         {showScores() ? (
           <div
-            className={`unselectable pointer text-muted px-1 post-score`}
-            data-tippy-content={this.pointsTippy}
+            className="unselectable pointer text-muted px-1 post-score"
+            data-tippy-content={tippy(this.props.counts)}
           >
             {numToSI(this.props.counts.score)}
           </div>
@@ -183,13 +203,11 @@ export class VoteButtons extends Component<VoteButtonsProps, VoteButtonsState> {
         )}
         {this.props.enableDownvotes && (
           <button
+            type="button"
             className={`btn-animate btn btn-link p-0 ${
               this.props.my_vote == -1 ? "text-danger" : "text-muted"
             }`}
-            onClick={linkEvent(
-              this.props.postListing,
-              this.props.handleDownvote
-            )}
+            onClick={linkEvent(this, handleDownvote)}
             data-tippy-content={I18NextService.i18n.t("downvote")}
             aria-label={I18NextService.i18n.t("downvote")}
             aria-pressed={this.props.my_vote === -1}