From e23a92126a26f6340affad8d5e4fcc803754f81a Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 13 Jan 2026 15:35:03 -0600 Subject: [PATCH] Add live event feed card to Explore --- .../ExploreScreenLiveEventFeedsBanner.tsx | 17 +++ .../components/LiveEventFeedCardWide.tsx | 113 ++++++++++++++++++ src/screens/Search/Explore.tsx | 10 ++ 3 files changed, 140 insertions(+) create mode 100644 src/features/liveEvents/components/ExploreScreenLiveEventFeedsBanner.tsx create mode 100644 src/features/liveEvents/components/LiveEventFeedCardWide.tsx diff --git a/src/features/liveEvents/components/ExploreScreenLiveEventFeedsBanner.tsx b/src/features/liveEvents/components/ExploreScreenLiveEventFeedsBanner.tsx new file mode 100644 index 0000000000..4133e96972 --- /dev/null +++ b/src/features/liveEvents/components/ExploreScreenLiveEventFeedsBanner.tsx @@ -0,0 +1,17 @@ +import {View} from 'react-native' + +import {atoms as a, useTheme} from '#/alf' +import {LiveEventFeedCardWide} from '#/features/liveEvents/components/LiveEventFeedCardWide' +import {useLiveEvents} from '#/features/liveEvents/context' + +export function ExploreScreenLiveEventFeedsBanner() { + const t = useTheme() + const events = useLiveEvents() + const feed = events.feeds.at(0) + if (!feed) return null + return ( + + + + ) +} diff --git a/src/features/liveEvents/components/LiveEventFeedCardWide.tsx b/src/features/liveEvents/components/LiveEventFeedCardWide.tsx new file mode 100644 index 0000000000..4e7ad78e3a --- /dev/null +++ b/src/features/liveEvents/components/LiveEventFeedCardWide.tsx @@ -0,0 +1,113 @@ +import {useMemo} from 'react' +import {View} from 'react-native' +import {Image} from 'expo-image' +import {LinearGradient} from 'expo-linear-gradient' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {isBskyCustomFeedUrl} from '#/lib/strings/url-helpers' +import {atoms as a, useBreakpoints, utils} from '#/alf' +import {Link} from '#/components/Link' +import {Text} from '#/components/Typography' +import {type LiveEventFeed} from '#/features/liveEvents/types' + +const roundedStyles = [a.rounded_lg, a.curve_continuous] + +export function LiveEventFeedCardWide({feed}: {feed: LiveEventFeed}) { + const {_} = useLingui() + const {gtPhone} = useBreakpoints() + + const image = feed.images.wide + const url = useMemo(() => { + // Validated in multiple places on the backend + if (isBskyCustomFeedUrl(feed.url)) { + return new URL(feed.url).pathname + } + return '/' + }, [feed.url]) + + return ( + + {({hovered, pressed}) => ( + + + + + + + + + + + + Happening now + + + {feed.title} + + + + + + )} + + ) +} diff --git a/src/screens/Search/Explore.tsx b/src/screens/Search/Explore.tsx index b3e26dcfd3..6b49588db9 100644 --- a/src/screens/Search/Explore.tsx +++ b/src/screens/Search/Explore.tsx @@ -68,6 +68,7 @@ import {Loader} from '#/components/Loader' import * as ProfileCard from '#/components/ProfileCard' import {SubtleHover} from '#/components/SubtleHover' import {Text} from '#/components/Typography' +import {ExploreScreenLiveEventFeedsBanner} from '#/features/liveEvents/components/ExploreScreenLiveEventFeedsBanner' import * as ModuleHeader from './components/ModuleHeader' import { SuggestedAccountsTabBar, @@ -201,6 +202,10 @@ type ExploreScreenItems = type: 'interests-card' key: 'interests-card' } + | { + type: 'liveEventFeedsBanner' + key: string + } export function Explore({ focusSearchInput, @@ -684,6 +689,8 @@ export function Explore({ i.push(topBorder) i.push(...interestsNuxModule) + i.push({type: 'liveEventFeedsBanner', key: 'liveEventFeedsBanner'}) + if (useFullExperience) { i.push(trendingTopicsModule) i.push(...suggestedFeedsModule) @@ -998,6 +1005,9 @@ export function Explore({ case 'interests-card': { return } + case 'liveEventFeedsBanner': { + return + } } }, [