Bluesky app fork with some witchin' additions 馃挮
at feat/tealfm 68 lines 1.9 kB view raw
1import {View} from 'react-native' 2import {AppBskyEmbedVideo} from '@atproto/api' 3 4import {type FeedPostSliceItem} from '#/state/queries/post-feed' 5import {type VideoFeedSourceContext} from '#/screens/VideoFeed/types' 6import {atoms as a, useGutters} from '#/alf' 7import * as Grid from '#/components/Grid' 8import { 9 VideoPostCard, 10 VideoPostCardPlaceholder, 11} from '#/components/VideoPostCard' 12import {useAnalytics} from '#/analytics' 13 14export function PostFeedVideoGridRow({ 15 items: slices, 16 sourceContext, 17}: { 18 items: FeedPostSliceItem[] 19 sourceContext: VideoFeedSourceContext 20}) { 21 const ax = useAnalytics() 22 const gutters = useGutters(['base', 'base', 0, 'base']) 23 const posts = slices 24 .filter(slice => AppBskyEmbedVideo.isView(slice.post.embed)) 25 .map(slice => ({ 26 post: slice.post, 27 moderation: slice.moderation, 28 })) 29 30 /** 31 * This should not happen because we should be filtering out posts without 32 * videos within the `PostFeed` component. 33 */ 34 if (posts.length !== slices.length) return null 35 36 return ( 37 <View style={[gutters]}> 38 <View style={[a.flex_row, a.gap_sm]}> 39 <Grid.Row gap={a.gap_sm.gap}> 40 {posts.map(post => ( 41 <Grid.Col key={post.post.uri} width={1 / 2}> 42 <VideoPostCard 43 post={post.post} 44 sourceContext={sourceContext} 45 moderation={post.moderation} 46 onInteract={() => { 47 ax.metric('videoCard:click', {context: 'feed'}) 48 }} 49 /> 50 </Grid.Col> 51 ))} 52 </Grid.Row> 53 </View> 54 </View> 55 ) 56} 57 58export function PostFeedVideoGridRowPlaceholder() { 59 const gutters = useGutters(['base', 'base', 0, 'base']) 60 return ( 61 <View style={[gutters]}> 62 <View style={[a.flex_row, a.gap_sm]}> 63 <VideoPostCardPlaceholder /> 64 <VideoPostCardPlaceholder /> 65 </View> 66 </View> 67 ) 68}