From 094429ff1ee891236924545415d0c66e548871b3 Mon Sep 17 00:00:00 2001
From: Jay Sitter <jay@jaysitter.com>
Date: Thu, 22 Jun 2023 23:48:53 -0400
Subject: [PATCH] fix: Rework some vote buttons architecture

---
 src/shared/components/common/vote-buttons.tsx | 52 ++++++++++++-------
 src/shared/components/post/post-listing.tsx   | 36 +++----------
 2 files changed, 40 insertions(+), 48 deletions(-)

diff --git a/src/shared/components/common/vote-buttons.tsx b/src/shared/components/common/vote-buttons.tsx
index 20e8da2..bba82ba 100644
--- a/src/shared/components/common/vote-buttons.tsx
+++ b/src/shared/components/common/vote-buttons.tsx
@@ -1,19 +1,21 @@
-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 { VoteType } from "../../interfaces";
 import { I18NextService } from "../../services";
 import { Icon, Spinner } from "../common/icon";
-import { PostListing } from "../post/post-listing";
 
 interface VoteButtonsProps {
-  postListing: PostListing;
+  id: number;
+  onVote: (i: CreatePostLike | CreateCommentLike) => void;
   enableDownvotes?: boolean;
-  upvoteLoading?: boolean;
-  downvoteLoading?: boolean;
-  handleUpvote: (i: PostListing) => void;
-  handleDownvote: (i: PostListing) => void;
   counts: CommentAggregates | PostAggregates;
   my_vote?: number;
 }
@@ -42,6 +44,26 @@ const tippy = (counts: CommentAggregates | PostAggregates): string => {
   return `${points} • ${upvotes} • ${downvotes}`;
 };
 
+const handleUpvote = (i: VoteButtons) => {
+  i.setState({ upvoteLoading: true });
+  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 });
+  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
@@ -63,7 +85,7 @@ export class VoteButtonsCompact extends Component<
             this.props.my_vote === 1 ? "text-info" : "text-muted"
           }`}
           data-tippy-content={tippy(this.props.counts)}
-          onClick={linkEvent(this.props.postListing, this.props.handleUpvote)}
+          onClick={linkEvent(this, handleUpvote)}
           aria-label={I18NextService.i18n.t("upvote")}
           aria-pressed={this.props.my_vote === 1}
         >
@@ -85,10 +107,7 @@ export class VoteButtonsCompact extends Component<
             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
-            )}
+            onClick={linkEvent(this, handleDownvote)}
             data-tippy-content={tippy(this.props.counts)}
             aria-label={I18NextService.i18n.t("downvote")}
             aria-pressed={this.props.my_vote === -1}
@@ -133,7 +152,7 @@ export class VoteButtons extends Component<VoteButtonsProps, VoteButtonsState> {
           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(this, handleUpvote)}
           data-tippy-content={I18NextService.i18n.t("upvote")}
           aria-label={I18NextService.i18n.t("upvote")}
           aria-pressed={this.props.my_vote === 1}
@@ -159,10 +178,7 @@ export class VoteButtons extends Component<VoteButtonsProps, VoteButtonsState> {
             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}
diff --git a/src/shared/components/post/post-listing.tsx b/src/shared/components/post/post-listing.tsx
index 0340cf5..8e0cc28 100644
--- a/src/shared/components/post/post-listing.tsx
+++ b/src/shared/components/post/post-listing.tsx
@@ -1,4 +1,4 @@
-import { myAuthRequired, newVote } from "@utils/app";
+import { myAuthRequired } from "@utils/app";
 import { canShare, share } from "@utils/browser";
 import { getExternalHost, getHttpBase } from "@utils/env";
 import {
@@ -43,7 +43,7 @@ import {
   TransferCommunity,
 } from "lemmy-js-client";
 import { relTags } from "../../config";
-import { BanType, PostFormParams, PurgeType, VoteType } from "../../interfaces";
+import { BanType, PostFormParams, PurgeType } from "../../interfaces";
 import { mdNoImages, mdToHtml, mdToHtmlInline } from "../../markdown";
 import { I18NextService, UserService } from "../../services";
 import { setupTippy } from "../../tippy";
@@ -78,8 +78,6 @@ interface PostListingState {
   showBody: boolean;
   showReportDialog: boolean;
   reportReason?: string;
-  upvoteLoading: boolean;
-  downvoteLoading: boolean;
   reportLoading: boolean;
   blockLoading: boolean;
   lockLoading: boolean;
@@ -142,8 +140,6 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     showMoreMobile: false,
     showBody: false,
     showReportDialog: false,
-    upvoteLoading: false,
-    downvoteLoading: false,
     purgeLoading: false,
     reportLoading: false,
     blockLoading: false,
@@ -169,8 +165,6 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
   componentWillReceiveProps(nextProps: PostListingProps) {
     if (this.props !== nextProps) {
       this.setState({
-        upvoteLoading: false,
-        downvoteLoading: false,
         purgeLoading: false,
         reportLoading: false,
         blockLoading: false,
@@ -604,10 +598,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         )}
         {mobile && !this.props.viewOnly && (
           <VoteButtonsCompact
+            id={this.postView.post.id}
+            onVote={this.props.onPostVote}
             postListing={this}
             enableDownvotes={this.props.enableDownvotes}
-            handleUpvote={this.handleUpvote}
-            handleDownvote={this.handleDownvote}
             counts={this.postView.counts}
             my_vote={this.postView.my_vote}
           />
@@ -1387,10 +1381,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
           <article className="row post-container">
             {!this.props.viewOnly && (
               <VoteButtons
+                id={this.postView.post.id}
+                onVote={this.props.onPostVote}
                 postListing={this}
                 enableDownvotes={this.props.enableDownvotes}
-                handleUpvote={this.handleUpvote}
-                handleDownvote={this.handleDownvote}
                 counts={this.postView.counts}
                 my_vote={this.postView.my_vote}
               />
@@ -1759,24 +1753,6 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
     setupTippy();
   }
 
-  handleUpvote(i: PostListing) {
-    i.setState({ upvoteLoading: true });
-    i.props.onPostVote({
-      post_id: i.postView.post.id,
-      score: newVote(VoteType.Upvote, i.props.post_view.my_vote),
-      auth: myAuthRequired(),
-    });
-  }
-
-  handleDownvote(i: PostListing) {
-    i.setState({ downvoteLoading: true });
-    i.props.onPostVote({
-      post_id: i.postView.post.id,
-      score: newVote(VoteType.Downvote, i.props.post_view.my_vote),
-      auth: myAuthRequired(),
-    });
-  }
-
   get pointsTippy(): string {
     const points = I18NextService.i18n.t("number_of_points", {
       count: Number(this.postView.counts.score),
-- 
2.44.1