diff --git a/bskyogcard/.eslintrc.cjs b/bskyogcard/.eslintrc.cjs
new file mode 100644
index 0000000000..2bafdbe83a
--- /dev/null
+++ b/bskyogcard/.eslintrc.cjs
@@ -0,0 +1,81 @@
+module.exports = {
+ root: true,
+ extends: [
+ 'plugin:react/recommended',
+ 'plugin:react/jsx-runtime',
+ 'prettier',
+ ],
+ parser: '@typescript-eslint/parser',
+ plugins: [
+ '@typescript-eslint',
+ 'react',
+ 'simple-import-sort',
+ 'eslint-plugin-react-compiler',
+ ],
+ rules: {
+ 'react/no-unescaped-entities': 0,
+ 'react/prop-types': 0,
+ 'react-native/no-inline-styles': 0,
+ 'simple-import-sort/imports': [
+ 'error',
+ {
+ groups: [
+ // Side effect imports.
+ ['^\\u0000'],
+ // Node.js builtins prefixed with `node:`.
+ ['^node:'],
+ // Packages.
+ // Things that start with a letter (or digit or underscore), or `@` followed by a letter.
+ // React/React Native priortized, followed by expo
+ // Followed by all packages excluding unprefixed relative ones
+ [
+ '^(react\\/(.*)$)|^(react$)|^(react-native(.*)$)',
+ '^(expo(.*)$)|^(expo$)',
+ '^(?!(?:alf|components|lib|locale|logger|platform|screens|state|view)(?:$|\\/))@?\\w',
+ ],
+ // Relative imports.
+ // Ideally, anything that starts with a dot or #
+ // due to unprefixed relative imports being used, we whitelist the relative paths we use
+ // (?:$|\\/) matches end of string or /
+ [
+ '^(?:#\\/)?(?:lib|state|logger|platform|locale)(?:$|\\/)',
+ '^(?:#\\/)?view(?:$|\\/)',
+ '^(?:#\\/)?screens(?:$|\\/)',
+ '^(?:#\\/)?alf(?:$|\\/)',
+ '^(?:#\\/)?components(?:$|\\/)',
+ '^#\\/',
+ '^\\.',
+ ],
+ // anything else - hopefully we don't have any of these
+ ['^'],
+ ],
+ },
+ ],
+ 'simple-import-sort/exports': 'error',
+ 'react-compiler/react-compiler': 'warn',
+ 'no-restricted-imports': [
+ 'error',
+ {
+ paths: [
+ {
+ name: '@atproto/api',
+ importNames: ['moderatePost'],
+ message:
+ 'Please use `moderatePost_wrapped` from `#/lib/moderatePost_wrapped` instead.',
+ },
+ ],
+ },
+ ],
+ },
+ ignorePatterns: [
+ 'coverage',
+ '*.lock',
+ '.husky',
+ '*.html',
+ ],
+ parserOptions: {
+ sourceType: 'module',
+ ecmaVersion: 'latest',
+ },
+}
+
diff --git a/bskyogcard/src/components/FeedCard.tsx b/bskyogcard/src/components/FeedCard.tsx
new file mode 100644
index 0000000000..bef859c76a
--- /dev/null
+++ b/bskyogcard/src/components/FeedCard.tsx
@@ -0,0 +1,74 @@
+import {AppBskyFeedDefs, moderateFeedGenerator} from '@atproto/api'
+
+import {ModeratorData} from '../data/getModeratorData.js'
+import {PostData} from '../data/getPostData.js'
+import {atoms as a, theme as t} from '../theme/index.js'
+import {formatCount} from '../util/formatCount.js'
+import {getModerationCauseInfo} from '../util/getModerationCauseInfo.js'
+import {Box} from './Box.js'
+import {Image} from './Image.js'
+import {ModeratedEmbed} from './ModeratedEmbed.js'
+import {Text} from './Text.js'
+
+export function FeedCard({
+ embed,
+ data,
+ moderatorData,
+}: {
+ embed: AppBskyFeedDefs.GeneratorView
+ data: PostData
+ moderatorData: ModeratorData
+}) {
+ const feedModeration = moderateFeedGenerator(
+ embed,
+ moderatorData.moderationOptions,
+ )
+ const modui = feedModeration.ui('contentList')
+ const info = getModerationCauseInfo({
+ cause: modui.blurs.at(0),
+ moderatorData,
+ })
+
+ if (info) {
+ return
+ }
+
+ const {avatar, displayName, likeCount = 0, creator} = embed
+ const image = data.images.get(avatar || '')
+
+ return (
+
+
+ {image && (
+
+ )}
+
+ {displayName}
+ By @{creator.handle}
+
+
+
+ {likeCount > 1 && (
+
+ Liked by {formatCount(likeCount)} users
+
+ )}
+
+ )
+}
diff --git a/bskyogcard/src/components/Image.tsx b/bskyogcard/src/components/Image.tsx
index b969f64d29..1d6ce670d8 100644
--- a/bskyogcard/src/components/Image.tsx
+++ b/bskyogcard/src/components/Image.tsx
@@ -1,7 +1,8 @@
import React from 'react'
import {Image as ImageSource} from '../data/getPostData.js'
-import {style as s} from '../theme/index.js'
+import {atoms as a, style as s, theme as t} from '../theme/index.js'
+import {Box} from './Box.js'
export type ImageProps = Omit<
React.ImgHTMLAttributes,
@@ -21,3 +22,28 @@ export function Image({image, cx, ...rest}: ImageProps) {
/>
)
}
+
+export function SquareImage({image}: {image: ImageSource}) {
+ return (
+
+
+
+ )
+}
diff --git a/bskyogcard/src/components/LinkCard.tsx b/bskyogcard/src/components/LinkCard.tsx
new file mode 100644
index 0000000000..523e0f5f58
--- /dev/null
+++ b/bskyogcard/src/components/LinkCard.tsx
@@ -0,0 +1,59 @@
+import {Image as ImageSource} from '../data/getPostData.js'
+import {atoms as a, theme as t} from '../theme/index.js'
+import {toShortUrl} from '../util/toShortUrl.js'
+import {Box} from './Box.js'
+import {Image} from './Image.js'
+import {Text} from './Text.js'
+
+export function LinkCard({
+ image,
+ uri,
+ title,
+ description,
+}: {
+ image?: ImageSource
+ uri?: string
+ title: string
+ description: string
+}) {
+ return (
+
+ {image && (
+
+
+
+ )}
+
+ {uri && (
+
+ {toShortUrl(uri)}
+
+ )}
+ {title}
+ {description}
+
+
+ )
+}
diff --git a/bskyogcard/src/components/ListCard.tsx b/bskyogcard/src/components/ListCard.tsx
new file mode 100644
index 0000000000..df5d6b7ddb
--- /dev/null
+++ b/bskyogcard/src/components/ListCard.tsx
@@ -0,0 +1,67 @@
+import {AppBskyGraphDefs, moderateUserList} from '@atproto/api'
+
+import {ModeratorData} from '../data/getModeratorData.js'
+import {PostData} from '../data/getPostData.js'
+import {atoms as a, theme as t} from '../theme/index.js'
+import {getModerationCauseInfo} from '../util/getModerationCauseInfo.js'
+import {Box} from './Box.js'
+import {Image} from './Image.js'
+import {ModeratedEmbed} from './ModeratedEmbed.js'
+import {Text} from './Text.js'
+
+export function ListCard({
+ embed,
+ data,
+ moderatorData,
+}: {
+ embed: AppBskyGraphDefs.ListView
+ data: PostData
+ moderatorData: ModeratorData
+}) {
+ const listModeration = moderateUserList(
+ embed,
+ moderatorData.moderationOptions,
+ )
+ const modui = listModeration.ui('contentList')
+ const info = getModerationCauseInfo({
+ cause: modui.blurs.at(0),
+ moderatorData,
+ })
+
+ if (info) {
+ return
+ }
+
+ const {avatar, name, creator} = embed
+ const image = data.images.get(avatar || '')
+
+ return (
+
+
+ {image && (
+
+ )}
+
+ {name}
+ By @{creator.handle}
+
+
+
+ )
+}
diff --git a/bskyogcard/src/components/ModeratedEmbed.tsx b/bskyogcard/src/components/ModeratedEmbed.tsx
new file mode 100644
index 0000000000..19880a0892
--- /dev/null
+++ b/bskyogcard/src/components/ModeratedEmbed.tsx
@@ -0,0 +1,25 @@
+import {atoms as a, theme as t} from '../theme/index.js'
+import {ModerationCauseInfo} from '../util/getModerationCauseInfo.js'
+import {Box} from './Box.js'
+import {Text} from './Text.js'
+
+export function ModeratedEmbed({info}: {info: ModerationCauseInfo}) {
+ return (
+
+
+
+
+ {info.name}
+
+
+
+ )
+}
diff --git a/bskyogcard/src/components/Post.tsx b/bskyogcard/src/components/Post.tsx
index 1673995375..c59c3f4345 100644
--- a/bskyogcard/src/components/Post.tsx
+++ b/bskyogcard/src/components/Post.tsx
@@ -1,42 +1,22 @@
-/* eslint-disable bsky-internal/avoid-unwrapped-text, react-native-a11y/has-valid-accessibility-ignores-invert-colors */
-import React from 'react'
import {
- AppBskyEmbedExternal,
- AppBskyEmbedImages,
- AppBskyEmbedRecord,
- AppBskyEmbedRecordWithMedia,
AppBskyFeedDefs,
AppBskyFeedPost,
- AppBskyGraphDefs,
- AppBskyGraphStarterpack,
- moderateFeedGenerator,
- moderateUserList,
- ModerationDecision,
RichText as RichTextApi,
} from '@atproto/api'
import {ModeratorData} from '../data/getModeratorData.js'
-import {Image as ImageSource, PostData} from '../data/getPostData.js'
+import {PostData} from '../data/getPostData.js'
import {atoms as a, gradient, theme as t} from '../theme/index.js'
import {formatCount} from '../util/formatCount.js'
import {formatDate} from '../util/formatDate.js'
-import {
- getModerationCauseInfo,
- ModerationCauseInfo,
-} from '../util/getModerationCauseInfo.js'
-import {getStarterPackImageUri} from '../util/getStarterPackImageUri.js'
import {moderatePost} from '../util/moderatePost.js'
-import {toShortUrl} from '../util/toShortUrl.js'
-import {viewRecordToPostView} from '../util/viewRecordToPostView.js'
import {Avatar} from './Avatar.js'
import {Box} from './Box.js'
-import * as Grid from './Grid.js'
-import {CircleInfo} from './icons/CircleInfo.js'
import {Heart} from './icons/Heart.js'
import {Logomark} from './icons/Logomark.js'
import {Logotype} from './icons/Logotype.js'
import {Repost} from './icons/Repost.js'
-import {Image} from './Image.js'
+import {PostEmbed} from './PostEmbed.js'
import {RichText} from './RichText.js'
import {Text} from './Text.js'
@@ -105,7 +85,7 @@ export function Post({
{post.embed && (
-
)
}
-
-export function Embeds({
- embed,
- data,
- moderation,
- moderatorData,
- hideNestedEmbeds,
-}: {
- embed: AppBskyFeedDefs.PostView['embed']
- data: PostData
- moderation: ModerationDecision
- moderatorData: ModeratorData
- hideNestedEmbeds?: boolean
-}) {
- /**
- * If record-with-media, pass through the existing moderation into `Embeds`
- * and move on to `QuoteEmbed`'s own moderation.
- */
- if (AppBskyEmbedRecordWithMedia.isView(embed)) {
- return (
-
-
- {!hideNestedEmbeds && (
-
- )}
-
- )
- }
-
- const mod = moderation.ui('contentMedia')
- const info = getModerationCauseInfo({
- cause: mod.blurs.at(0),
- moderatorData,
- })
-
- if (info) {
- return
- }
-
- if (AppBskyEmbedExternal.isView(embed)) {
- const {title, description, uri, thumb} = embed.external
- const image = data.images.get(thumb)
- return (
-
- )
- }
-
- if (AppBskyEmbedImages.isView(embed)) {
- const {images} = embed
-
- if (images.length > 0) {
- const imgs = images.map(({fullsize}) => data.images.get(fullsize))
- if (imgs.length === 1) {
- return (
-
-
-
- )
- } else if (imgs.length === 2) {
- return (
-
-
-
-
-
-
-
-
- )
- } else if (imgs.length === 3) {
- return (
-
-
-
-
-
-
-
-
-
- )
- } else {
- return (
-
-
-
-
-
-
-
-
-
-
- )
- }
- }
- }
-
- if (AppBskyEmbedRecord.isView(embed)) {
- if (AppBskyFeedDefs.isGeneratorView(embed.record)) {
- return (
-
- )
- }
-
- if (AppBskyGraphDefs.isListView(embed.record)) {
- return (
-
- )
- }
-
- if (
- AppBskyGraphDefs.isValidStarterPackViewBasic(embed.record) &&
- AppBskyGraphStarterpack.isValidRecord(embed.record.record)
- ) {
- const uri = getStarterPackImageUri(embed.record)
- const {name, description} = embed.record.record
- const image = data.images.get(uri)
- return
- }
-
- return (
-
- )
- }
-
- return null
-}
-
-export function FeedCard({
- embed,
- data,
- moderatorData,
-}: {
- embed: AppBskyFeedDefs.GeneratorView
- data: PostData
- moderatorData: ModeratorData
-}) {
- const feedModeration = moderateFeedGenerator(
- embed,
- moderatorData.moderationOptions,
- )
- const modui = feedModeration.ui('contentList')
- const info = getModerationCauseInfo({
- cause: modui.blurs.at(0),
- moderatorData,
- })
-
- if (info) {
- return
- }
-
- const {avatar, displayName, likeCount, creator} = embed
- const image = data.images.get(avatar)
-
- return (
-
-
- {image && (
-
- )}
-
- {displayName}
- By @{creator.handle}
-
-
-
- {likeCount > 1 && (
-
- Liked by {formatCount(likeCount)} users
-
- )}
-
- )
-}
-
-export function ListCard({
- embed,
- data,
- moderatorData,
-}: {
- embed: AppBskyGraphDefs.ListView
- data: PostData
- moderatorData: ModeratorData
-}) {
- const listModeration = moderateUserList(
- embed,
- moderatorData.moderationOptions,
- )
- const modui = listModeration.ui('contentList')
- const info = getModerationCauseInfo({
- cause: modui.blurs.at(0),
- moderatorData,
- })
-
- if (info) {
- return
- }
-
- const {avatar, name, creator} = embed
- const image = data.images.get(avatar)
-
- return (
-
-
- {image && (
-
- )}
-
- {name}
- By @{creator.handle}
-
-
-
- )
-}
-
-export function LinkCard({
- image,
- uri,
- title,
- description,
-}: {
- image?: ImageSource
- uri?: string
- title: string
- description: string
-}) {
- return (
-
- {image && (
-
-
-
- )}
-
- {uri && (
-
- {toShortUrl(uri)}
-
- )}
- {title}
- {description}
-
-
- )
-}
-
-export function SquareImage({image}: {image: ImageSource}) {
- return (
-
-
-
- )
-}
-
-export function QuoteEmbed({
- embed,
- data,
- moderatorData,
-}: {
- embed: AppBskyEmbedRecord.View
- data: PostData
- moderatorData: ModeratorData
-}) {
- if (
- AppBskyEmbedRecord.isValidViewRecord(embed.record) &&
- AppBskyFeedPost.isValidRecord(embed.record.value)
- ) {
- const {author, value: post, embeds} = embed.record
- const avatar = data.images.get(author.avatar)
- const rt = post.text
- ? new RichTextApi({
- text: post.text,
- facets: post.facets,
- })
- : undefined
- const postView = viewRecordToPostView(embed.record)
- const moderation = moderatePost(postView, moderatorData.moderationOptions)
-
- const mod = moderation.ui('contentView')
- const info = getModerationCauseInfo({
- cause: mod.blurs.at(0),
- moderatorData,
- })
-
- if (info) {
- return
- }
-
- return (
-
-
-
-
-
- {author.displayName || author.handle}
-
-
- @{author.handle}
-
-
-
-
- {rt && }
-
- {Boolean(embeds && embeds.length) && (
-
-
-
- )}
-
- )
- } else if (AppBskyEmbedRecord.isViewBlocked(embed.record)) {
- return Quoted post is blocked
- } else if (AppBskyEmbedRecord.isViewNotFound(embed.record)) {
- return (
-
- Quoted post not found, it may have been deleted.
-
- )
- } else if (AppBskyEmbedRecord.isViewDetached(embed.record)) {
- return Quoted post detached by author
- }
- return null
-}
-
-export function NotQuoteEmbed({children}: {children: React.ReactNode}) {
- return (
-
-
-
- {children}
-
-
- )
-}
-
-export function ModeratedEmbed({info}: {info: ModerationCauseInfo}) {
- return (
-
-
-
-
- {info.name}
-
-
-
- )
-}
diff --git a/bskyogcard/src/components/PostEmbed.tsx b/bskyogcard/src/components/PostEmbed.tsx
new file mode 100644
index 0000000000..1556b99985
--- /dev/null
+++ b/bskyogcard/src/components/PostEmbed.tsx
@@ -0,0 +1,240 @@
+import {
+ AppBskyFeedDefs,
+ AppBskyGraphStarterpack,
+ ModerationDecision,
+} from '@atproto/api'
+
+import {ModeratorData} from '../data/getModeratorData.js'
+import {Image as ImageSource, PostData} from '../data/getPostData.js'
+import {atoms as a} from '../theme/index.js'
+import {getStarterPackImageUri} from '../util/getStarterPackImageUri.js'
+import {Embed, EmbedType,parseEmbed} from '../util/parseEmbed.js'
+import {Box} from './Box.js'
+import {FeedCard} from './FeedCard.js'
+import * as Grid from './Grid.js'
+import {Image, SquareImage} from './Image.js'
+import {LinkCard} from './LinkCard.js'
+import {ListCard} from './ListCard.js'
+import {NotQuotePost,QuotePost} from './PostEmbed/QuotePost.js'
+
+type CommonProps = {
+ data: PostData
+ moderation: ModerationDecision
+ moderatorData: ModeratorData
+ hideNestedEmbeds?: boolean
+}
+
+export function PostEmbed({
+ embed: rawEmbed,
+ ...rest
+}: CommonProps & {
+ embed: AppBskyFeedDefs.PostView['embed']
+}) {
+ const embed = parseEmbed(rawEmbed)
+
+ switch (embed.type) {
+ case 'images':
+ case 'link':
+ case 'video':
+ return
+ case 'feed':
+ case 'list':
+ case 'starter_pack':
+ case 'post':
+ case 'post_blocked':
+ case 'post_detached':
+ case 'post_not_found':
+ return
+ case 'post_with_media':
+ return (
+
+
+ {!rest.hideNestedEmbeds && (
+
+ )}
+
+ )
+ default:
+ return null
+ }
+}
+
+export function MediaEmbeds({
+ embed,
+ ...rest
+}: CommonProps & {
+ embed: Embed
+}) {
+ switch (embed.type) {
+ case 'images': {
+ return
+ }
+ case 'link': {
+ return
+ }
+ case 'video': {
+ return null
+ }
+ default:
+ return null
+ }
+}
+
+export function RecordEmbeds({
+ embed,
+ ...rest
+}: CommonProps & {
+ embed: Embed
+}) {
+ switch (embed.type) {
+ case 'feed': {
+ return
+ }
+ case 'list': {
+ return
+ }
+ case 'starter_pack': {
+ return
+ }
+ case 'post': {
+ return
+ }
+ case 'post_blocked': {
+ return Quoted post is blocked
+ }
+ case 'post_detached': {
+ return Quoted post detached by author
+ }
+ case 'post_not_found': {
+ return (
+
+ Quoted post not found, it may have been deleted.
+
+ )
+ }
+ }
+}
+
+export function QuoteEmbed({
+ embed,
+ ...rest
+}: CommonProps & {
+ embed: EmbedType<'post'>
+}) {
+ return
+}
+
+export function StarterPackEmbed({
+ embed,
+ ...rest
+}: CommonProps & {
+ embed: EmbedType<'starter_pack'>
+}) {
+ const uri = getStarterPackImageUri(embed.view)
+ if (!AppBskyGraphStarterpack.isValidRecord(embed.view.record)) return null
+ const {name, description} = embed.view.record
+ const image = rest.data.images.get(uri)
+ return
+}
+
+export function ListEmbed({
+ embed,
+ ...rest
+}: CommonProps & {
+ embed: EmbedType<'list'>
+}) {
+ return (
+
+ )
+}
+
+export function FeedEmbed({
+ embed,
+ ...rest
+}: CommonProps & {
+ embed: EmbedType<'feed'>
+}) {
+ return (
+
+ )
+}
+
+export function LinkEmbed({
+ embed,
+ ...rest
+}: CommonProps & {
+ embed: EmbedType<'link'>
+}) {
+ const {title, description, uri, thumb} = embed.view.external
+ if (!thumb) return null
+ const image = rest.data.images.get(thumb)
+ return (
+
+ )
+}
+
+export function ImagesEmbed({
+ embed,
+ ...rest
+}: CommonProps & {
+ embed: EmbedType<'images'>
+}) {
+ const {images} = embed.view
+
+ if (images.length > 0) {
+ const imgs = images
+ .map(({fullsize}) => rest.data.images.get(fullsize))
+ .filter(Boolean) as ImageSource[]
+ if (imgs.length === 1) {
+ return (
+
+
+
+ )
+ } else if (imgs.length === 2) {
+ return (
+
+
+
+
+
+
+
+
+ )
+ } else if (imgs.length === 3) {
+ return (
+
+
+
+
+
+
+
+
+
+ )
+ } else {
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+ }
+}
diff --git a/bskyogcard/src/components/PostEmbed/QuotePost.tsx b/bskyogcard/src/components/PostEmbed/QuotePost.tsx
new file mode 100644
index 0000000000..a96af2cd30
--- /dev/null
+++ b/bskyogcard/src/components/PostEmbed/QuotePost.tsx
@@ -0,0 +1,113 @@
+import React from 'react'
+import {
+ AppBskyEmbedRecord,
+ AppBskyFeedPost,
+ RichText as RichTextApi,
+} from '@atproto/api'
+
+import {ModeratorData} from '../../data/getModeratorData.js'
+import {PostData} from '../../data/getPostData.js'
+import {atoms as a, theme as t} from '../../theme/index.js'
+import {getModerationCauseInfo} from '../../util/getModerationCauseInfo.js'
+import {moderatePost} from '../../util/moderatePost.js'
+import {viewRecordToPostView} from '../../util/viewRecordToPostView.js'
+import {Avatar} from '../Avatar.js'
+import {Box} from '../Box.js'
+import {CircleInfo} from '../icons/CircleInfo.js'
+import {ModeratedEmbed} from '../ModeratedEmbed.js'
+import {PostEmbed} from '../PostEmbed.js'
+import {RichText} from '../RichText.js'
+import {Text} from '../Text.js'
+
+export function QuotePost({
+ embed,
+ data,
+ moderatorData,
+}: {
+ embed: AppBskyEmbedRecord.ViewRecord
+ data: PostData
+ moderatorData: ModeratorData
+}) {
+ const {author, value: post, embeds} = embed
+ const avatar = data.images.get(author.avatar || '')
+ const rt =
+ AppBskyFeedPost.isValidRecord(post) && post.text
+ ? new RichTextApi({
+ text: post.text,
+ facets: post.facets,
+ })
+ : undefined
+ const postView = viewRecordToPostView(embed)
+ const moderation = moderatePost(postView, moderatorData.moderationOptions)
+
+ const mod = moderation.ui('contentView')
+ const info = getModerationCauseInfo({
+ cause: mod.blurs.at(0),
+ moderatorData,
+ })
+
+ if (info) {
+ return
+ }
+
+ return (
+
+
+
+
+
+ {author.displayName || author.handle}
+
+
+ @{author.handle}
+
+
+
+
+ {rt && }
+
+ {embeds && embeds.length && (
+
+
+
+ )}
+
+ )
+}
+
+export function NotQuotePost({children}: {children: React.ReactNode}) {
+ return (
+
+
+
+ {children}
+
+
+ )
+}
diff --git a/bskyogcard/src/data/getPostData.ts b/bskyogcard/src/data/getPostData.ts
index 44323b0c5e..e2b07ba522 100644
--- a/bskyogcard/src/data/getPostData.ts
+++ b/bskyogcard/src/data/getPostData.ts
@@ -2,7 +2,7 @@ import {AppBskyFeedDefs} from '@atproto/api'
import {httpLogger} from '../logger.js'
import {getStarterPackImageUri} from '../util/getStarterPackImageUri.js'
-import {Embed,parseEmbed} from '../util/parseEmbed.js'
+import {Embed, parseEmbed} from '../util/parseEmbed.js'
import {getImage} from './getImage.js'
export type Metadata = {
@@ -103,8 +103,10 @@ export function getEmbedData(embed: Embed, images: Map) {
},
})
}
- for (const _e of embed.view.embeds) {
- getEmbedData(parseEmbed(_e), images)
+ if (embed.view.embeds) {
+ for (const _e of embed.view.embeds) {
+ getEmbedData(parseEmbed(_e), images)
+ }
}
break
}
@@ -125,6 +127,7 @@ export async function getPostData(
post: AppBskyFeedDefs.PostView,
): Promise {
const images: Map = new Map()
+ console.log(JSON.stringify(post, null, 2))
if (post.author.avatar) {
images.set(post.author.avatar, {
diff --git a/bskyogcard/src/util/getModerationCauseInfo.ts b/bskyogcard/src/util/getModerationCauseInfo.ts
index e281c155d7..8b84f980d9 100644
--- a/bskyogcard/src/util/getModerationCauseInfo.ts
+++ b/bskyogcard/src/util/getModerationCauseInfo.ts
@@ -50,7 +50,7 @@ export function getModerationCauseInfo({
cause,
moderatorData,
}: {
- cause: ModerationCause
+ cause?: ModerationCause
moderatorData: ModeratorData
}): ModerationCauseInfo | undefined {
if (!cause) return undefined