diff options
author | Hailey <me@haileyok.com> | 2025-01-19 17:17:41 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-19 17:17:41 -0800 |
commit | 34582edf3ea17789684100172d6dd496220482b0 (patch) | |
tree | ca29a927bf015107a60a867d8266274c8a78de49 /src/components/interstitials | |
parent | cb020655504dd0d39f8e91fd517f14dc4a82c307 (diff) | |
download | voidsky-34582edf3ea17789684100172d6dd496220482b0.tar.zst |
yolo (#7499)
* tweaks to constants (#7478) * add did * use correct did * typo * tweak * Prevent Drawer gesture conflicting with Suggestions scroll (#7468) * Extract BlockDrawerGeesture * Block drawer when scrolling interstitials (cherry picked from commit 9e3f2f43745eed9c71cb985e48135b7363d91aa9) * yolo interstitial * yolo mode * right swipe * fix nav gesture * vibe controls * collapsible post text * rm blurview, cover for tall videos * smarter video source handling * use thumbnails, improve perf significantly * better android loading * improve aspect ratio * optimize source changes * rm spinner on ios * whoops, remove debug `false` * FIX WRONG VIDEOS SHOWING UP * don't spring on way down * release video players when leaving screen * remove jank animation * Add grid * improve contract, fix double tap * Filter out posts without videos * Only do grid on native * Pipe through feedSourceUri and link to feed * Handle passed through params * Partial revert, just filter posts to start at index * Clean up cards, remove entry interstitial * Tweak handle * Change constant name * Rename some things * Make types legit * Clean up more naming * Add placeholder for grid view * Handle web, set up new organization * Begin work on Header * Replace types * Squashed commit of the following: commit 3d1be4c0f19789dd3c5a3572ec1acd744a2edb80 Author: Samuel Newman <mozzius@protonmail.com> Date: Fri Jan 17 01:08:05 2025 +0000 extend animation commit c9f199413b018efcbd9d8d2a58dd05eb41e7acb7 Author: Samuel Newman <mozzius@protonmail.com> Date: Fri Jan 17 01:01:24 2025 +0000 fix gap commit 22e520795f50efda176f21a5e967cb27d0cdd907 Author: Samuel Newman <mozzius@protonmail.com> Date: Fri Jan 17 00:50:16 2025 +0000 thinner bar, format time commit c32427f21405294ed3567545629a2964c4af59fe Author: Samuel Newman <mozzius@protonmail.com> Date: Fri Jan 17 00:47:57 2025 +0000 fix 2 in 3 screens commit cbf84c08d64ca0a08ba9070ef5db918f89aa4296 Author: Samuel Newman <mozzius@protonmail.com> Date: Fri Jan 17 00:45:46 2025 +0000 rm unneeded var commit 7e0e100177bb1cd0e64c0841bb7685c7f1eb857f Author: Samuel Newman <mozzius@protonmail.com> Date: Fri Jan 17 00:41:18 2025 +0000 scrubberrrrr * use white with opacity rather than gray * Simultaneous gesture * cleanup attempt * fix jank * link to profile on press * fix jitter fr this time * mostly fix android flicker * Maybe fix row generation * Add content hider to video card * emoji in post text * reduce update rate * fix type error * Fix grid layout trailing single item * Add Discover interstitial, settings, includes pin for now * Explore interstitial, handle dimissal, pinning, compact card * Only use grid placeholder on native * Update events * Add feature gate * android nav bar fixes + lower update speed * fix interval + decel rate on interstitials * attempt to fix broken scrub on android (not working) * follow button * Part out the interstitials for perf, add view more * Remove prod web route * Wrap interstitials with BlockDrawerGesture * Bring video cropping in line with images (#7462) * Mimic image cropping for videos on web * Same on native * Rename variables for clarity * Fix Android scrubbing * Add FeedFeedbackProvider * Remove swipe gesture * fix light status bar behaviour * bump * feedback * Copy pasta to new location * Copy pasta part deux * Filter only videos * Make whole text clickable to expand (cherry picked from commit 4cf31120779f4e06eb4c296b3d4b53814d432b07) * move scrubber to own file * end card * add icon to end card * add min view time to viewability config * play haptic on like * tweak feedback * tweak feedback again * Moderation (cherry picked from commit 6b6b471cfb363031284b3e7a1f6e0ade3ac4ae47) * remove bad check * fix feedback for new video grid * change prop name to items as well * Simplify logic * Fix mod footer * Give scrubber more space on android * Add subtle track behind scrubber, adjust opacity * wire in feed context again... * Add better a11y desc to card * Fix key issue * Update a11y copy * Fix scrubber height * improve scrubber animation * Make follow button more obvious * Make header back button more clear * Disable interactions with actual video el * keep content away from the bottom safe area * fix blur * fix moderation issue * improve contrast on mod screen * Make moderation static per item * Memoize rows * Optimizations * Take video moderation into account * Only blur titles for list blur * Change copy * Bump blur radius * animate text in both directions * Rm unused field * Filter by root early * Refactor for clarity * add compose prompt to scrubber * rm log * tweak gradient * Bump SDK, use contentMode to power video feed * Ensure ProfileFeed view also supports video feed * improve scrubber on android * rm border from footer * Update prod video feed did * Separate caches * Add lil hover to View More * Fix undefined logic, remove header for interstitial * Ungate * Fix stuckness * remove extra useless map * Fix effect cleanup * Send seen without cleanup * Simplify react stuff * Earlier early return to avoid loading flash * remove scrubber placeholder * Remove opacity hack * Render useEvent conditionally * Fix Android flash --------- Co-authored-by: dan <dan.abramov@gmail.com> Co-authored-by: Samuel Newman <mozzius@protonmail.com> Co-authored-by: Eric Bailey <git@esb.lol>
Diffstat (limited to 'src/components/interstitials')
-rw-r--r-- | src/components/interstitials/TrendingVideos.tsx | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/src/components/interstitials/TrendingVideos.tsx b/src/components/interstitials/TrendingVideos.tsx new file mode 100644 index 000000000..126d6f417 --- /dev/null +++ b/src/components/interstitials/TrendingVideos.tsx @@ -0,0 +1,231 @@ +import React, {useEffect} from 'react' +import {ScrollView, View} from 'react-native' +import {AppBskyEmbedVideo, AtUri} from '@atproto/api' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useQueryClient} from '@tanstack/react-query' + +import {VIDEO_FEED_URI} from '#/lib/constants' +import {makeCustomFeedLink} from '#/lib/routes/links' +import {logEvent} from '#/lib/statsig/statsig' +import {useTrendingSettingsApi} from '#/state/preferences/trending' +import {usePostFeedQuery} from '#/state/queries/post-feed' +import {RQKEY} from '#/state/queries/post-feed' +import {BlockDrawerGesture} from '#/view/shell/BlockDrawerGesture' +import {atoms as a, useGutters, useTheme} from '#/alf' +import {Button, ButtonIcon} from '#/components/Button' +import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' +import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' +import {Trending2_Stroke2_Corner2_Rounded as Graph} from '#/components/icons/Trending2' +import {Link} from '#/components/Link' +import * as Prompt from '#/components/Prompt' +import {Text} from '#/components/Typography' +import { + CompactVideoPostCard, + CompactVideoPostCardPlaceholder, +} from '#/components/VideoPostCard' + +const CARD_WIDTH = 100 + +const FEED_DESC = `feedgen|${VIDEO_FEED_URI}` +const FEED_PARAMS: { + feedCacheKey: 'discover' +} = { + feedCacheKey: 'discover', +} + +export function TrendingVideos() { + const t = useTheme() + const {_} = useLingui() + const gutters = useGutters([0, 'base']) + const {data, isLoading, error} = usePostFeedQuery(FEED_DESC, FEED_PARAMS) + + // Refetch on unmount if nothing else is using this query. + const queryClient = useQueryClient() + useEffect(() => { + return () => { + const query = queryClient + .getQueryCache() + .find({queryKey: RQKEY(FEED_DESC, FEED_PARAMS)}) + if (query && query.getObserversCount() <= 1) { + query.fetch() + } + } + }, [queryClient]) + + const {setTrendingVideoDisabled} = useTrendingSettingsApi() + const trendingPrompt = Prompt.usePromptControl() + + const onConfirmHide = React.useCallback(() => { + setTrendingVideoDisabled(true) + logEvent('trendingVideos:hide', {context: 'interstitial:discover'}) + }, [setTrendingVideoDisabled]) + + if (error) { + return null + } + + return ( + <View + style={[ + a.pt_lg, + a.pb_lg, + a.border_t, + t.atoms.border_contrast_low, + t.atoms.bg_contrast_25, + ]}> + <View + style={[ + gutters, + a.pb_sm, + a.flex_row, + a.align_center, + a.justify_between, + ]}> + <View style={[a.flex_1, a.flex_row, a.align_center, a.gap_xs]}> + <Graph /> + <Text style={[a.text_md, a.font_bold, a.leading_snug]}> + <Trans>Trending Videos</Trans> + </Text> + </View> + <Button + label={_(msg`Dismiss this section`)} + size="tiny" + variant="ghost" + color="secondary" + shape="round" + onPress={() => trendingPrompt.open()}> + <ButtonIcon icon={X} /> + </Button> + </View> + + <BlockDrawerGesture> + <ScrollView + horizontal + showsHorizontalScrollIndicator={false} + decelerationRate="fast" + snapToInterval={CARD_WIDTH + a.gap_sm.gap}> + <View + style={[ + a.flex_row, + a.gap_sm, + { + paddingLeft: gutters.paddingLeft, + paddingRight: gutters.paddingRight, + }, + ]}> + {isLoading ? ( + Array(10) + .fill(0) + .map((_, i) => ( + <View key={i} style={[{width: CARD_WIDTH}]}> + <CompactVideoPostCardPlaceholder /> + </View> + )) + ) : error || !data ? ( + <Text> + <Trans>Whoops! Trending videos failed to load.</Trans> + </Text> + ) : ( + <VideoCards data={data} /> + )} + </View> + </ScrollView> + </BlockDrawerGesture> + + <Prompt.Basic + control={trendingPrompt} + title={_(msg`Hide trending videos?`)} + description={_(msg`You can update this later from your settings.`)} + confirmButtonCta={_(msg`Hide`)} + onConfirm={onConfirmHide} + /> + </View> + ) +} + +function VideoCards({ + data, +}: { + data: Exclude<ReturnType<typeof usePostFeedQuery>['data'], undefined> +}) { + const t = useTheme() + const {_} = useLingui() + const items = React.useMemo(() => { + return data.pages + .flatMap(page => page.slices) + .map(slice => slice.items[0]) + .filter(Boolean) + .filter(item => AppBskyEmbedVideo.isView(item.post.embed)) + .slice(0, 8) + }, [data]) + const href = React.useMemo(() => { + const urip = new AtUri(VIDEO_FEED_URI) + return makeCustomFeedLink(urip.host, urip.rkey, undefined, 'discover') + }, []) + + return ( + <> + {items.map(item => ( + <View key={item.post.uri} style={[{width: CARD_WIDTH}]}> + <CompactVideoPostCard + post={item.post} + moderation={item.moderation} + sourceContext={{ + type: 'feedgen', + uri: VIDEO_FEED_URI, + sourceInterstitial: 'discover', + }} + onInteract={() => { + logEvent('videoCard:click', { + context: 'interstitial:discover', + }) + }} + /> + </View> + ))} + + <View style={[{width: CARD_WIDTH * 2}]}> + <Link + to={href} + label={_(msg`View more`)} + style={[ + a.justify_center, + a.align_center, + a.flex_1, + a.rounded_md, + t.atoms.bg, + ]}> + {({pressed}) => ( + <View + style={[ + a.flex_row, + a.align_center, + a.gap_md, + { + opacity: pressed ? 0.6 : 1, + }, + ]}> + <Text style={[a.text_md]}> + <Trans>View more</Trans> + </Text> + <View + style={[ + a.align_center, + a.justify_center, + a.rounded_full, + { + width: 34, + height: 34, + backgroundColor: t.palette.primary_500, + }, + ]}> + <ButtonIcon icon={ChevronRight} /> + </View> + </View> + )} + </Link> + </View> + </> + ) +} |