diff --git a/src/lib/moderation/create-sanitized-display-name.ts b/src/lib/moderation/create-sanitized-display-name.ts index 4c62a5c03c..d15564d385 100644 --- a/src/lib/moderation/create-sanitized-display-name.ts +++ b/src/lib/moderation/create-sanitized-display-name.ts @@ -1,3 +1,5 @@ +import {type ModerationUI} from '@atproto/api' + import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' import type * as bsky from '#/types/bsky' @@ -5,9 +7,10 @@ import type * as bsky from '#/types/bsky' export function createSanitizedDisplayName( profile: bsky.profile.AnyProfileView, noAt = false, + moderation?: ModerationUI, ) { if (profile.displayName != null && profile.displayName !== '') { - return sanitizeDisplayName(profile.displayName) + return sanitizeDisplayName(profile.displayName, moderation) } else { return sanitizeHandle(profile.handle, noAt ? '' : '@') } diff --git a/src/view/com/posts/PostFeedItem.tsx b/src/view/com/posts/PostFeedItem.tsx index 89ea9b6810..ef86ca58b0 100644 --- a/src/view/com/posts/PostFeedItem.tsx +++ b/src/view/com/posts/PostFeedItem.tsx @@ -9,21 +9,17 @@ import { type ModerationDecision, RichText as RichTextAPI, } from '@atproto/api' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' import {useQueryClient} from '@tanstack/react-query' import {useActorStatus} from '#/lib/actor-status' -import {isReasonFeedSource, type ReasonFeedSource} from '#/lib/api/feed/types' +import {type ReasonFeedSource} from '#/lib/api/feed/types' import {MAX_POST_LINES} from '#/lib/constants' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' import {type NavigationProp} from '#/lib/routes/types' import {useGate} from '#/lib/statsig/statsig' -import {sanitizeDisplayName} from '#/lib/strings/display-names' -import {sanitizeHandle} from '#/lib/strings/handles' import {countLines} from '#/lib/strings/helpers' import { POST_TOMBSTONE, @@ -38,14 +34,10 @@ import { buildPostSourceKey, setUnstablePostSource, } from '#/state/unstable-post-source' -import {FeedNameText} from '#/view/com/util/FeedInfoText' -import {Link, TextLinkOnWebOnly} from '#/view/com/util/Link' +import {Link} from '#/view/com/util/Link' import {PostMeta} from '#/view/com/util/PostMeta' -import {Text} from '#/view/com/util/text/Text' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a} from '#/alf' -import {Pin_Stroke2_Corner0_Rounded as PinIcon} from '#/components/icons/Pin' -import {Repost_Stroke2_Corner2_Rounded as RepostIcon} from '#/components/icons/Repost' import {ContentHider} from '#/components/moderation/ContentHider' import {LabelsOnMyPost} from '#/components/moderation/LabelsOnMe' import {PostAlerts} from '#/components/moderation/PostAlerts' @@ -56,10 +48,10 @@ import {PostRepliedTo} from '#/components/Post/PostRepliedTo' import {ShowMoreTextButton} from '#/components/Post/ShowMoreTextButton' import {PostControls} from '#/components/PostControls' import {DiscoverDebug} from '#/components/PostControls/DiscoverDebug' -import {ProfileHoverCard} from '#/components/ProfileHoverCard' import {RichText} from '#/components/RichText' import {SubtleHover} from '#/components/SubtleHover' import * as bsky from '#/types/bsky' +import {PostFeedReason} from './PostFeedReason' interface FeedItemProps { record: AppBskyFeedPost.Record @@ -173,7 +165,6 @@ let FeedItemInner = ({ const navigation = useNavigation() const pal = usePalette('default') const gate = useGate() - const {_} = useLingui() const [hover, setHover] = useState(false) @@ -275,11 +266,6 @@ let FeedItemInner = ({ }, ] - const {currentAccount} = useSession() - const isOwner = - AppBskyFeedDefs.isReasonRepost(reason) && - reason.by.did === currentAccount?.did - /** * If `post[0]` in this slice is the actual root post (not an orphan thread), * then we may have a threadgate record to reference @@ -334,99 +320,14 @@ let FeedItemInner = ({ )} - - {isReasonFeedSource(reason) ? ( - - - - From{' '} - - - - - ) : AppBskyFeedDefs.isReasonRepost(reason) ? ( - - - - {isOwner ? ( - Reposted by you - ) : ( - - Reposted by{' '} - - - {sanitizeDisplayName( - reason.by.displayName || - sanitizeHandle(reason.by.handle), - moderation.ui('displayName'), - )} - - } - href={makeProfileLink(reason.by)} - onBeforePress={onOpenReposter} - /> - - - )} - - - ) : AppBskyFeedDefs.isReasonPin(reason) ? ( - - - - Pinned - - - ) : null} + + {reason && ( + + )} @@ -602,12 +503,6 @@ const styles = StyleSheet.create({ marginLeft: 'auto', marginRight: 'auto', }, - includeReason: { - flexDirection: 'row', - alignItems: 'center', - marginBottom: 2, - marginLeft: -16, - }, layout: { flexDirection: 'row', marginTop: 1, diff --git a/src/view/com/posts/PostFeedReason.tsx b/src/view/com/posts/PostFeedReason.tsx new file mode 100644 index 0000000000..10ed25f911 --- /dev/null +++ b/src/view/com/posts/PostFeedReason.tsx @@ -0,0 +1,139 @@ +import {StyleSheet, View} from 'react-native' +import {AppBskyFeedDefs, type ModerationDecision} from '@atproto/api' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {isReasonFeedSource, type ReasonFeedSource} from '#/lib/api/feed/types' +import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name' +import {makeProfileLink} from '#/lib/routes/links' +import {useSession} from '#/state/session' +import {atoms as a, useTheme} from '#/alf' +import {Pin_Stroke2_Corner0_Rounded as PinIcon} from '#/components/icons/Pin' +import {Repost_Stroke2_Corner2_Rounded as RepostIcon} from '#/components/icons/Repost' +import {Link, WebOnlyInlineLinkText} from '#/components/Link' +import {ProfileHoverCard} from '#/components/ProfileHoverCard' +import {Text} from '#/components/Typography' +import {FeedNameText} from '../util/FeedInfoText' + +export function PostFeedReason({ + reason, + moderation, + onOpenReposter, +}: { + reason: + | ReasonFeedSource + | AppBskyFeedDefs.ReasonRepost + | AppBskyFeedDefs.ReasonPin + | {[k: string]: unknown; $type: string} + moderation?: ModerationDecision + onOpenReposter?: () => void +}) { + const t = useTheme() + const {_} = useLingui() + + const {currentAccount} = useSession() + + if (isReasonFeedSource(reason)) { + return ( + + + + From{' '} + + + + + ) + } + + if (AppBskyFeedDefs.isReasonRepost(reason)) { + const isOwner = reason.by.did === currentAccount?.did + const reposter = createSanitizedDisplayName( + reason.by, + false, + moderation?.ui('displayName'), + ) + return ( + + + + {isOwner ? ( + Reposted by you + ) : ( + + Reposted by{' '} + + + {reposter} + + + + )} + + + ) + } + + if (AppBskyFeedDefs.isReasonPin(reason)) { + return ( + + + + Pinned + + + ) + } +} + +const styles = StyleSheet.create({ + includeReason: { + flexDirection: 'row', + alignItems: 'center', + marginBottom: 2, + marginLeft: -16, + }, +}) diff --git a/src/view/com/util/FeedInfoText.tsx b/src/view/com/util/FeedInfoText.tsx index 3ad05facb3..69476c9903 100644 --- a/src/view/com/util/FeedInfoText.tsx +++ b/src/view/com/util/FeedInfoText.tsx @@ -1,54 +1,51 @@ -import {type StyleProp, StyleSheet, type TextStyle} from 'react-native' +import {type StyleProp, type TextStyle} from 'react-native' import {sanitizeDisplayName} from '#/lib/strings/display-names' -import {type TypographyVariant} from '#/lib/ThemeContext' import {useFeedSourceInfoQuery} from '#/state/queries/feed' -import {TextLinkOnWebOnly} from './Link' +import {atoms as a, platform} from '#/alf' +import {WebOnlyInlineLinkText} from '#/components/Link' import {LoadingPlaceholder} from './LoadingPlaceholder' export function FeedNameText({ - type = 'md', uri, href, - lineHeight, numberOfLines, style, }: { - type?: TypographyVariant uri: string href: string - lineHeight?: number numberOfLines?: number style?: StyleProp }) { const {data, isError} = useFeedSourceInfoQuery({uri}) let inner - if (data?.displayName || isError) { + if (data || isError) { const displayName = data?.displayName || uri.split('/').pop() || '' inner = ( - + numberOfLines={numberOfLines}> + {sanitizeDisplayName(displayName)} + ) } else { inner = ( ) } return inner } - -const styles = StyleSheet.create({ - loadingPlaceholder: {position: 'relative', top: 1, left: 2}, -})