From a063966fb0e2c121e92f16ad7ab0a02748a1223e Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 16 Jan 2025 13:44:43 -0600 Subject: [PATCH] Filter out posts without videos --- src/components/VideoPostCard.tsx | 30 ++++++++----------- src/components/feeds/PostFeedVideoGridRow.tsx | 15 ++++++++-- src/view/com/posts/PostFeed.tsx | 13 +++++--- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/components/VideoPostCard.tsx b/src/components/VideoPostCard.tsx index 70a2a0d608..ea1092f760 100644 --- a/src/components/VideoPostCard.tsx +++ b/src/components/VideoPostCard.tsx @@ -1,12 +1,11 @@ -import {Pressable,View} from 'react-native' +import {Pressable, View} from 'react-native' import {Image} from 'expo-image' import {LinearGradient} from 'expo-linear-gradient' -import {AppBskyEmbedVideo} from '@atproto/api' +import {AppBskyEmbedVideo,AppBskyFeedDefs} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {sanitizeHandle} from '#/lib/strings/handles' -import {FeedPostSliceItem} from '#/state/queries/post-feed' import {formatCount} from '#/view/com/util/numeric/format' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useTheme} from '#/alf' @@ -17,20 +16,21 @@ import {Heart2_Stroke2_Corner0_Rounded as Heart} from '#/components/icons/Heart2 import {Repost_Stroke2_Corner2_Rounded as Repost} from '#/components/icons/Repost' import {Text} from '#/components/Typography' -export function VideoPostCard({post}: {post: FeedPostSliceItem}) { +export function VideoPostCard({post}: {post: AppBskyFeedDefs.PostView}) { const t = useTheme() const {_, i18n} = useLingui() - const embed = post.post.embed + const embed = post.embed const { state: hovered, onIn: onHoverIn, onOut: onHoverOut, } = useInteractionState() - if (!AppBskyEmbedVideo.isView(embed)) { - // TODO unavailable? - return null - } + /** + * Filtering should be done at a higher level, such as `PostFeed` or + * `PostFeedVideoGridRow`, but we need to protect here as well. + */ + if (!AppBskyEmbedVideo.isView(embed)) return null const {thumbnail} = embed const black = select(t.name, { @@ -95,13 +95,13 @@ export function VideoPostCard({post}: {post: FeedPostSliceItem}) { - {formatCount(i18n, post.post.likeCount || 0)} + {formatCount(i18n, post.likeCount || 0)} - {formatCount(i18n, post.post.repostCount || 0)} + {formatCount(i18n, post.repostCount || 0)} @@ -109,11 +109,7 @@ export function VideoPostCard({post}: {post: FeedPostSliceItem}) { - + - {sanitizeHandle(post.post.author.handle, '@')} + {sanitizeHandle(post.author.handle, '@')} diff --git a/src/components/feeds/PostFeedVideoGridRow.tsx b/src/components/feeds/PostFeedVideoGridRow.tsx index c82ee9f7c3..2d1a035632 100644 --- a/src/components/feeds/PostFeedVideoGridRow.tsx +++ b/src/components/feeds/PostFeedVideoGridRow.tsx @@ -1,16 +1,27 @@ import {View} from 'react-native' +import {AppBskyEmbedVideo} from '@atproto/api' import {FeedPostSliceItem} from '#/state/queries/post-feed' import {atoms as a, useGutters} from '#/alf' import {VideoPostCard} from '#/components/VideoPostCard' -export function PostFeedVideoGridRow({posts}: {posts: FeedPostSliceItem[]}) { +export function PostFeedVideoGridRow({slices}: {slices: FeedPostSliceItem[]}) { const gutters = useGutters(['base', 'base', 0, 'base']) + const posts = slices + .filter(slice => AppBskyEmbedVideo.isView(slice.post.embed)) + .map(slice => slice.post) + + /** + * This should not happen because we should be filtering out posts without + * videos within the `PostFeed` component. + */ + if (posts.length !== slices.length) return null + return ( {posts.map(post => ( - + ))} diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx index 3bc7a669c0..812e7d56a3 100644 --- a/src/view/com/posts/PostFeed.tsx +++ b/src/view/com/posts/PostFeed.tsx @@ -9,7 +9,7 @@ import { View, ViewStyle, } from 'react-native' -import {AppBskyActorDefs} from '@atproto/api' +import {AppBskyActorDefs, AppBskyEmbedVideo} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useQueryClient} from '@tanstack/react-query' @@ -93,7 +93,7 @@ type FeedRow = | { type: 'videoGridRow' key: string - posts: FeedPostSliceItem[] + slices: FeedPostSliceItem[] } | { type: 'sliceViewFullThread' @@ -338,6 +338,11 @@ let PostFeed = ({ const slice = page.slices[i] const root = slice.items.at(0) if (!root) continue + // TODO test this + if (!AppBskyEmbedVideo.isView(root.post.embed)) { + i-- + continue + } const cols = gtMobile ? 3 : 2 if (i % cols === 0) { rows.push([root]) @@ -352,7 +357,7 @@ let PostFeed = ({ arr.push({ type: 'videoGridRow', key: row.map(r => r._reactKey).join('-'), - posts: row, + slices: row, }) } } else { @@ -590,7 +595,7 @@ let PostFeed = ({ } else if (row.type === 'sliceViewFullThread') { return } else if (row.type === 'videoGridRow') { - return + return } else { return null }