about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/Menu/index.tsx45
-rw-r--r--src/components/Menu/index.web.tsx39
-rw-r--r--src/components/PostControls/PostMenu/PostMenuItems.tsx15
-rw-r--r--src/components/PostControls/ShareMenu/ShareMenuItems.tsx56
-rw-r--r--src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx133
5 files changed, 142 insertions, 146 deletions
diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx
index c5ccfa5ec..94438724c 100644
--- a/src/components/Menu/index.tsx
+++ b/src/components/Menu/index.tsx
@@ -1,5 +1,11 @@
-import React from 'react'
-import {Pressable, StyleProp, View, ViewStyle} from 'react-native'
+import {cloneElement, Fragment, isValidElement, useMemo} from 'react'
+import {
+  Pressable,
+  type StyleProp,
+  type TextStyle,
+  View,
+  type ViewStyle,
+} from 'react-native'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import flattenReactChildren from 'react-keyed-flatten-children'
@@ -16,12 +22,12 @@ import {
   useMenuItemContext,
 } from '#/components/Menu/context'
 import {
-  ContextType,
-  GroupProps,
-  ItemIconProps,
-  ItemProps,
-  ItemTextProps,
-  TriggerProps,
+  type ContextType,
+  type GroupProps,
+  type ItemIconProps,
+  type ItemProps,
+  type ItemTextProps,
+  type TriggerProps,
 } from '#/components/Menu/types'
 import {Text} from '#/components/Typography'
 
