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.tsx153
1 files changed, 103 insertions, 50 deletions
diff --git a/src/view/com/util/forms/PostDropdownBtn.tsx b/src/view/com/util/forms/PostDropdownBtn.tsx
index 1fffa3123..1ba5ae8ae 100644
--- a/src/view/com/util/forms/PostDropdownBtn.tsx
+++ b/src/view/com/util/forms/PostDropdownBtn.tsx
@@ -1,49 +1,101 @@
 import React from 'react'
-import {StyleProp, View, ViewStyle} from 'react-native'
+import {Linking, StyleProp, View, ViewStyle} from 'react-native'
+import Clipboard from '@react-native-clipboard/clipboard'
 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
+import {AppBskyFeedDefs, AppBskyFeedPost, AtUri} from '@atproto/api'
 import {toShareUrl} from 'lib/strings/url-helpers'
-import {useStores} from 'state/index'
 import {useTheme} from 'lib/ThemeContext'
 import {shareUrl} from 'lib/sharing'
 import {
   NativeDropdown,
   DropdownItem as NativeDropdownItem,
 } from './NativeDropdown'
+import * as Toast from '../Toast'
 import {EventStopper} from '../EventStopper'
+import {useModalControls} from '#/state/modals'
+import {makeProfileLink} from '#/lib/routes/links'
+import {getTranslatorLink} from '#/locale/helpers'
+import {usePostDeleteMutation} from '#/state/queries/post'
+import {useMutedThreads, useToggleThreadMute} from '#/state/muted-threads'
+import {useLanguagePrefs} from '#/state/preferences'
+import {logger} from '#/logger'
+import {Shadow} from '#/state/cache/types'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+import {useSession} from '#/state/session'
+import {isWeb} from '#/platform/detection'
 
 export function PostDropdownBtn({
   testID,
-  itemUri,
-  itemCid,
-  itemHref,
-  isAuthor,
-  isThreadMuted,
-  onCopyPostText,
-  onOpenTranslate,
-  onToggleThreadMute,
-  onDeletePost,
+  post,
+  record,
   style,
 }: {
   testID: string
-  itemUri: string
-  itemCid: string
-  itemHref: string
-  itemTitle: string
-  isAuthor: boolean
-  isThreadMuted: boolean
-  onCopyPostText: () => void
-  onOpenTranslate: () => void
-  onToggleThreadMute: () => void
-  onDeletePost: () => void
+  post: Shadow<AppBskyFeedDefs.PostView>
+  record: AppBskyFeedPost.Record
   style?: StyleProp<ViewStyle>
 }) {
-  const store = useStores()
+  const {hasSession, currentAccount} = useSession()
   const theme = useTheme()
+  const {_} = useLingui()
   const defaultCtrlColor = theme.palette.default.postCtrl
+  const {openModal} = useModalControls()
+  const langPrefs = useLanguagePrefs()
+  const mutedThreads = useMutedThreads()
+  const toggleThreadMute = useToggleThreadMute()
+  const postDeleteMutation = usePostDeleteMutation()
+
+  const rootUri = record.reply?.root?.uri || post.uri
+  const isThreadMuted = mutedThreads.includes(rootUri)
+  const isAuthor = post.author.did === currentAccount?.did
+  const href = React.useMemo(() => {
+    const urip = new AtUri(post.uri)
+    return makeProfileLink(post.author, 'post', urip.rkey)
+  }, [post.uri, post.author])
+
+  const translatorUrl = getTranslatorLink(
+    record.text,
+    langPrefs.primaryLanguage,
+  )
+
+  const onDeletePost = React.useCallback(() => {
+    postDeleteMutation.mutateAsync({uri: post.uri}).then(
+      () => {
+        Toast.show('Post deleted')
+      },
+      e => {
+        logger.error('Failed to delete post', {error: e})
+        Toast.show('Failed to delete post, please try again')
+      },
+    )
+  }, [post, postDeleteMutation])
+
+  const onToggleThreadMute = React.useCallback(() => {
+    try {
+      const muted = toggleThreadMute(rootUri)
+      if (muted) {
+        Toast.show('You will no longer receive notifications for this thread')
+      } else {
+        Toast.show('You will now receive notifications for this thread')
+      }
+    } catch (e) {
+      logger.error('Failed to toggle thread mute', {error: e})
+    }
+  }, [rootUri, toggleThreadMute])
+
+  const onCopyPostText = React.useCallback(() => {
+    Clipboard.setString(record?.text || '')
+    Toast.show('Copied to clipboard')
+  }, [record])
+
+  const onOpenTranslate = React.useCallback(() => {
+    Linking.openURL(translatorUrl)
+  }, [translatorUrl])
 
   const dropdownItems: NativeDropdownItem[] = [
     {
-      label: 'Translate',
+      label: _(msg`Translate`),
       onPress() {
         onOpenTranslate()
       },
@@ -57,7 +109,7 @@ export function PostDropdownBtn({
       },
     },
     {
-      label: 'Copy post text',
+      label: _(msg`Copy post text`),
       onPress() {
         onCopyPostText()
       },
@@ -71,9 +123,9 @@ export function PostDropdownBtn({
       },
     },
     {
-      label: 'Share',
+      label: isWeb ? _(msg`Copy link to post`) : _(msg`Share`),
       onPress() {
-        const url = toShareUrl(itemHref)
+        const url = toShareUrl(href)
         shareUrl(url)
       },
       testID: 'postDropdownShareBtn',
@@ -85,11 +137,11 @@ export function PostDropdownBtn({
         web: 'share',
       },
     },
-    {
+    hasSession && {
       label: 'separator',
     },
-    {
-      label: isThreadMuted ? 'Unmute thread' : 'Mute thread',
+    hasSession && {
+      label: isThreadMuted ? _(msg`Unmute thread`) : _(msg`Mute thread`),
       onPress() {
         onToggleThreadMute()
       },
@@ -102,37 +154,38 @@ export function PostDropdownBtn({
         web: 'comment-slash',
       },
     },
-    {
+    hasSession && {
       label: 'separator',
     },
-    !isAuthor && {
-      label: 'Report post',
-      onPress() {
-        store.shell.openModal({
-          name: 'report',
-          uri: itemUri,
-          cid: itemCid,
-        })
-      },
-      testID: 'postDropdownReportBtn',
-      icon: {
-        ios: {
-          name: 'exclamationmark.triangle',
+    !isAuthor &&
+      hasSession && {
+        label: _(msg`Report post`),
+        onPress() {
+          openModal({
+            name: 'report',
+            uri: post.uri,
+            cid: post.cid,
+          })
+        },
+        testID: 'postDropdownReportBtn',
+        icon: {
+          ios: {
+            name: 'exclamationmark.triangle',
+          },
+          android: 'ic_menu_report_image',
+          web: 'circle-exclamation',
         },
-        android: 'ic_menu_report_image',
-        web: 'circle-exclamation',
       },
-    },
     isAuthor && {
       label: 'separator',
     },
     isAuthor && {
-      label: 'Delete post',
+      label: _(msg`Delete post`),
       onPress() {
-        store.shell.openModal({
+        openModal({
           name: 'confirm',
-          title: 'Delete this post?',
-          message: 'Are you sure? This can not be undone.',
+          title: _(msg`Delete this post?`),
+          message: _(msg`Are you sure? This cannot be undone.`),
           onPressConfirm: onDeletePost,
         })
       },