diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/moderation.ts | 21 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThreadItem.tsx | 9 | ||||
-rw-r--r-- | src/view/com/post/Post.tsx | 8 | ||||
-rw-r--r-- | src/view/com/posts/FeedItem.tsx | 8 | ||||
-rw-r--r-- | src/view/com/util/moderation/ContentHider.tsx | 23 | ||||
-rw-r--r-- | src/view/com/util/post-embeds/index.tsx | 15 |
6 files changed, 74 insertions, 10 deletions
diff --git a/src/lib/moderation.ts b/src/lib/moderation.ts index 6c08606ee..8ba99128b 100644 --- a/src/lib/moderation.ts +++ b/src/lib/moderation.ts @@ -1,4 +1,4 @@ -import {ModerationCause, ProfileModeration} from '@atproto/api' +import {ModerationCause, ProfileModeration, PostModeration} from '@atproto/api' export interface ModerationCauseDescription { name: string @@ -92,6 +92,25 @@ export function getProfileModerationCauses( }) as ModerationCause[] } +export function isPostMediaBlurred( + decisions: PostModeration['decisions'], +): boolean { + return decisions.post.blurMedia +} + +export function isQuoteBlurred( + decisions: PostModeration['decisions'], +): boolean { + return ( + decisions.quote?.blur || + decisions.quote?.blurMedia || + decisions.quote?.filter || + decisions.quotedAccount?.blur || + decisions.quotedAccount?.filter || + false + ) +} + export function isCauseALabelOnUri( cause: ModerationCause | undefined, uri: string, diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 900adfa81..63119eedf 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -351,11 +351,14 @@ let PostThreadItemLoaded = ({ {post.embed && ( <ContentHider moderation={moderation.embed} + moderationDecisions={moderation.decisions} ignoreMute={isEmbedByEmbedder(post.embed, post.author.did)} + ignoreQuoteDecisions style={s.mb10}> <PostEmbeds embed={post.embed} moderation={moderation.embed} + moderationDecisions={moderation.decisions} /> </ContentHider> )} @@ -526,10 +529,14 @@ let PostThreadItemLoaded = ({ {post.embed && ( <ContentHider style={styles.contentHider} - moderation={moderation.embed}> + moderation={moderation.embed} + moderationDecisions={moderation.decisions} + ignoreMute={isEmbedByEmbedder(post.embed, post.author.did)} + ignoreQuoteDecisions> <PostEmbeds embed={post.embed} moderation={moderation.embed} + moderationDecisions={moderation.decisions} /> </ContentHider> )} diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index 2e8019e71..9b1bf7a49 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -196,8 +196,14 @@ function PostInner({ {post.embed ? ( <ContentHider moderation={moderation.embed} + moderationDecisions={moderation.decisions} + ignoreQuoteDecisions style={styles.contentHider}> - <PostEmbeds embed={post.embed} moderation={moderation.embed} /> + <PostEmbeds + embed={post.embed} + moderation={moderation.embed} + moderationDecisions={moderation.decisions} + /> </ContentHider> ) : null} </ContentHider> diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index dfb0cfcf6..b6c509e92 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -320,9 +320,15 @@ let FeedItemInner = ({ <ContentHider testID="contentHider-embed" moderation={moderation.embed} + moderationDecisions={moderation.decisions} ignoreMute={isEmbedByEmbedder(post.embed, post.author.did)} + ignoreQuoteDecisions style={styles.embed}> - <PostEmbeds embed={post.embed} moderation={moderation.embed} /> + <PostEmbeds + embed={post.embed} + moderation={moderation.embed} + moderationDecisions={moderation.decisions} + /> </ContentHider> ) : null} </ContentHider> diff --git a/src/view/com/util/moderation/ContentHider.tsx b/src/view/com/util/moderation/ContentHider.tsx index c5c887685..20749e33c 100644 --- a/src/view/com/util/moderation/ContentHider.tsx +++ b/src/view/com/util/moderation/ContentHider.tsx @@ -2,25 +2,30 @@ import React from 'react' import {Pressable, StyleProp, StyleSheet, View, ViewStyle} from 'react-native' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {usePalette} from 'lib/hooks/usePalette' -import {ModerationUI} from '@atproto/api' +import {ModerationUI, PostModeration} from '@atproto/api' import {Text} from '../text/Text' import {ShieldExclamation} from 'lib/icons' import {describeModerationCause} from 'lib/moderation' import {useLingui} from '@lingui/react' import {msg} from '@lingui/macro' import {useModalControls} from '#/state/modals' +import {isPostMediaBlurred} from 'lib/moderation' export function ContentHider({ testID, moderation, + moderationDecisions, ignoreMute, + ignoreQuoteDecisions, style, childContainerStyle, children, }: React.PropsWithChildren<{ testID?: string moderation: ModerationUI + moderationDecisions?: PostModeration['decisions'] ignoreMute?: boolean + ignoreQuoteDecisions?: boolean style?: StyleProp<ViewStyle> childContainerStyle?: StyleProp<ViewStyle> }>) { @@ -29,7 +34,11 @@ export function ContentHider({ const [override, setOverride] = React.useState(false) const {openModal} = useModalControls() - if (!moderation.blur || (ignoreMute && moderation.cause?.type === 'muted')) { + if ( + !moderation.blur || + (ignoreMute && moderation.cause?.type === 'muted') || + shouldIgnoreQuote(moderationDecisions, ignoreQuoteDecisions) + ) { return ( <View testID={testID} style={[styles.outer, style]}> {children} @@ -99,6 +108,16 @@ export function ContentHider({ ) } +function shouldIgnoreQuote( + decisions: PostModeration['decisions'] | undefined, + ignore: boolean | undefined, +): boolean { + if (!decisions || !ignore) { + return false + } + return !isPostMediaBlurred(decisions) +} + const styles = StyleSheet.create({ outer: { overflow: 'hidden', diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx index ca3bf1104..5c16a3b3e 100644 --- a/src/view/com/util/post-embeds/index.tsx +++ b/src/view/com/util/post-embeds/index.tsx @@ -16,6 +16,7 @@ import { AppBskyFeedDefs, AppBskyGraphDefs, ModerationUI, + PostModeration, } from '@atproto/api' import {Link} from '../Link' import {ImageLayoutGrid} from '../images/ImageLayoutGrid' @@ -28,8 +29,9 @@ import {getYoutubeVideoId} from 'lib/strings/url-helpers' import {MaybeQuoteEmbed} from './QuoteEmbed' import {AutoSizedImage} from '../images/AutoSizedImage' import {ListEmbed} from './ListEmbed' -import {isCauseALabelOnUri} from 'lib/moderation' +import {isCauseALabelOnUri, isQuoteBlurred} from 'lib/moderation' import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard' +import {ContentHider} from '../moderation/ContentHider' type Embed = | AppBskyEmbedRecord.View @@ -41,10 +43,12 @@ type Embed = export function PostEmbeds({ embed, moderation, + moderationDecisions, style, }: { embed?: Embed moderation: ModerationUI + moderationDecisions?: PostModeration['decisions'] style?: StyleProp<ViewStyle> }) { const pal = usePalette('default') @@ -55,14 +59,17 @@ export function PostEmbeds({ // = if (AppBskyEmbedRecordWithMedia.isView(embed)) { const isModOnQuote = - AppBskyEmbedRecord.isViewRecord(embed.record.record) && - isCauseALabelOnUri(moderation.cause, embed.record.record.uri) + (AppBskyEmbedRecord.isViewRecord(embed.record.record) && + isCauseALabelOnUri(moderation.cause, embed.record.record.uri)) || + (moderationDecisions && isQuoteBlurred(moderationDecisions)) const mediaModeration = isModOnQuote ? {} : moderation const quoteModeration = isModOnQuote ? moderation : {} return ( <View style={[styles.stackContainer, style]}> <PostEmbeds embed={embed.media} moderation={mediaModeration} /> - <MaybeQuoteEmbed embed={embed.record} moderation={quoteModeration} /> + <ContentHider moderation={quoteModeration}> + <MaybeQuoteEmbed embed={embed.record} moderation={quoteModeration} /> + </ContentHider> </View> ) } |