forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
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}