diff --git a/src/lib/moderation.ts b/src/lib/moderation.ts
index 6c08606ee8..8ba99128bc 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 900adfa81c..63119eedf8 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 && (
)}
@@ -526,10 +529,14 @@ let PostThreadItemLoaded = ({
{post.embed && (
+ moderation={moderation.embed}
+ moderationDecisions={moderation.decisions}
+ ignoreMute={isEmbedByEmbedder(post.embed, post.author.did)}
+ ignoreQuoteDecisions>
)}
diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx
index 2e8019e71a..9b1bf7a496 100644
--- a/src/view/com/post/Post.tsx
+++ b/src/view/com/post/Post.tsx
@@ -196,8 +196,14 @@ function PostInner({
{post.embed ? (
-
+
) : null}
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index dfb0cfcf68..b6c509e926 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -320,9 +320,15 @@ let FeedItemInner = ({
-
+
) : null}
diff --git a/src/view/com/util/moderation/ContentHider.tsx b/src/view/com/util/moderation/ContentHider.tsx
index c5c887685b..20749e33c7 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
childContainerStyle?: StyleProp
}>) {
@@ -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 (
{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 ca3bf11044..5c16a3b3eb 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
}) {
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 (
-
+
+
+
)
}