@@ -39,7 +45,7 @@ export function Root({
   control?: Dialog.DialogControlProps
 }>) {
   const defaultControl = Dialog.useDialogControl()
-  const context = React.useMemo<ContextType>(
+  const context = useMemo<ContextType>(
     () => ({
       control: control || defaultControl,
     }),
@@ -276,16 +282,21 @@ export function ContainerItem({
   )
 }
 
-export function LabelText({children}: {children: React.ReactNode}) {
+export function LabelText({
+  children,
+  style,
+}: {
+  children: React.ReactNode
+  style?: StyleProp<TextStyle>
+}) {
   const t = useTheme()
   return (
     <Text
       style={[
         a.font_bold,
         t.atoms.text_contrast_medium,
-        {
-          marginBottom: -8,
-        },
+        {marginBottom: -8},
+        style,
       ]}>
       {children}
     </Text>
@@ -304,20 +315,20 @@ export function Group({children, style}: GroupProps) {
         style,
       ]}>
       {flattenReactChildren(children).map((child, i) => {
-        return React.isValidElement(child) &&
+        return isValidElement(child) &&
           (child.type === Item || child.type === ContainerItem) ? (
-          <React.Fragment key={i}>
+          <Fragment key={i}>
             {i > 0 ? (
               <View style={[a.border_b, t.atoms.border_contrast_low]} />
             ) : null}
-            {React.cloneElement(child, {
+            {cloneElement(child, {
               // @ts-expect-error cloneElement is not aware of the types
               style: {
                 borderRadius: 0,
                 borderWidth: 0,
               },
             })}
-          </React.Fragment>
+          </Fragment>
         ) : null
       })}
     </View>
diff --git a/src/components/Menu/index.web.tsx b/src/components/Menu/index.web.tsx
index 7d6e50556..8d26c8f03 100644
--- a/src/components/Menu/index.web.tsx
+++ b/src/components/Menu/index.web.tsx
@@ -1,5 +1,11 @@
-import React from 'react'
-import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native'
+import {forwardRef, useCallback, useId, useMemo, useState} from 'react'
+import {
+  Pressable,
+  type StyleProp,
+  type TextStyle,
+  View,
+  type ViewStyle,
+} from 'react-native'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {DropdownMenu} from 'radix-ui'
@@ -29,10 +35,10 @@ import {Text} from '#/components/Typography'
 export {useMenuContext}
 
 export function useMenuControl(): Dialog.DialogControlProps {
-  const id = React.useId()
-  const [isOpen, setIsOpen] = React.useState(false)
+  const id = useId()
+  const [isOpen, setIsOpen] = useState(false)
 
-  return React.useMemo(
+  return useMemo(
     () => ({
       id,
       ref: {current: null},
@@ -56,13 +62,13 @@ export function Root({
 }>) {
   const {_} = useLingui()
   const defaultControl = useMenuControl()
-  const context = React.useMemo<ContextType>(
+  const context = useMemo<ContextType>(
     () => ({
       control: control || defaultControl,
     }),
     [control, defaultControl],
   )
-  const onOpenChange = React.useCallback(
+  const onOpenChange = useCallback(
     (open: boolean) => {
       if (context.control.isOpen && !open) {
         context.control.close()
@@ -96,7 +102,7 @@ export function Root({
   )
 }
 
-const RadixTriggerPassThrough = React.forwardRef(
+const RadixTriggerPassThrough = forwardRef(
   (
     props: {
       children: (
@@ -355,18 +361,23 @@ export function ItemRadio({selected}: {selected: boolean}) {
   )
 }
 
-export function LabelText({children}: {children: React.ReactNode}) {
+export function LabelText({
+  children,
+  style,
+}: {
+  children: React.ReactNode
+  style?: StyleProp<TextStyle>
+}) {
   const t = useTheme()
   return (
     <Text
       style={[
         a.font_bold,
-        a.pt_md,
-        a.pb_sm,
+        a.p_sm,
         t.atoms.text_contrast_low,
-        {
-          paddingHorizontal: 10,
-        },
+        a.leading_snug,
+        {paddingHorizontal: 10},
+        style,
       ]}>
       {children}
     </Text>
diff --git a/src/components/PostControls/PostMenu/PostMenuItems.tsx b/src/components/PostControls/PostMenu/PostMenuItems.tsx
index 7f33f3348..01ddd0bcf 100644
--- a/src/components/PostControls/PostMenu/PostMenuItems.tsx
+++ b/src/components/PostControls/PostMenu/PostMenuItems.tsx
@@ -48,7 +48,7 @@ import {
   useProfileMuteMutationQueue,
 } from '#/state/queries/profile'
 import {useToggleReplyVisibilityMutation} from '#/state/queries/threadgate'
-import {useSession} from '#/state/session'
+import {useRequireAuth, useSession} from '#/state/session'
 import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
 import * as Toast from '#/view/com/util/Toast'
 import {useDialogControl} from '#/components/Dialog'
@@ -113,6 +113,7 @@ let PostMenuItems = ({
   const {mutateAsync: deletePostMutate} = usePostDeleteMutation()
   const {mutateAsync: pinPostMutate, isPending: isPinPending} =
     usePinnedPostMutation()
+  const requireSignIn = useRequireAuth()
   const hiddenPosts = useHiddenPosts()
   const {hidePost} = useHiddenPostsApi()
   const feedFeedback = useFeedFeedbackContext()
@@ -397,6 +398,8 @@ let PostMenuItems = ({
     openLink(url)
   }
 
+  const onSignIn = () => requireSignIn(() => {})
+
   const gate = useGate()
   const isDiscoverDebugUser =
     IS_INTERNAL ||
@@ -434,7 +437,7 @@ let PostMenuItems = ({
         )}
 
         <Menu.Group>
-          {(!hideInPWI || hasSession) && (
+          {!hideInPWI || hasSession ? (
             <>
               <Menu.Item
                 testID="postDropdownTranslateBtn"
@@ -452,6 +455,14 @@ let PostMenuItems = ({
                 <Menu.ItemIcon icon={ClipboardIcon} position="right" />
               </Menu.Item>
             </>
+          ) : (
+            <Menu.Item
+              testID="postDropdownSignInBtn"
+              label={_(msg`Sign in to view post`)}
+              onPress={onSignIn}>
+              <Menu.ItemText>{_(msg`Sign in to view post`)}</Menu.ItemText>
+              <Menu.ItemIcon icon={Eye} position="right" />
+            </Menu.Item>
           )}
         </Menu.Group>
 
diff --git a/src/components/PostControls/ShareMenu/ShareMenuItems.tsx b/src/components/PostControls/ShareMenu/ShareMenuItems.tsx
index c090c3e2d..1c04f3174 100644
--- a/src/components/PostControls/ShareMenu/ShareMenuItems.tsx
+++ b/src/components/PostControls/ShareMenu/ShareMenuItems.tsx
@@ -14,6 +14,8 @@ import {isIOS} from '#/platform/detection'
 import {useProfileShadow} from '#/state/cache/profile-shadow'
 import {useSession} from '#/state/session'
 import * as Toast from '#/view/com/util/Toast'
+import {atoms as a} from '#/alf'
+import {Admonition} from '#/components/Admonition'
 import {useDialogControl} from '#/components/Dialog'
 import {SendViaChatDialog} from '#/components/dms/dialogs/ShareViaChatDialog'
 import {ArrowOutOfBoxModified_Stroke2_Corner2_Rounded as ArrowOutOfBoxIcon} from '#/components/icons/ArrowOutOfBox'
@@ -21,7 +23,6 @@ import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/i
 import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/icons/Clipboard'
 import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlaneIcon} from '#/components/icons/PaperPlane'
 import * as Menu from '#/components/Menu'
-import * as Prompt from '#/components/Prompt'
 import {useDevMode} from '#/storage/hooks/dev-mode'
 import {RecentChats} from './RecentChats'
 import {type ShareMenuItemsProps} from './ShareMenuItems.types'
@@ -30,11 +31,9 @@ let ShareMenuItems = ({
   post,
   onShare: onShareProp,
 }: ShareMenuItemsProps): React.ReactNode => {
-  const {hasSession, currentAccount} = useSession()
+  const {hasSession} = useSession()
   const {_} = useLingui()
   const navigation = useNavigation<NavigationProp>()
-  const pwiWarningShareControl = useDialogControl()
-  const pwiWarningCopyControl = useDialogControl()
   const sendViaChatControl = useDialogControl()
   const [devModeEnabled] = useDevMode()
 
@@ -52,9 +51,6 @@ let ShareMenuItems = ({
     )
   }, [postAuthor])
 
-  const showLoggedOutWarning =
-    postAuthor.did !== currentAccount?.did && hideInPWI
-
   const onSharePost = () => {
     logger.metric('share:press:nativeShare', {}, {statsig: true})
     const url = toShareUrl(href)
@@ -117,13 +113,7 @@ let ShareMenuItems = ({
           <Menu.Item
             testID="postDropdownShareBtn"
             label={_(msg`Share via...`)}
-            onPress={() => {
-              if (showLoggedOutWarning) {
-                pwiWarningShareControl.open()
-              } else {
-                onSharePost()
-              }
-            }}>
+            onPress={onSharePost}>
             <Menu.ItemText>
               <Trans>Share via...</Trans>
             </Menu.ItemText>
@@ -133,13 +123,7 @@ let ShareMenuItems = ({
           <Menu.Item
             testID="postDropdownShareBtn"
             label={_(msg`Copy link to post`)}
-            onPress={() => {
-              if (showLoggedOutWarning) {
-                pwiWarningCopyControl.open()
-              } else {
-                onCopyLink()
-              }
-            }}>
+            onPress={onCopyLink}>
             <Menu.ItemText>
               <Trans>Copy link to post</Trans>
             </Menu.ItemText>
@@ -147,6 +131,16 @@ let ShareMenuItems = ({
           </Menu.Item>
         </Menu.Group>
 
+        {hideInPWI && (
+          <Menu.Group>
+            <Menu.ContainerItem>
+              <Admonition type="warning" style={[a.flex_1, a.border_0, a.p_0]}>
+                <Trans>This post is only visible to logged-in users.</Trans>
+              </Admonition>
+            </Menu.ContainerItem>
+          </Menu.Group>
+        )}
+
         {devModeEnabled && (
           <Menu.Group>
             <Menu.Item
@@ -171,26 +165,6 @@ let ShareMenuItems = ({
         )}
       </Menu.Outer>
 
-      <Prompt.Basic
-        control={pwiWarningShareControl}
-        title={_(msg`Note about sharing`)}
-        description={_(
-          msg`This post is only visible to logged-in users. It won't be visible to people who aren't signed in.`,
-        )}
-        onConfirm={onSharePost}
-        confirmButtonCta={_(msg`Share anyway`)}
-      />
-
-      <Prompt.Basic
-        control={pwiWarningCopyControl}
-        title={_(msg`Note about sharing`)}
-        description={_(
-          msg`This post is only visible to logged-in users. It won't be visible to people who aren't signed in.`,
-        )}
-        onConfirm={onCopyLink}
-        confirmButtonCta={_(msg`Copy anyway`)}
-      />
-
       <SendViaChatDialog
         control={sendViaChatControl}
         onSelectChat={onSelectChatToShareTo}
diff --git a/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx b/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx
index 0da259678..8d52a2fdf 100644
--- a/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx
+++ b/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx
@@ -22,7 +22,6 @@ import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/i
 import {CodeBrackets_Stroke2_Corner0_Rounded as CodeBracketsIcon} from '#/components/icons/CodeBrackets'
 import {PaperPlane_Stroke2_Corner0_Rounded as Send} from '#/components/icons/PaperPlane'
 import * as Menu from '#/components/Menu'
-import * as Prompt from '#/components/Prompt'
 import {useDevMode} from '#/storage/hooks/dev-mode'
 import {type ShareMenuItemsProps} from './ShareMenuItems.types'
 
@@ -32,11 +31,10 @@ let ShareMenuItems = ({
   timestamp,
   onShare: onShareProp,
 }: ShareMenuItemsProps): React.ReactNode => {
-  const {hasSession, currentAccount} = useSession()
+  const {hasSession} = useSession()
   const {gtMobile} = useBreakpoints()
   const {_} = useLingui()
   const navigation = useNavigation<NavigationProp>()
-  const loggedOutWarningPromptControl = useDialogControl()
   const embedPostControl = useDialogControl()
   const sendViaChatControl = useDialogControl()
   const [devModeEnabled] = useDevMode()
@@ -56,9 +54,6 @@ let ShareMenuItems = ({
     )
   }, [postAuthor])
 
-  const showLoggedOutWarning =
-    postAuthor.did !== currentAccount?.did && hideInPWI
-
   const onCopyLink = () => {
     logger.metric('share:press:copyLink', {}, {statsig: true})
     const url = toShareUrl(href)
@@ -84,92 +79,86 @@ let ShareMenuItems = ({
     shareText(postAuthor.did)
   }
 
+  const copyLinkItem = (
+    <Menu.Item
+      testID="postDropdownShareBtn"
+      label={_(msg`Copy link to post`)}
+      onPress={onCopyLink}>
+      <Menu.ItemText>
+        <Trans>Copy link to post</Trans>
+      </Menu.ItemText>
+      <Menu.ItemIcon icon={ChainLinkIcon} position="right" />
+    </Menu.Item>
+  )
+
   return (
     <>
       <Menu.Outer>
-        <Menu.Group>
+        {!hideInPWI && copyLinkItem}
+
+        {hasSession && (
           <Menu.Item
-            testID="postDropdownShareBtn"
-            label={_(msg`Copy link to post`)}
+            testID="postDropdownSendViaDMBtn"
+            label={_(msg`Send via direct message`)}
             onPress={() => {
-              if (showLoggedOutWarning) {
-                loggedOutWarningPromptControl.open()
-              } else {
-                onCopyLink()
-              }
+              logger.metric('share:press:openDmSearch', {}, {statsig: true})
+              sendViaChatControl.open()
             }}>
             <Menu.ItemText>
-              <Trans>Copy link to post</Trans>
+              <Trans>Send via direct message</Trans>
             </Menu.ItemText>
-            <Menu.ItemIcon icon={ChainLinkIcon} position="right" />
+            <Menu.ItemIcon icon={Send} position="right" />
+          </Menu.Item>
+        )}
+
+        {canEmbed && (
+          <Menu.Item
+            testID="postDropdownEmbedBtn"
+            label={_(msg`Embed post`)}
+            onPress={() => {
+              logger.metric('share:press:embed', {}, {statsig: true})
+              embedPostControl.open()
+            }}>
+            <Menu.ItemText>{_(msg`Embed post`)}</Menu.ItemText>
+            <Menu.ItemIcon icon={CodeBracketsIcon} position="right" />
           </Menu.Item>
+        )}
+
+        {hideInPWI && (
+          <>
+            {hasSession && <Menu.Divider />}
+            {copyLinkItem}
+            <Menu.LabelText style={{maxWidth: 220}}>
+              <Trans>Note: This post is only visible to logged-in users.</Trans>
+            </Menu.LabelText>
+          </>
+        )}
 
-          {hasSession && (
+        {devModeEnabled && (
+          <>
+            <Menu.Divider />
             <Menu.Item
-              testID="postDropdownSendViaDMBtn"
-              label={_(msg`Send via direct message`)}
-              onPress={() => {
-                logger.metric('share:press:openDmSearch', {}, {statsig: true})
-                sendViaChatControl.open()
-              }}>
+              testID="postAtUriShareBtn"
+              label={_(msg`Copy post at:// URI`)}
+              onPress={onShareATURI}>
               <Menu.ItemText>
-                <Trans>Send via direct message</Trans>
+                <Trans>Copy post at:// URI</Trans>
               </Menu.ItemText>
-              <Menu.ItemIcon icon={Send} position="right" />
+              <Menu.ItemIcon icon={ClipboardIcon} position="right" />
             </Menu.Item>
-          )}
-
-          {canEmbed && (
             <Menu.Item
-              testID="postDropdownEmbedBtn"
-              label={_(msg`Embed post`)}
-              onPress={() => {
-                logger.metric('share:press:embed', {}, {statsig: true})
-                embedPostControl.open()
-              }}>
-              <Menu.ItemText>{_(msg`Embed post`)}</Menu.ItemText>
-              <Menu.ItemIcon icon={CodeBracketsIcon} position="right" />
+              testID="postAuthorDIDShareBtn"
+              label={_(msg`Copy author DID`)}
+              onPress={onShareAuthorDID}>
+              <Menu.ItemText>
+                <Trans>Copy author DID</Trans>
+              </Menu.ItemText>
+              <Menu.ItemIcon icon={ClipboardIcon} position="right" />
             </Menu.Item>
-          )}
-        </Menu.Group>
-
-        {devModeEnabled && (
-          <>
-            <Menu.Divider />
-            <Menu.Group>
-              <Menu.Item
-                testID="postAtUriShareBtn"
-                label={_(msg`Copy post at:// URI`)}
-                onPress={onShareATURI}>
-                <Menu.ItemText>
-                  <Trans>Copy post at:// URI</Trans>
-                </Menu.ItemText>
-                <Menu.ItemIcon icon={ClipboardIcon} position="right" />
-              </Menu.Item>
-              <Menu.Item
-                testID="postAuthorDIDShareBtn"
-                label={_(msg`Copy author DID`)}
-                onPress={onShareAuthorDID}>
-                <Menu.ItemText>
-                  <Trans>Copy author DID</Trans>
-                </Menu.ItemText>
-                <Menu.ItemIcon icon={ClipboardIcon} position="right" />
-              </Menu.Item>
-            </Menu.Group>
           </>
         )}
       </Menu.Outer>
 
-      <Prompt.Basic
-        control={loggedOutWarningPromptControl}
-        title={_(msg`Note about sharing`)}
-        description={_(
-          msg`This post is only visible to logged-in users. It won't be visible to people who aren't signed in.`,
-        )}
-        onConfirm={onCopyLink}
-        confirmButtonCta={_(msg`Share anyway`)}
-      />
-
       {canEmbed && (
         <EmbedDialog
           control={embedPostControl}