about summary refs log tree commit diff
path: root/src/view/com/util/post-embeds
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/util/post-embeds')
-rw-r--r--src/view/com/util/post-embeds/QuoteEmbed.tsx129
-rw-r--r--src/view/com/util/post-embeds/index.tsx106
2 files changed, 133 insertions, 102 deletions
diff --git a/src/view/com/util/post-embeds/QuoteEmbed.tsx b/src/view/com/util/post-embeds/QuoteEmbed.tsx
index 35b091269..2b1c3e617 100644
--- a/src/view/com/util/post-embeds/QuoteEmbed.tsx
+++ b/src/view/com/util/post-embeds/QuoteEmbed.tsx
@@ -1,13 +1,15 @@
 import React from 'react'
 import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
 import {
+  AppBskyFeedDefs,
   AppBskyEmbedRecord,
   AppBskyFeedPost,
   AppBskyEmbedImages,
   AppBskyEmbedRecordWithMedia,
-  ModerationUI,
   AppBskyEmbedExternal,
   RichText as RichTextAPI,
+  moderatePost,
+  ModerationDecision,
 } from '@atproto/api'
 import {AtUri} from '@atproto/api'
 import {PostMeta} from '../PostMeta'
@@ -16,20 +18,20 @@ import {Text} from '../text/Text'
 import {usePalette} from 'lib/hooks/usePalette'
 import {ComposerOptsQuote} from 'state/shell/composer'
 import {PostEmbeds} from '.'
-import {PostAlerts} from '../moderation/PostAlerts'
+import {PostAlerts} from '../../../../components/moderation/PostAlerts'
 import {makeProfileLink} from 'lib/routes/links'
 import {InfoCircleIcon} from 'lib/icons'
 import {Trans} from '@lingui/macro'
