From b6d152248043ccb2cc646fe5582939c065b117a7 Mon Sep 17 00:00:00 2001
From: Lim Chee Aun <cheeaun@gmail.com>
Date: Wed, 27 Nov 2024 22:16:28 +0800
Subject: [PATCH] Fix clicking outside button also trigger the menu

---
 src/components/status.jsx | 108 +++++++++++++++++++-------------------
 1 file changed, 55 insertions(+), 53 deletions(-)

diff --git a/src/components/status.jsx b/src/components/status.jsx
index 3669f229..7c251c9f 100644
--- a/src/components/status.jsx
+++ b/src/components/status.jsx
@@ -15,7 +15,7 @@ import { shallowEqual } from 'fast-equals';
 import prettify from 'html-prettify';
 import pThrottle from 'p-throttle';
 import { Fragment } from 'preact';
-import { memo } from 'preact/compat';
+import { forwardRef, memo } from 'preact/compat';
 import {
   useCallback,
   useContext,
@@ -2403,42 +2403,42 @@ function Status({
                   disabled={!canBoost}
                 />
               </div> */}
-                <MenuConfirm
-                  disabled={!canBoost}
-                  onClick={confirmBoostStatus}
-                  confirmLabel={
-                    <>
-                      <Icon icon="rocket" />
-                      <span>{reblogged ? t`Unboost` : t`Boost`}</span>
-                    </>
-                  }
-                  menuExtras={
-                    <MenuItem
-                      onClick={() => {
-                        showCompose({
-                          draftStatus: {
-                            status: `\n${url}`,
-                          },
-                        });
-                      }}
-                    >
-                      <Icon icon="quote" />
-                      <span>
-                        <Trans>Quote</Trans>
-                      </span>
-                    </MenuItem>
-                  }
-                  menuFooter={
-                    mediaNoDesc &&
-                    !reblogged && (
-                      <div class="footer">
-                        <Icon icon="alert" />
-                        <Trans>Some media have no descriptions.</Trans>
-                      </div>
-                    )
-                  }
-                >
-                  <div class="action has-count">
+                <div class="action has-count">
+                  <MenuConfirm
+                    disabled={!canBoost}
+                    onClick={confirmBoostStatus}
+                    confirmLabel={
+                      <>
+                        <Icon icon="rocket" />
+                        <span>{reblogged ? t`Unboost` : t`Boost`}</span>
+                      </>
+                    }
+                    menuExtras={
+                      <MenuItem
+                        onClick={() => {
+                          showCompose({
+                            draftStatus: {
+                              status: `\n${url}`,
+                            },
+                          });
+                        }}
+                      >
+                        <Icon icon="quote" />
+                        <span>
+                          <Trans>Quote</Trans>
+                        </span>
+                      </MenuItem>
+                    }
+                    menuFooter={
+                      mediaNoDesc &&
+                      !reblogged && (
+                        <div class="footer">
+                          <Icon icon="alert" />
+                          <Trans>Some media have no descriptions.</Trans>
+                        </div>
+                      )
+                    }
+                  >
                     <StatusButton
                       checked={reblogged}
                       title={[t`Boost`, t`Unboost`]}
@@ -2449,8 +2449,8 @@ function Status({
                       // onClick={boostStatus}
                       disabled={!canBoost}
                     />
-                  </div>
-                </MenuConfirm>
+                  </MenuConfirm>
+                </div>
                 <div class="action has-count">
                   <StatusButton
                     checked={favourited}
@@ -3426,18 +3426,19 @@ function EmbedModal({ post, instance, onClose }) {
   );
 }
 
-function StatusButton({
-  checked,
-  count,
-  class: className,
-  title,
-  alt,
-  size,
-  icon,
-  iconSize = 'l',
-  onClick,
-  ...props
-}) {
+const StatusButton = forwardRef((props, ref) => {
+  let {
+    checked,
+    count,
+    class: className,
+    title,
+    alt,
+    size,
+    icon,
+    iconSize = 'l',
+    onClick,
+    ...otherProps
+  } = props;
   if (typeof title === 'string') {
     title = [title, title];
   }
@@ -3460,6 +3461,7 @@ function StatusButton({
 
   return (
     <button
+      ref={ref}
       type="button"
       title={buttonTitle}
       class={`plain ${size ? 'small' : ''} ${className} ${
@@ -3471,7 +3473,7 @@ function StatusButton({
         e.stopPropagation();
         onClick(e);
       }}
-      {...props}
+      {...otherProps}
     >
       <Icon icon={icon} size={iconSize} alt={iconAlt} />
       {!!count && (
@@ -3482,7 +3484,7 @@ function StatusButton({
       )}
     </button>
   );
-}
+});
 
 function nicePostURL(url) {
   if (!url) return;