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