@@ -8,6 +8,7 @@ import {useLingui} from '@lingui/react'
|
|||||||
import {useOpenLink} from '#/lib/hooks/useOpenLink'
|
import {useOpenLink} from '#/lib/hooks/useOpenLink'
|
||||||
import {richTextToString} from '#/lib/strings/rich-text-helpers'
|
import {richTextToString} from '#/lib/strings/rich-text-helpers'
|
||||||
import {getTranslatorLink} from '#/locale/helpers'
|
import {getTranslatorLink} from '#/locale/helpers'
|
||||||
|
import {logger} from '#/logger'
|
||||||
import {isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {useConvoActive} from '#/state/messages/convo'
|
import {useConvoActive} from '#/state/messages/convo'
|
||||||
import {useLanguagePrefs} from '#/state/preferences'
|
import {useLanguagePrefs} from '#/state/preferences'
|
||||||
@@ -61,6 +62,12 @@ export let MessageContextMenu = ({
|
|||||||
langPrefs.primaryLanguage,
|
langPrefs.primaryLanguage,
|
||||||
)
|
)
|
||||||
openLink(translatorUrl, true)
|
openLink(translatorUrl, true)
|
||||||
|
|
||||||
|
logger.metric('translate', {
|
||||||
|
sourceLanguages: [],
|
||||||
|
targetLanguage: langPrefs.primaryLanguage,
|
||||||
|
textLength: message.text.length,
|
||||||
|
})
|
||||||
}, [langPrefs.primaryLanguage, message.text, openLink])
|
}, [langPrefs.primaryLanguage, message.text, openLink])
|
||||||
|
|
||||||
const onDelete = useCallback(() => {
|
const onDelete = useCallback(() => {
|
||||||
|
|||||||
@@ -364,4 +364,10 @@ export type MetricEvents = {
|
|||||||
details: boolean
|
details: boolean
|
||||||
}
|
}
|
||||||
'reportDialog:failure': {}
|
'reportDialog:failure': {}
|
||||||
|
|
||||||
|
translate: {
|
||||||
|
sourceLanguages: string[]
|
||||||
|
targetLanguage: string
|
||||||
|
textLength: number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import React, {memo, useMemo} from 'react'
|
import React, {memo, useMemo} from 'react'
|
||||||
import {
|
import {
|
||||||
GestureResponderEvent,
|
type GestureResponderEvent,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text as RNText,
|
Text as RNText,
|
||||||
View,
|
View,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {
|
import {
|
||||||
AppBskyFeedDefs,
|
type AppBskyFeedDefs,
|
||||||
AppBskyFeedPost,
|
AppBskyFeedPost,
|
||||||
AppBskyFeedThreadgate,
|
type AppBskyFeedThreadgate,
|
||||||
AtUri,
|
AtUri,
|
||||||
ModerationDecision,
|
type ModerationDecision,
|
||||||
RichText as RichTextAPI,
|
RichText as RichTextAPI,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {msg, Plural, Trans} from '@lingui/macro'
|
import {msg, Plural, Trans} from '@lingui/macro'
|
||||||
@@ -26,9 +26,14 @@ import {countLines} from '#/lib/strings/helpers'
|
|||||||
import {niceDate} from '#/lib/strings/time'
|
import {niceDate} from '#/lib/strings/time'
|
||||||
import {s} from '#/lib/styles'
|
import {s} from '#/lib/styles'
|
||||||
import {getTranslatorLink, isPostInLanguage} from '#/locale/helpers'
|
import {getTranslatorLink, isPostInLanguage} from '#/locale/helpers'
|
||||||
import {POST_TOMBSTONE, Shadow, usePostShadow} from '#/state/cache/post-shadow'
|
import {logger} from '#/logger'
|
||||||
|
import {
|
||||||
|
POST_TOMBSTONE,
|
||||||
|
type Shadow,
|
||||||
|
usePostShadow,
|
||||||
|
} from '#/state/cache/post-shadow'
|
||||||
import {useLanguagePrefs} from '#/state/preferences'
|
import {useLanguagePrefs} from '#/state/preferences'
|
||||||
import {ThreadPost} from '#/state/queries/post-thread'
|
import {type ThreadPost} from '#/state/queries/post-thread'
|
||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {useComposerControls} from '#/state/shell/composer'
|
import {useComposerControls} from '#/state/shell/composer'
|
||||||
import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
|
import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
|
||||||
@@ -52,7 +57,7 @@ import {ContentHider} from '#/components/moderation/ContentHider'
|
|||||||
import {LabelsOnMyPost} from '#/components/moderation/LabelsOnMe'
|
import {LabelsOnMyPost} from '#/components/moderation/LabelsOnMe'
|
||||||
import {PostAlerts} from '#/components/moderation/PostAlerts'
|
import {PostAlerts} from '#/components/moderation/PostAlerts'
|
||||||
import {PostHider} from '#/components/moderation/PostHider'
|
import {PostHider} from '#/components/moderation/PostHider'
|
||||||
import {AppModerationCause} from '#/components/Pills'
|
import {type AppModerationCause} from '#/components/Pills'
|
||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
import {RichText} from '#/components/RichText'
|
import {RichText} from '#/components/RichText'
|
||||||
import {SubtleWebHover} from '#/components/SubtleWebHover'
|
import {SubtleWebHover} from '#/components/SubtleWebHover'
|
||||||
@@ -747,14 +752,29 @@ function ExpandedPostDetails({
|
|||||||
const {_, i18n} = useLingui()
|
const {_, i18n} = useLingui()
|
||||||
const openLink = useOpenLink()
|
const openLink = useOpenLink()
|
||||||
const isRootPost = !('reply' in post.record)
|
const isRootPost = !('reply' in post.record)
|
||||||
|
const langPrefs = useLanguagePrefs()
|
||||||
|
|
||||||
const onTranslatePress = React.useCallback(
|
const onTranslatePress = React.useCallback(
|
||||||
(e: GestureResponderEvent) => {
|
(e: GestureResponderEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
openLink(translatorUrl, true)
|
openLink(translatorUrl, true)
|
||||||
|
|
||||||
|
if (
|
||||||
|
bsky.dangerousIsType<AppBskyFeedPost.Record>(
|
||||||
|
post.record,
|
||||||
|
AppBskyFeedPost.isRecord,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
logger.metric('translate', {
|
||||||
|
sourceLanguages: post.record.langs ?? [],
|
||||||
|
targetLanguage: langPrefs.primaryLanguage,
|
||||||
|
textLength: post.record.text.length,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
[openLink, translatorUrl],
|
[openLink, translatorUrl, langPrefs, post],
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import {
|
|||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import * as Clipboard from 'expo-clipboard'
|
import * as Clipboard from 'expo-clipboard'
|
||||||
import {
|
import {
|
||||||
AppBskyFeedDefs,
|
type AppBskyFeedDefs,
|
||||||
AppBskyFeedPost,
|
AppBskyFeedPost,
|
||||||
AppBskyFeedThreadgate,
|
type AppBskyFeedThreadgate,
|
||||||
AtUri,
|
AtUri,
|
||||||
RichText as RichTextAPI,
|
type RichText as RichTextAPI,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
@@ -20,7 +20,10 @@ import {useNavigation} from '@react-navigation/native'
|
|||||||
import {useOpenLink} from '#/lib/hooks/useOpenLink'
|
import {useOpenLink} from '#/lib/hooks/useOpenLink'
|
||||||
import {getCurrentRoute} from '#/lib/routes/helpers'
|
import {getCurrentRoute} from '#/lib/routes/helpers'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
import {
|
||||||
|
type CommonNavigatorParams,
|
||||||
|
type NavigationProp,
|
||||||
|
} from '#/lib/routes/types'
|
||||||
import {shareText, shareUrl} from '#/lib/sharing'
|
import {shareText, shareUrl} from '#/lib/sharing'
|
||||||
import {logEvent} from '#/lib/statsig/statsig'
|
import {logEvent} from '#/lib/statsig/statsig'
|
||||||
import {richTextToString} from '#/lib/strings/rich-text-helpers'
|
import {richTextToString} from '#/lib/strings/rich-text-helpers'
|
||||||
@@ -28,7 +31,7 @@ import {toShareUrl} from '#/lib/strings/url-helpers'
|
|||||||
import {getTranslatorLink} from '#/locale/helpers'
|
import {getTranslatorLink} from '#/locale/helpers'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {Shadow} from '#/state/cache/post-shadow'
|
import {type Shadow} from '#/state/cache/post-shadow'
|
||||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||||
import {useFeedFeedbackContext} from '#/state/feed-feedback'
|
import {useFeedFeedbackContext} from '#/state/feed-feedback'
|
||||||
import {useLanguagePrefs} from '#/state/preferences'
|
import {useLanguagePrefs} from '#/state/preferences'
|
||||||
@@ -85,6 +88,7 @@ import {
|
|||||||
useReportDialogControl,
|
useReportDialogControl,
|
||||||
} from '#/components/moderation/ReportDialog'
|
} from '#/components/moderation/ReportDialog'
|
||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
|
import * as bsky from '#/types/bsky'
|
||||||
import * as Toast from '../Toast'
|
import * as Toast from '../Toast'
|
||||||
|
|
||||||
let PostDropdownMenuItems = ({
|
let PostDropdownMenuItems = ({
|
||||||
@@ -248,7 +252,20 @@ let PostDropdownMenuItems = ({
|
|||||||
|
|
||||||
const onPressTranslate = React.useCallback(async () => {
|
const onPressTranslate = React.useCallback(async () => {
|
||||||
await openLink(translatorUrl, true)
|
await openLink(translatorUrl, true)
|
||||||
}, [openLink, translatorUrl])
|
|
||||||
|
if (
|
||||||
|
bsky.dangerousIsType<AppBskyFeedPost.Record>(
|
||||||
|
post.record,
|
||||||
|
AppBskyFeedPost.isRecord,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
logger.metric('translate', {
|
||||||
|
sourceLanguages: post.record.langs ?? [],
|
||||||
|
targetLanguage: langPrefs.primaryLanguage,
|
||||||
|
textLength: post.record.text.length,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [openLink, translatorUrl, langPrefs, post])
|
||||||
|
|
||||||
const onHidePost = React.useCallback(() => {
|
const onHidePost = React.useCallback(() => {
|
||||||
hidePost({uri: postUri})
|
hidePost({uri: postUri})
|
||||||
|
|||||||
Reference in New Issue
Block a user