+import {useModerationOpts} from '#/state/queries/preferences'
+import {ContentHider} from '../../../../components/moderation/ContentHider'
 import {RichText} from '#/components/RichText'
 import {atoms as a} from '#/alf'
 
 export function MaybeQuoteEmbed({
   embed,
-  moderation,
   style,
 }: {
   embed: AppBskyEmbedRecord.View
-  moderation: ModerationUI
   style?: StyleProp<ViewStyle>
 }) {
   const pal = usePalette('default')
@@ -39,17 +41,9 @@ export function MaybeQuoteEmbed({
     AppBskyFeedPost.validateRecord(embed.record.value).success
   ) {
     return (
-      <QuoteEmbed
-        quote={{
-          author: embed.record.author,
-          cid: embed.record.cid,
-          uri: embed.record.uri,
-          indexedAt: embed.record.indexedAt,
-          text: embed.record.value.text,
-          facets: embed.record.value.facets,
-          embeds: embed.record.embeds,
-        }}
-        moderation={moderation}
+      <QuoteEmbedModerated
+        viewRecord={embed.record}
+        postRecord={embed.record.value}
         style={style}
       />
     )
@@ -75,19 +69,49 @@ export function MaybeQuoteEmbed({
   return null
 }
 
+function QuoteEmbedModerated({
+  viewRecord,
+  postRecord,
+  style,
+}: {
+  viewRecord: AppBskyEmbedRecord.ViewRecord
+  postRecord: AppBskyFeedPost.Record
+  style?: StyleProp<ViewStyle>
+}) {
+  const moderationOpts = useModerationOpts()
+  const moderation = React.useMemo(() => {
+    return moderationOpts
+      ? moderatePost(viewRecordToPostView(viewRecord), moderationOpts)
+      : undefined
+  }, [viewRecord, moderationOpts])
+
+  const quote = {
+    author: viewRecord.author,
+    cid: viewRecord.cid,
+    uri: viewRecord.uri,
+    indexedAt: viewRecord.indexedAt,
+    text: postRecord.text,
+    facets: postRecord.facets,
+    embeds: viewRecord.embeds,
+  }
+
+  return <QuoteEmbed quote={quote} moderation={moderation} style={style} />
+}
+
 export function QuoteEmbed({
   quote,
   moderation,
   style,
 }: {
   quote: ComposerOptsQuote
-  moderation?: ModerationUI
+  moderation?: ModerationDecision
   style?: StyleProp<ViewStyle>
 }) {
   const pal = usePalette('default')
   const itemUrip = new AtUri(quote.uri)
   const itemHref = makeProfileLink(quote.author, 'post', itemUrip.rkey)
   const itemTitle = `Post by ${quote.author.handle}`
+
   const richText = React.useMemo(
     () =>
       quote.text.trim()
@@ -95,6 +119,7 @@ export function QuoteEmbed({
         : undefined,
     [quote.text, quote.facets],
   )
+
   const embed = React.useMemo(() => {
     const e = quote.embeds?.[0]
 
@@ -108,40 +133,52 @@ export function QuoteEmbed({
       return e.media
     }
   }, [quote.embeds])
+
   return (
-    <Link
-      style={[styles.container, pal.borderDark, style]}
-      hoverStyle={{borderColor: pal.colors.borderLinkHover}}
-      href={itemHref}
-      title={itemTitle}>
-      <View pointerEvents="none">
-        <PostMeta
-          author={quote.author}
-          showAvatar
-          authorHasWarning={false}
-          postHref={itemHref}
-          timestamp={quote.indexedAt}
-        />
-      </View>
-      {moderation ? (
-        <PostAlerts moderation={moderation} style={styles.alert} />
-      ) : null}
-      {richText ? (
-        <RichText
-          enableTags
-          value={richText}
-          style={[a.text_md]}
-          numberOfLines={20}
-          disableLinks
-          authorHandle={quote.author.handle}
-        />
-      ) : null}
-      {embed && <PostEmbeds embed={embed} moderation={{}} />}
-    </Link>
+    <ContentHider modui={moderation?.ui('contentList')}>
+      <Link
+        style={[styles.container, pal.borderDark, style]}
+        hoverStyle={{borderColor: pal.colors.borderLinkHover}}
+        href={itemHref}
+        title={itemTitle}>
+        <View pointerEvents="none">
+          <PostMeta
+            author={quote.author}
+            moderation={moderation}
+            showAvatar
+            authorHasWarning={false}
+            postHref={itemHref}
+            timestamp={quote.indexedAt}
+          />
+        </View>
+        {moderation ? (
+          <PostAlerts modui={moderation.ui('contentView')} style={[a.py_xs]} />
+        ) : null}
+        {richText ? (
+          <RichText
+            value={richText}
+            style={[a.text_md]}
+            numberOfLines={20}
+            disableLinks
+          />
+        ) : null}
+        {embed && <PostEmbeds embed={embed} moderation={moderation} />}
+      </Link>
+    </ContentHider>
   )
 }
 
-export default QuoteEmbed
+function viewRecordToPostView(
+  viewRecord: AppBskyEmbedRecord.ViewRecord,
+): AppBskyFeedDefs.PostView {
+  const {value, embeds, ...rest} = viewRecord
+  return {
+    ...rest,
+    $type: 'app.bsky.feed.defs#postView',
+    record: value,
+    embed: embeds?.[0],
+  }
+}
 
 const styles = StyleSheet.create({
   container: {
diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx
index 7e235babb..47091fbb0 100644
--- a/src/view/com/util/post-embeds/index.tsx
+++ b/src/view/com/util/post-embeds/index.tsx
@@ -15,8 +15,7 @@ import {
   AppBskyEmbedRecordWithMedia,
   AppBskyFeedDefs,
   AppBskyGraphDefs,
-  ModerationUI,
-  PostModeration,
+  ModerationDecision,
 } from '@atproto/api'
 import {Link} from '../Link'
 import {ImageLayoutGrid} from '../images/ImageLayoutGrid'
@@ -26,9 +25,8 @@ import {ExternalLinkEmbed} from './ExternalLinkEmbed'
 import {MaybeQuoteEmbed} from './QuoteEmbed'
 import {AutoSizedImage} from '../images/AutoSizedImage'
 import {ListEmbed} from './ListEmbed'
-import {isCauseALabelOnUri, isQuoteBlurred} from 'lib/moderation'
 import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard'
-import {ContentHider} from '../moderation/ContentHider'
+import {ContentHider} from '../../../../components/moderation/ContentHider'
 import {isNative} from '#/platform/detection'
 import {shareUrl} from '#/lib/sharing'
 
@@ -42,12 +40,10 @@ type Embed =
 export function PostEmbeds({
   embed,
   moderation,
-  moderationDecisions,
   style,
 }: {
   embed?: Embed
-  moderation: ModerationUI
-  moderationDecisions?: PostModeration['decisions']
+  moderation?: ModerationDecision
   style?: StyleProp<ViewStyle>
 }) {
   const pal = usePalette('default')
@@ -66,18 +62,10 @@ export function PostEmbeds({
   // quote post with media
   // =
   if (AppBskyEmbedRecordWithMedia.isView(embed)) {
-    const isModOnQuote =
-      (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={style}>
-        <PostEmbeds embed={embed.media} moderation={mediaModeration} />
-        <ContentHider moderation={quoteModeration}>
-          <MaybeQuoteEmbed embed={embed.record} moderation={quoteModeration} />
-        </ContentHider>
+        <PostEmbeds embed={embed.media} moderation={moderation} />
+        <MaybeQuoteEmbed embed={embed.record} />
       </View>
     )
   }
@@ -86,6 +74,7 @@ export function PostEmbeds({
     // custom feed embed (i.e. generator view)
     // =
     if (AppBskyFeedDefs.isGeneratorView(embed.record)) {
+      // TODO moderation
       return (
         <FeedSourceCard
           feedUri={embed.record.uri}
@@ -97,16 +86,13 @@ export function PostEmbeds({
 
     // list embed
     if (AppBskyGraphDefs.isListView(embed.record)) {
+      // TODO moderation
       return <ListEmbed item={embed.record} />
     }
 
     // quote post
     // =
-    return (
-      <ContentHider moderation={moderation}>
-        <MaybeQuoteEmbed embed={embed} style={style} moderation={moderation} />
-      </ContentHider>
-    )
+    return <MaybeQuoteEmbed embed={embed} style={style} />
   }
 
   // image embed
@@ -132,35 +118,41 @@ export function PostEmbeds({
       if (images.length === 1) {
         const {alt, thumb, aspectRatio} = images[0]
         return (
-          <View style={[styles.imagesContainer, style]}>
-            <AutoSizedImage
-              alt={alt}
-              uri={thumb}
-              dimensionsHint={aspectRatio}
-              onPress={() => _openLightbox(0)}
-              onPressIn={() => onPressIn(0)}
-              style={[styles.singleImage]}>
-              {alt === '' ? null : (
-                <View style={styles.altContainer}>
-                  <Text style={styles.alt} accessible={false}>
-                    ALT
-                  </Text>
-                </View>
-              )}
-            </AutoSizedImage>
-          </View>
+          <ContentHider modui={moderation?.ui('contentMedia')}>
+            <View style={[styles.imagesContainer, style]}>
+              <AutoSizedImage
+                alt={alt}
+                uri={thumb}
+                dimensionsHint={aspectRatio}
+                onPress={() => _openLightbox(0)}
+                onPressIn={() => onPressIn(0)}
+                style={[styles.singleImage]}>
+                {alt === '' ? null : (
+                  <View style={styles.altContainer}>
+                    <Text style={styles.alt} accessible={false}>
+                      ALT
+                    </Text>
+                  </View>
+                )}
+              </AutoSizedImage>
+            </View>
+          </ContentHider>
         )
       }
 
       return (
-        <View style={[styles.imagesContainer, style]}>
-          <ImageLayoutGrid
-            images={embed.images}
-            onPress={_openLightbox}
-            onPressIn={onPressIn}
-            style={embed.images.length === 1 ? [styles.singleImage] : undefined}
-          />
-        </View>
+        <ContentHider modui={moderation?.ui('contentMedia')}>
+          <View style={[styles.imagesContainer, style]}>
+            <ImageLayoutGrid
+              images={embed.images}
+              onPress={_openLightbox}
+              onPressIn={onPressIn}
+              style={
+                embed.images.length === 1 ? [styles.singleImage] : undefined
+              }
+            />
+          </View>
+        </ContentHider>
       )
     }
   }
@@ -171,15 +163,17 @@ export function PostEmbeds({
     const link = embed.external
 
     return (
-      <Link
-        asAnchor
-        anchorNoUnderline
-        href={link.uri}
-        style={[styles.extOuter, pal.view, pal.borderDark, style]}
-        hoverStyle={{borderColor: pal.colors.borderLinkHover}}
-        onLongPress={onShareExternal}>
-        <ExternalLinkEmbed link={link} />
-      </Link>
+      <ContentHider modui={moderation?.ui('contentMedia')}>
+        <Link
+          asAnchor
+          anchorNoUnderline
+          href={link.uri}
+          style={[styles.extOuter, pal.view, pal.borderDark, style]}
+          hoverStyle={{borderColor: pal.colors.borderLinkHover}}
+          onLongPress={onShareExternal}>
+          <ExternalLinkEmbed link={link} />
+        </Link>
+      </ContentHider>
     )
   }