From be0e78b45af64235e2de4b47bfaa1243b88f35d0 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 14 Jan 2026 11:27:59 -0600 Subject: [PATCH] Handle live event in feed card --- src/components/FeedCard.tsx | 38 +++++++++++++++++++++++-- src/components/FeedInterstitials.tsx | 1 + src/components/Post/Embed/FeedEmbed.tsx | 6 ++-- src/features/liveEvents/context.tsx | 21 ++++++++++++++ 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/components/FeedCard.tsx b/src/components/FeedCard.tsx index c5e6200527..1fcedc6916 100644 --- a/src/components/FeedCard.tsx +++ b/src/components/FeedCard.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, {useMemo} from 'react' import {type GestureResponderEvent, View} from 'react-native' import { type AppBskyFeedDefs, @@ -21,19 +21,21 @@ import { import {useSession} from '#/state/session' import * as Toast from '#/view/com/util/Toast' import {UserAvatar} from '#/view/com/util/UserAvatar' -import {atoms as a, useTheme} from '#/alf' +import {atoms as a, select, useTheme} from '#/alf' import { Button, ButtonIcon, type ButtonProps, ButtonText, } from '#/components/Button' +import {Live_Stroke2_Corner0_Rounded as LiveIcon} from '#/components/icons/Live' import {Pin_Stroke2_Corner0_Rounded as PinIcon} from '#/components/icons/Pin' import {Link as InternalLink, type LinkProps} from '#/components/Link' import {Loader} from '#/components/Loader' import * as Prompt from '#/components/Prompt' import {RichText, type RichTextProps} from '#/components/RichText' import {Text} from '#/components/Typography' +import {useActiveLiveEventFeedUris} from '#/features/liveEvents/context' import type * as bsky from '#/types/bsky' import {Trash_Stroke2_Corner0_Rounded as TrashIcon} from './icons/Trash' @@ -49,7 +51,11 @@ export function Default(props: Props) {
- +
@@ -118,14 +124,40 @@ export function AvatarPlaceholder({size = 40}: Omit) { export function TitleAndByline({ title, creator, + uri, }: { title: string creator?: bsky.profile.AnyProfileView + uri?: string }) { const t = useTheme() + const activeLiveEvents = useActiveLiveEventFeedUris() + const liveColor = useMemo( + () => + select(t.name, { + dark: t.palette.negative_600, + dim: t.palette.negative_600, + light: t.palette.negative_500, + }), + [t], + ) return ( + {uri && activeLiveEvents.has(uri) && ( + + + + Happening now + + + )} + style={[a.border, t.atoms.border_contrast_low, a.p_sm, a.rounded_md]}> - + - ) diff --git a/src/features/liveEvents/context.tsx b/src/features/liveEvents/context.tsx index 05e44620cd..83154d9f17 100644 --- a/src/features/liveEvents/context.tsx +++ b/src/features/liveEvents/context.tsx @@ -2,6 +2,11 @@ import {createContext, useContext} from 'react' import {QueryClient, useQuery} from '@tanstack/react-query' import {useIsBskyTeam} from '#/lib/hooks/useIsBskyTeam' +import { + convertBskyAppUrlIfNeeded, + isBskyCustomFeedUrl, + makeRecordUri, +} from '#/lib/strings/url-helpers' import {IS_DEV, LIVE_EVENTS_URL} from '#/env' import {useLiveEventPreferences} from '#/features/liveEvents/preferences' import {type LiveEventsWorkerResponse} from '#/features/liveEvents/types' @@ -88,3 +93,19 @@ export function useUserPreferencedLiveEvents() { }), } } + +export function useActiveLiveEventFeedUris() { + const {feeds} = useLiveEvents() + + return new Set( + feeds + // insurance + .filter(f => isBskyCustomFeedUrl(f.url)) + .map(f => { + const uri = convertBskyAppUrlIfNeeded(f.url) + const [_0, did, _1, rkey] = uri.split('/').filter(Boolean) + const urip = makeRecordUri(did, 'app.bsky.feed.generator', rkey) + return urip.toString() + }), + ) +}