diff options
Diffstat (limited to 'src/view/com/util/forms/PostDropdownBtn.tsx')
-rw-r--r-- | src/view/com/util/forms/PostDropdownBtn.tsx | 153 |
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, }) }, |