about summary refs log tree commit diff
path: root/src/view/com/util/forms/PostDropdownBtn.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/util/forms/PostDropdownBtn.tsx')
-rw-r--r--src/view/com/util/forms/PostDropdownBtn.tsx587
1 files changed, 309 insertions, 278 deletions
diff --git a/src/view/com/util/forms/PostDropdownBtn.tsx b/src/view/com/util/forms/PostDropdownBtn.tsx
index 1cd4841a5..e71332279 100644
--- a/src/view/com/util/forms/PostDropdownBtn.tsx
+++ b/src/view/com/util/forms/PostDropdownBtn.tsx
@@ -102,12 +102,77 @@ let PostDropdownBtn = ({
   timestamp: string
   threadgateRecord?: AppBskyFeedThreadgate.Record
 }): React.ReactNode => {
-  const {hasSession, currentAccount} = useSession()
   const theme = useTheme()
   const alf = useAlf()
-  const {gtMobile} = useBreakpoints()
   const {_} = useLingui()
   const defaultCtrlColor = theme.palette.default.postCtrl
+  return (
+    <EventStopper onKeyDown={false}>
+      <Menu.Root>
+        <Menu.Trigger label={_(msg`Open post options menu`)}>
+          {({props, state}) => {
+            return (
+              <Pressable
+                {...props}
+                hitSlop={hitSlop}
+                testID={testID}
+                style={[
+                  style,
+                  a.rounded_full,
+                  (state.hovered || state.pressed) && [
+                    alf.atoms.bg_contrast_25,
+                  ],
+                ]}>
+                <DotsHorizontal
+                  fill={defaultCtrlColor}
+                  style={{pointerEvents: 'none'}}
+                  size={size}
+                />
+              </Pressable>
+            )
+          }}
+        </Menu.Trigger>
+        <Menu.Outer>
+          <PostDropdownMenuItems
+            testID={testID}
+            post={post}
+            postFeedContext={postFeedContext}
+            record={record}
+            richText={richText}
+            timestamp={timestamp}
+            threadgateRecord={threadgateRecord}
+          />
+        </Menu.Outer>
+      </Menu.Root>
+    </EventStopper>
+  )
+}
+
+PostDropdownBtn = memo(PostDropdownBtn)
+export {PostDropdownBtn}
+
+let PostDropdownMenuItems = ({
+  post,
+  postFeedContext,
+  record,
+  richText,
+  timestamp,
+  threadgateRecord,
+}: {
+  testID: string
+  post: Shadow<AppBskyFeedDefs.PostView>
+  postFeedContext: string | undefined
+  record: AppBskyFeedPost.Record
+  richText: RichTextAPI
+  style?: StyleProp<ViewStyle>
+  hitSlop?: PressableProps['hitSlop']
+  size?: 'lg' | 'md' | 'sm'
+  timestamp: string
+  threadgateRecord?: AppBskyFeedThreadgate.Record
+}): React.ReactNode => {
+  const {hasSession, currentAccount} = useSession()
+  const {gtMobile} = useBreakpoints()
+  const {_} = useLingui()
   const langPrefs = useLanguagePrefs()
   const {mutateAsync: deletePostMutate} = usePostDeleteMutation()
   const {mutateAsync: pinPostMutate, isPending: isPinPending} =
@@ -360,308 +425,276 @@ let PostDropdownBtn = ({
   }, [isPinned, pinPostMutate, postCid, postUri])
 
   return (
-    <EventStopper onKeyDown={false}>
-      <Menu.Root>
-        <Menu.Trigger label={_(msg`Open post options menu`)}>
-          {({props, state}) => {
-            return (
-              <Pressable
-                {...props}
-                hitSlop={hitSlop}
-                testID={testID}
-                style={[
-                  style,
-                  a.rounded_full,
-                  (state.hovered || state.pressed) && [
-                    alf.atoms.bg_contrast_25,
-                  ],
-                ]}>
-                <DotsHorizontal
-                  fill={defaultCtrlColor}
-                  style={{pointerEvents: 'none'}}
-                  size={size}
-                />
-              </Pressable>
-            )
-          }}
-        </Menu.Trigger>
+    <>
+      {isAuthor && (
+        <>
+          <Menu.Group>
+            <Menu.Item
+              testID="pinPostBtn"
+              label={
+                isPinned
+                  ? _(msg`Unpin from profile`)
+                  : _(msg`Pin to your profile`)
+              }
+              disabled={isPinPending}
+              onPress={onPressPin}>
+              <Menu.ItemText>
+                {isPinned
+                  ? _(msg`Unpin from profile`)
+                  : _(msg`Pin to your profile`)}
+              </Menu.ItemText>
+              <Menu.ItemIcon
+                icon={isPinPending ? Loader : PinIcon}
+                position="right"
+              />
+            </Menu.Item>
+          </Menu.Group>
+          <Menu.Divider />
+        </>
+      )}
 
-        <Menu.Outer>
-          {isAuthor && (
-            <>
-              <Menu.Group>
-                <Menu.Item
-                  testID="pinPostBtn"
-                  label={
-                    isPinned
-                      ? _(msg`Unpin from profile`)
-                      : _(msg`Pin to your profile`)
-                  }
-                  disabled={isPinPending}
-                  onPress={onPressPin}>
-                  <Menu.ItemText>
-                    {isPinned
-                      ? _(msg`Unpin from profile`)
-                      : _(msg`Pin to your profile`)}
-                  </Menu.ItemText>
-                  <Menu.ItemIcon
-                    icon={isPinPending ? Loader : PinIcon}
-                    position="right"
-                  />
-                </Menu.Item>
-              </Menu.Group>
-              <Menu.Divider />
-            </>
-          )}
+      <Menu.Group>
+        {(!hideInPWI || hasSession) && (
+          <>
+            <Menu.Item
+              testID="postDropdownTranslateBtn"
+              label={_(msg`Translate`)}
+              onPress={onPressTranslate}>
+              <Menu.ItemText>{_(msg`Translate`)}</Menu.ItemText>
+              <Menu.ItemIcon icon={Translate} position="right" />
+            </Menu.Item>
 
-          <Menu.Group>
-            {(!hideInPWI || hasSession) && (
-              <>
-                <Menu.Item
-                  testID="postDropdownTranslateBtn"
-                  label={_(msg`Translate`)}
-                  onPress={onPressTranslate}>
-                  <Menu.ItemText>{_(msg`Translate`)}</Menu.ItemText>
-                  <Menu.ItemIcon icon={Translate} position="right" />
-                </Menu.Item>
+            <Menu.Item
+              testID="postDropdownCopyTextBtn"
+              label={_(msg`Copy post text`)}
+              onPress={onCopyPostText}>
+              <Menu.ItemText>{_(msg`Copy post text`)}</Menu.ItemText>
+              <Menu.ItemIcon icon={ClipboardIcon} position="right" />
+            </Menu.Item>
+          </>
+        )}
 
-                <Menu.Item
-                  testID="postDropdownCopyTextBtn"
-                  label={_(msg`Copy post text`)}
-                  onPress={onCopyPostText}>
-                  <Menu.ItemText>{_(msg`Copy post text`)}</Menu.ItemText>
-                  <Menu.ItemIcon icon={ClipboardIcon} position="right" />
-                </Menu.Item>
-              </>
-            )}
+        {hasSession && (
+          <Menu.Item
+            testID="postDropdownSendViaDMBtn"
+            label={_(msg`Send via direct message`)}
+            onPress={() => sendViaChatControl.open()}>
+            <Menu.ItemText>
+              <Trans>Send via direct message</Trans>
+            </Menu.ItemText>
+            <Menu.ItemIcon icon={Send} position="right" />
+          </Menu.Item>
+        )}
 
-            {hasSession && (
-              <Menu.Item
-                testID="postDropdownSendViaDMBtn"
-                label={_(msg`Send via direct message`)}
-                onPress={() => sendViaChatControl.open()}>
-                <Menu.ItemText>
-                  <Trans>Send via direct message</Trans>
-                </Menu.ItemText>
-                <Menu.ItemIcon icon={Send} position="right" />
-              </Menu.Item>
-            )}
+        <Menu.Item
+          testID="postDropdownShareBtn"
+          label={isWeb ? _(msg`Copy link to post`) : _(msg`Share`)}
+          onPress={() => {
+            if (showLoggedOutWarning) {
+              loggedOutWarningPromptControl.open()
+            } else {
+              onSharePost()
+            }
+          }}>
+          <Menu.ItemText>
+            {isWeb ? _(msg`Copy link to post`) : _(msg`Share`)}
+          </Menu.ItemText>
+          <Menu.ItemIcon icon={Share} position="right" />
+        </Menu.Item>
+
+        {canEmbed && (
+          <Menu.Item
+            testID="postDropdownEmbedBtn"
+            label={_(msg`Embed post`)}
+            onPress={() => embedPostControl.open()}>
+            <Menu.ItemText>{_(msg`Embed post`)}</Menu.ItemText>
+            <Menu.ItemIcon icon={CodeBrackets} position="right" />
+          </Menu.Item>
+        )}
+      </Menu.Group>
+
+      {hasSession && feedFeedback.enabled && (
+        <>
+          <Menu.Divider />
+          <Menu.Group>
+            <Menu.Item
+              testID="postDropdownShowMoreBtn"
+              label={_(msg`Show more like this`)}
+              onPress={onPressShowMore}>
+              <Menu.ItemText>{_(msg`Show more like this`)}</Menu.ItemText>
+              <Menu.ItemIcon icon={EmojiSmile} position="right" />
+            </Menu.Item>
 
             <Menu.Item
-              testID="postDropdownShareBtn"
-              label={isWeb ? _(msg`Copy link to post`) : _(msg`Share`)}
-              onPress={() => {
-                if (showLoggedOutWarning) {
-                  loggedOutWarningPromptControl.open()
-                } else {
-                  onSharePost()
-                }
-              }}>
+              testID="postDropdownShowLessBtn"
+              label={_(msg`Show less like this`)}
+              onPress={onPressShowLess}>
+              <Menu.ItemText>{_(msg`Show less like this`)}</Menu.ItemText>
+              <Menu.ItemIcon icon={EmojiSad} position="right" />
+            </Menu.Item>
+          </Menu.Group>
+        </>
+      )}
+
+      {hasSession && (
+        <>
+          <Menu.Divider />
+          <Menu.Group>
+            <Menu.Item
+              testID="postDropdownMuteThreadBtn"
+              label={
+                isThreadMuted ? _(msg`Unmute thread`) : _(msg`Mute thread`)
+              }
+              onPress={onToggleThreadMute}>
               <Menu.ItemText>
-                {isWeb ? _(msg`Copy link to post`) : _(msg`Share`)}
+                {isThreadMuted ? _(msg`Unmute thread`) : _(msg`Mute thread`)}
               </Menu.ItemText>
-              <Menu.ItemIcon icon={Share} position="right" />
+              <Menu.ItemIcon
+                icon={isThreadMuted ? Unmute : Mute}
+                position="right"
+              />
             </Menu.Item>
 
-            {canEmbed && (
-              <Menu.Item
-                testID="postDropdownEmbedBtn"
-                label={_(msg`Embed post`)}
-                onPress={() => embedPostControl.open()}>
-                <Menu.ItemText>{_(msg`Embed post`)}</Menu.ItemText>
-                <Menu.ItemIcon icon={CodeBrackets} position="right" />
-              </Menu.Item>
-            )}
+            <Menu.Item
+              testID="postDropdownMuteWordsBtn"
+              label={_(msg`Mute words & tags`)}
+              onPress={() => mutedWordsDialogControl.open()}>
+              <Menu.ItemText>{_(msg`Mute words & tags`)}</Menu.ItemText>
+              <Menu.ItemIcon icon={Filter} position="right" />
+            </Menu.Item>
           </Menu.Group>
+        </>
+      )}
 
-          {hasSession && feedFeedback.enabled && (
-            <>
-              <Menu.Divider />
-              <Menu.Group>
-                <Menu.Item
-                  testID="postDropdownShowMoreBtn"
-                  label={_(msg`Show more like this`)}
-                  onPress={onPressShowMore}>
-                  <Menu.ItemText>{_(msg`Show more like this`)}</Menu.ItemText>
-                  <Menu.ItemIcon icon={EmojiSmile} position="right" />
-                </Menu.Item>
-
+      {hasSession &&
+        (canHideReplyForEveryone || canDetachQuote || canHidePostForMe) && (
+          <>
+            <Menu.Divider />
+            <Menu.Group>
+              {canHidePostForMe && (
                 <Menu.Item
-                  testID="postDropdownShowLessBtn"
-                  label={_(msg`Show less like this`)}
-                  onPress={onPressShowLess}>
-                  <Menu.ItemText>{_(msg`Show less like this`)}</Menu.ItemText>
-                  <Menu.ItemIcon icon={EmojiSad} position="right" />
+                  testID="postDropdownHideBtn"
+                  label={
+                    isReply
+                      ? _(msg`Hide reply for me`)
+                      : _(msg`Hide post for me`)
+                  }
+                  onPress={() => hidePromptControl.open()}>
+                  <Menu.ItemText>
+                    {isReply
+                      ? _(msg`Hide reply for me`)
+                      : _(msg`Hide post for me`)}
+                  </Menu.ItemText>
+                  <Menu.ItemIcon icon={EyeSlash} position="right" />
                 </Menu.Item>
-              </Menu.Group>
-            </>
-          )}
-
-          {hasSession && (
-            <>
-              <Menu.Divider />
-              <Menu.Group>
+              )}
+              {canHideReplyForEveryone && (
                 <Menu.Item
-                  testID="postDropdownMuteThreadBtn"
+                  testID="postDropdownHideBtn"
                   label={
-                    isThreadMuted ? _(msg`Unmute thread`) : _(msg`Mute thread`)
+                    isReplyHiddenByThreadgate
+                      ? _(msg`Show reply for everyone`)
+                      : _(msg`Hide reply for everyone`)
                   }
-                  onPress={onToggleThreadMute}>
+                  onPress={
+                    isReplyHiddenByThreadgate
+                      ? onToggleReplyVisibility
+                      : () => hideReplyConfirmControl.open()
+                  }>
                   <Menu.ItemText>
-                    {isThreadMuted
-                      ? _(msg`Unmute thread`)
-                      : _(msg`Mute thread`)}
+                    {isReplyHiddenByThreadgate
+                      ? _(msg`Show reply for everyone`)
+                      : _(msg`Hide reply for everyone`)}
                   </Menu.ItemText>
                   <Menu.ItemIcon
-                    icon={isThreadMuted ? Unmute : Mute}
+                    icon={isReplyHiddenByThreadgate ? Eye : EyeSlash}
                     position="right"
                   />
                 </Menu.Item>
+              )}
 
+              {canDetachQuote && (
                 <Menu.Item
-                  testID="postDropdownMuteWordsBtn"
-                  label={_(msg`Mute words & tags`)}
-                  onPress={() => mutedWordsDialogControl.open()}>
-                  <Menu.ItemText>{_(msg`Mute words & tags`)}</Menu.ItemText>
-                  <Menu.ItemIcon icon={Filter} position="right" />
+                  disabled={isDetachPending}
+                  testID="postDropdownHideBtn"
+                  label={
+                    quoteEmbed.isDetached
+                      ? _(msg`Re-attach quote`)
+                      : _(msg`Detach quote`)
+                  }
+                  onPress={
+                    quoteEmbed.isDetached
+                      ? onToggleQuotePostAttachment
+                      : () => quotePostDetachConfirmControl.open()
+                  }>
+                  <Menu.ItemText>
+                    {quoteEmbed.isDetached
+                      ? _(msg`Re-attach quote`)
+                      : _(msg`Detach quote`)}
+                  </Menu.ItemText>
+                  <Menu.ItemIcon
+                    icon={
+                      isDetachPending
+                        ? Loader
+                        : quoteEmbed.isDetached
+                        ? Eye
+                        : EyeSlash
+                    }
+                    position="right"
+                  />
                 </Menu.Item>
-              </Menu.Group>
-            </>
-          )}
+              )}
+            </Menu.Group>
+          </>
+        )}
+
+      {hasSession && (
+        <>
+          <Menu.Divider />
+          <Menu.Group>
+            {!isAuthor && (
+              <Menu.Item
+                testID="postDropdownReportBtn"
+                label={_(msg`Report post`)}
+                onPress={() => reportDialogControl.open()}>
+                <Menu.ItemText>{_(msg`Report post`)}</Menu.ItemText>
+                <Menu.ItemIcon icon={Warning} position="right" />
+              </Menu.Item>
+            )}
 
-          {hasSession &&
-            (canHideReplyForEveryone || canDetachQuote || canHidePostForMe) && (
+            {isAuthor && (
               <>
-                <Menu.Divider />
-                <Menu.Group>
-                  {canHidePostForMe && (
-                    <Menu.Item
-                      testID="postDropdownHideBtn"
-                      label={
-                        isReply
-                          ? _(msg`Hide reply for me`)
-                          : _(msg`Hide post for me`)
-                      }
-                      onPress={() => hidePromptControl.open()}>
-                      <Menu.ItemText>
-                        {isReply
-                          ? _(msg`Hide reply for me`)
-                          : _(msg`Hide post for me`)}
-                      </Menu.ItemText>
-                      <Menu.ItemIcon icon={EyeSlash} position="right" />
-                    </Menu.Item>
-                  )}
-                  {canHideReplyForEveryone && (
-                    <Menu.Item
-                      testID="postDropdownHideBtn"
-                      label={
-                        isReplyHiddenByThreadgate
-                          ? _(msg`Show reply for everyone`)
-                          : _(msg`Hide reply for everyone`)
-                      }
-                      onPress={
-                        isReplyHiddenByThreadgate
-                          ? onToggleReplyVisibility
-                          : () => hideReplyConfirmControl.open()
-                      }>
-                      <Menu.ItemText>
-                        {isReplyHiddenByThreadgate
-                          ? _(msg`Show reply for everyone`)
-                          : _(msg`Hide reply for everyone`)}
-                      </Menu.ItemText>
-                      <Menu.ItemIcon
-                        icon={isReplyHiddenByThreadgate ? Eye : EyeSlash}
-                        position="right"
-                      />
-                    </Menu.Item>
-                  )}
-
-                  {canDetachQuote && (
-                    <Menu.Item
-                      disabled={isDetachPending}
-                      testID="postDropdownHideBtn"
-                      label={
-                        quoteEmbed.isDetached
-                          ? _(msg`Re-attach quote`)
-                          : _(msg`Detach quote`)
-                      }
-                      onPress={
-                        quoteEmbed.isDetached
-                          ? onToggleQuotePostAttachment
-                          : () => quotePostDetachConfirmControl.open()
-                      }>
-                      <Menu.ItemText>
-                        {quoteEmbed.isDetached
-                          ? _(msg`Re-attach quote`)
-                          : _(msg`Detach quote`)}
-                      </Menu.ItemText>
-                      <Menu.ItemIcon
-                        icon={
-                          isDetachPending
-                            ? Loader
-                            : quoteEmbed.isDetached
-                            ? Eye
-                            : EyeSlash
-                        }
-                        position="right"
-                      />
-                    </Menu.Item>
-                  )}
-                </Menu.Group>
+                <Menu.Item
+                  testID="postDropdownEditPostInteractions"
+                  label={_(msg`Edit interaction settings`)}
+                  onPress={() => postInteractionSettingsDialogControl.open()}
+                  {...(isAuthor
+                    ? Platform.select({
+                        web: {
+                          onHoverIn: prefetchPostInteractionSettings,
+                        },
+                        native: {
+                          onPressIn: prefetchPostInteractionSettings,
+                        },
+                      })
+                    : {})}>
+                  <Menu.ItemText>
+                    {_(msg`Edit interaction settings`)}
+                  </Menu.ItemText>
+                  <Menu.ItemIcon icon={Gear} position="right" />
+                </Menu.Item>
+                <Menu.Item
+                  testID="postDropdownDeleteBtn"
+                  label={_(msg`Delete post`)}
+                  onPress={() => deletePromptControl.open()}>
+                  <Menu.ItemText>{_(msg`Delete post`)}</Menu.ItemText>
+                  <Menu.ItemIcon icon={Trash} position="right" />
+                </Menu.Item>
               </>
             )}
-
-          {hasSession && (
-            <>
-              <Menu.Divider />
-              <Menu.Group>
-                {!isAuthor && (
-                  <Menu.Item
-                    testID="postDropdownReportBtn"
-                    label={_(msg`Report post`)}
-                    onPress={() => reportDialogControl.open()}>
-                    <Menu.ItemText>{_(msg`Report post`)}</Menu.ItemText>
-                    <Menu.ItemIcon icon={Warning} position="right" />
-                  </Menu.Item>
-                )}
-
-                {isAuthor && (
-                  <>
-                    <Menu.Item
-                      testID="postDropdownEditPostInteractions"
-                      label={_(msg`Edit interaction settings`)}
-                      onPress={() =>
-                        postInteractionSettingsDialogControl.open()
-                      }
-                      {...(isAuthor
-                        ? Platform.select({
-                            web: {
-                              onHoverIn: prefetchPostInteractionSettings,
-                            },
-                            native: {
-                              onPressIn: prefetchPostInteractionSettings,
-                            },
-                          })
-                        : {})}>
-                      <Menu.ItemText>
-                        {_(msg`Edit interaction settings`)}
-                      </Menu.ItemText>
-                      <Menu.ItemIcon icon={Gear} position="right" />
-                    </Menu.Item>
-                    <Menu.Item
-                      testID="postDropdownDeleteBtn"
-                      label={_(msg`Delete post`)}
-                      onPress={() => deletePromptControl.open()}>
-                      <Menu.ItemText>{_(msg`Delete post`)}</Menu.ItemText>
-                      <Menu.ItemIcon icon={Trash} position="right" />
-                    </Menu.Item>
-                  </>
-                )}
-              </Menu.Group>
-            </>
-          )}
-        </Menu.Outer>
-      </Menu.Root>
+          </Menu.Group>
+        </>
+      )}
 
       <Prompt.Basic
         control={deletePromptControl}
@@ -745,9 +778,7 @@ let PostDropdownBtn = ({
         onConfirm={onToggleReplyVisibility}
         confirmButtonCta={_(msg`Yes, hide`)}
       />
-    </EventStopper>
+    </>
   )
 }
-
-PostDropdownBtn = memo(PostDropdownBtn)
-export {PostDropdownBtn}
+PostDropdownMenuItems = memo(PostDropdownMenuItems)