Handle previews
This commit is contained in:
+46
-46
@@ -146,49 +146,51 @@ function InnerApp() {
|
|||||||
<QueryProvider currentDid={currentAccount?.did}>
|
<QueryProvider currentDid={currentAccount?.did}>
|
||||||
<PolicyUpdateOverlayProvider>
|
<PolicyUpdateOverlayProvider>
|
||||||
<StatsigProvider>
|
<StatsigProvider>
|
||||||
<AgeAssuranceV2Provider>
|
<LiveEventsProvider>
|
||||||
<ComposerProvider>
|
<AgeAssuranceV2Provider>
|
||||||
<MessagesProvider>
|
<ComposerProvider>
|
||||||
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
|
<MessagesProvider>
|
||||||
<LabelDefsProvider>
|
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
|
||||||
<ModerationOptsProvider>
|
<LabelDefsProvider>
|
||||||
<LoggedOutViewProvider>
|
<ModerationOptsProvider>
|
||||||
<SelectedFeedProvider>
|
<LoggedOutViewProvider>
|
||||||
<HiddenRepliesProvider>
|
<SelectedFeedProvider>
|
||||||
<HomeBadgeProvider>
|
<HiddenRepliesProvider>
|
||||||
<UnreadNotifsProvider>
|
<HomeBadgeProvider>
|
||||||
<BackgroundNotificationPreferencesProvider>
|
<UnreadNotifsProvider>
|
||||||
<MutedThreadsProvider>
|
<BackgroundNotificationPreferencesProvider>
|
||||||
<ProgressGuideProvider>
|
<MutedThreadsProvider>
|
||||||
<ServiceAccountManager>
|
<ProgressGuideProvider>
|
||||||
<EmailVerificationProvider>
|
<ServiceAccountManager>
|
||||||
<HideBottomBarBorderProvider>
|
<EmailVerificationProvider>
|
||||||
<GestureHandlerRootView
|
<HideBottomBarBorderProvider>
|
||||||
style={s.h100pct}>
|
<GestureHandlerRootView
|
||||||
<GlobalGestureEventsProvider>
|
style={s.h100pct}>
|
||||||
<IntentDialogProvider>
|
<GlobalGestureEventsProvider>
|
||||||
<TestCtrls />
|
<IntentDialogProvider>
|
||||||
<Shell />
|
<TestCtrls />
|
||||||
<ToastOutlet />
|
<Shell />
|
||||||
</IntentDialogProvider>
|
<ToastOutlet />
|
||||||
</GlobalGestureEventsProvider>
|
</IntentDialogProvider>
|
||||||
</GestureHandlerRootView>
|
</GlobalGestureEventsProvider>
|
||||||
</HideBottomBarBorderProvider>
|
</GestureHandlerRootView>
|
||||||
</EmailVerificationProvider>
|
</HideBottomBarBorderProvider>
|
||||||
</ServiceAccountManager>
|
</EmailVerificationProvider>
|
||||||
</ProgressGuideProvider>
|
</ServiceAccountManager>
|
||||||
</MutedThreadsProvider>
|
</ProgressGuideProvider>
|
||||||
</BackgroundNotificationPreferencesProvider>
|
</MutedThreadsProvider>
|
||||||
</UnreadNotifsProvider>
|
</BackgroundNotificationPreferencesProvider>
|
||||||
</HomeBadgeProvider>
|
</UnreadNotifsProvider>
|
||||||
</HiddenRepliesProvider>
|
</HomeBadgeProvider>
|
||||||
</SelectedFeedProvider>
|
</HiddenRepliesProvider>
|
||||||
</LoggedOutViewProvider>
|
</SelectedFeedProvider>
|
||||||
</ModerationOptsProvider>
|
</LoggedOutViewProvider>
|
||||||
</LabelDefsProvider>
|
</ModerationOptsProvider>
|
||||||
</MessagesProvider>
|
</LabelDefsProvider>
|
||||||
</ComposerProvider>
|
</MessagesProvider>
|
||||||
</AgeAssuranceV2Provider>
|
</ComposerProvider>
|
||||||
|
</AgeAssuranceV2Provider>
|
||||||
|
</LiveEventsProvider>
|
||||||
</StatsigProvider>
|
</StatsigProvider>
|
||||||
</PolicyUpdateOverlayProvider>
|
</PolicyUpdateOverlayProvider>
|
||||||
</QueryProvider>
|
</QueryProvider>
|
||||||
@@ -235,9 +237,7 @@ function App() {
|
|||||||
<StarterPackProvider>
|
<StarterPackProvider>
|
||||||
<SafeAreaProvider
|
<SafeAreaProvider
|
||||||
initialMetrics={initialWindowMetrics}>
|
initialMetrics={initialWindowMetrics}>
|
||||||
<LiveEventsProvider>
|
<InnerApp />
|
||||||
<InnerApp />
|
|
||||||
</LiveEventsProvider>
|
|
||||||
</SafeAreaProvider>
|
</SafeAreaProvider>
|
||||||
</StarterPackProvider>
|
</StarterPackProvider>
|
||||||
</BottomSheetProvider>
|
</BottomSheetProvider>
|
||||||
|
|||||||
+42
-42
@@ -122,45 +122,47 @@ function InnerApp() {
|
|||||||
<QueryProvider currentDid={currentAccount?.did}>
|
<QueryProvider currentDid={currentAccount?.did}>
|
||||||
<PolicyUpdateOverlayProvider>
|
<PolicyUpdateOverlayProvider>
|
||||||
<StatsigProvider>
|
<StatsigProvider>
|
||||||
<AgeAssuranceV2Provider>
|
<LiveEventsProvider>
|
||||||
<ComposerProvider>
|
<AgeAssuranceV2Provider>
|
||||||
<MessagesProvider>
|
<ComposerProvider>
|
||||||
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
|
<MessagesProvider>
|
||||||
<LabelDefsProvider>
|
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
|
||||||
<ModerationOptsProvider>
|
<LabelDefsProvider>
|
||||||
<LoggedOutViewProvider>
|
<ModerationOptsProvider>
|
||||||
<SelectedFeedProvider>
|
<LoggedOutViewProvider>
|
||||||
<HiddenRepliesProvider>
|
<SelectedFeedProvider>
|
||||||
<HomeBadgeProvider>
|
<HiddenRepliesProvider>
|
||||||
<UnreadNotifsProvider>
|
<HomeBadgeProvider>
|
||||||
<BackgroundNotificationPreferencesProvider>
|
<UnreadNotifsProvider>
|
||||||
<MutedThreadsProvider>
|
<BackgroundNotificationPreferencesProvider>
|
||||||
<SafeAreaProvider>
|
<MutedThreadsProvider>
|
||||||
<ProgressGuideProvider>
|
<SafeAreaProvider>
|
||||||
<ServiceConfigProvider>
|
<ProgressGuideProvider>
|
||||||
<EmailVerificationProvider>
|
<ServiceConfigProvider>
|
||||||
<HideBottomBarBorderProvider>
|
<EmailVerificationProvider>
|
||||||
<IntentDialogProvider>
|
<HideBottomBarBorderProvider>
|
||||||
<Shell />
|
<IntentDialogProvider>
|
||||||
<ToastOutlet />
|
<Shell />
|
||||||
</IntentDialogProvider>
|
<ToastOutlet />
|
||||||
</HideBottomBarBorderProvider>
|
</IntentDialogProvider>
|
||||||
</EmailVerificationProvider>
|
</HideBottomBarBorderProvider>
|
||||||
</ServiceConfigProvider>
|
</EmailVerificationProvider>
|
||||||
</ProgressGuideProvider>
|
</ServiceConfigProvider>
|
||||||
</SafeAreaProvider>
|
</ProgressGuideProvider>
|
||||||
</MutedThreadsProvider>
|
</SafeAreaProvider>
|
||||||
</BackgroundNotificationPreferencesProvider>
|
</MutedThreadsProvider>
|
||||||
</UnreadNotifsProvider>
|
</BackgroundNotificationPreferencesProvider>
|
||||||
</HomeBadgeProvider>
|
</UnreadNotifsProvider>
|
||||||
</HiddenRepliesProvider>
|
</HomeBadgeProvider>
|
||||||
</SelectedFeedProvider>
|
</HiddenRepliesProvider>
|
||||||
</LoggedOutViewProvider>
|
</SelectedFeedProvider>
|
||||||
</ModerationOptsProvider>
|
</LoggedOutViewProvider>
|
||||||
</LabelDefsProvider>
|
</ModerationOptsProvider>
|
||||||
</MessagesProvider>
|
</LabelDefsProvider>
|
||||||
</ComposerProvider>
|
</MessagesProvider>
|
||||||
</AgeAssuranceV2Provider>
|
</ComposerProvider>
|
||||||
|
</AgeAssuranceV2Provider>
|
||||||
|
</LiveEventsProvider>
|
||||||
</StatsigProvider>
|
</StatsigProvider>
|
||||||
</PolicyUpdateOverlayProvider>
|
</PolicyUpdateOverlayProvider>
|
||||||
</QueryProvider>
|
</QueryProvider>
|
||||||
@@ -203,9 +205,7 @@ function App() {
|
|||||||
<LightboxStateProvider>
|
<LightboxStateProvider>
|
||||||
<PortalProvider>
|
<PortalProvider>
|
||||||
<StarterPackProvider>
|
<StarterPackProvider>
|
||||||
<LiveEventsProvider>
|
<InnerApp />
|
||||||
<InnerApp />
|
|
||||||
</LiveEventsProvider>
|
|
||||||
</StarterPackProvider>
|
</StarterPackProvider>
|
||||||
</PortalProvider>
|
</PortalProvider>
|
||||||
</LightboxStateProvider>
|
</LightboxStateProvider>
|
||||||
|
|||||||
+12
-17
@@ -12,26 +12,15 @@ import {
|
|||||||
LiveEventFeedOptionsMenu,
|
LiveEventFeedOptionsMenu,
|
||||||
useDialogControl,
|
useDialogControl,
|
||||||
} from '#/features/liveEvents/components/LiveEventFeedOptionsMenu'
|
} from '#/features/liveEvents/components/LiveEventFeedOptionsMenu'
|
||||||
import {useLiveEvents} from '#/features/liveEvents/context'
|
import {useUserPreferencedLiveEvents} from '#/features/liveEvents/context'
|
||||||
import {useLiveEventPreferences} from '#/features/liveEvents/preferences'
|
import {type LiveEventFeed} from '#/features/liveEvents/types'
|
||||||
|
|
||||||
export function DiscoverFeedLiveEventFeedsAndTrendingBanner() {
|
export function DiscoverFeedLiveEventFeedsAndTrendingBanner() {
|
||||||
const t = useTheme()
|
const events = useUserPreferencedLiveEvents()
|
||||||
const {_} = useLingui()
|
|
||||||
const events = useLiveEvents()
|
|
||||||
const {rightNavVisible} = useLayoutBreakpoints()
|
const {rightNavVisible} = useLayoutBreakpoints()
|
||||||
const {trendingDisabled} = useTrendingSettings()
|
const {trendingDisabled} = useTrendingSettings()
|
||||||
const optionsMenuControl = useDialogControl()
|
|
||||||
const {data, isLoading} = useLiveEventPreferences()
|
|
||||||
|
|
||||||
// user prefs should be loaded by now, but for TS-sake
|
if (!events.feeds.length) {
|
||||||
if (isLoading) return null
|
|
||||||
|
|
||||||
const {hideAllFeeds, hiddenFeedIds} = data
|
|
||||||
const feed = events.feeds.at(0)
|
|
||||||
const feedHidden = feed?.id ? hiddenFeedIds.includes(feed?.id || '') : false
|
|
||||||
|
|
||||||
if (!feed || hideAllFeeds || feedHidden) {
|
|
||||||
if (!rightNavVisible && !trendingDisabled) {
|
if (!rightNavVisible && !trendingDisabled) {
|
||||||
// only show trending on mobile when live event banner is not shown
|
// only show trending on mobile when live event banner is not shown
|
||||||
return <TrendingInterstitial />
|
return <TrendingInterstitial />
|
||||||
@@ -44,7 +33,13 @@ export function DiscoverFeedLiveEventFeedsAndTrendingBanner() {
|
|||||||
// On desktop, we show in the sidebar
|
// On desktop, we show in the sidebar
|
||||||
if (rightNavVisible) return null
|
if (rightNavVisible) return null
|
||||||
|
|
||||||
const image = feed.images.wide
|
return events.feeds.map(feed => <Inner feed={feed} key={feed.id} />)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Inner({feed}: {feed: LiveEventFeed}) {
|
||||||
|
const t = useTheme()
|
||||||
|
const {_} = useLingui()
|
||||||
|
const optionsMenuControl = useDialogControl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -76,7 +71,7 @@ export function DiscoverFeedLiveEventFeedsAndTrendingBanner() {
|
|||||||
<EllipsisIcon
|
<EllipsisIcon
|
||||||
size="sm"
|
size="sm"
|
||||||
fill={
|
fill={
|
||||||
image.textColor === 'light'
|
feed.images.wide.textColor === 'light'
|
||||||
? t.palette.white
|
? t.palette.white
|
||||||
: t.palette.black
|
: t.palette.black
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export function LiveEventFeedCardWide({
|
|||||||
const {gtPhone} = useBreakpoints()
|
const {gtPhone} = useBreakpoints()
|
||||||
|
|
||||||
const image = feed.images.wide
|
const image = feed.images.wide
|
||||||
|
const textColor = feed.images.wide.textColor === 'light' ? 'white' : 'black'
|
||||||
const url = useMemo(() => {
|
const url = useMemo(() => {
|
||||||
// Validated in multiple places on the backend
|
// Validated in multiple places on the backend
|
||||||
if (isBskyCustomFeedUrl(feed.url)) {
|
if (isBskyCustomFeedUrl(feed.url)) {
|
||||||
@@ -106,16 +107,20 @@ export function LiveEventFeedCardWide({
|
|||||||
style={[
|
style={[
|
||||||
a.leading_snug,
|
a.leading_snug,
|
||||||
gtPhone ? a.text_xs : a.text_2xs,
|
gtPhone ? a.text_xs : a.text_2xs,
|
||||||
{color: 'white', opacity: 0.8},
|
{color: textColor, opacity: 0.8},
|
||||||
]}>
|
]}>
|
||||||
<Trans>Happening now</Trans>
|
{feed.preview ? (
|
||||||
|
<Trans>Preview</Trans>
|
||||||
|
) : (
|
||||||
|
<Trans>Happening now</Trans>
|
||||||
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
<Text
|
||||||
style={[
|
style={[
|
||||||
a.leading_snug,
|
a.leading_snug,
|
||||||
a.font_bold,
|
a.font_bold,
|
||||||
gtPhone ? a.text_3xl : a.text_lg,
|
gtPhone ? a.text_3xl : a.text_lg,
|
||||||
{color: 'white'},
|
{color: textColor},
|
||||||
]}>
|
]}>
|
||||||
{feed.title}
|
{feed.title}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
import {createContext, useContext} from 'react'
|
import {createContext, useContext} from 'react'
|
||||||
import {QueryClient, useQuery} from '@tanstack/react-query'
|
import {QueryClient, useQuery} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {useIsBskyTeam} from '#/lib/hooks/useIsBskyTeam'
|
||||||
import {IS_DEV, LIVE_EVENTS_URL} from '#/env'
|
import {IS_DEV, LIVE_EVENTS_URL} from '#/env'
|
||||||
|
import {useLiveEventPreferences} from '#/features/liveEvents/preferences'
|
||||||
import {type LiveEventsWorkerResponse} from '#/features/liveEvents/types'
|
import {type LiveEventsWorkerResponse} from '#/features/liveEvents/types'
|
||||||
|
import {useDevMode} from '#/storage/hooks/dev-mode'
|
||||||
|
|
||||||
const qc = new QueryClient()
|
const qc = new QueryClient()
|
||||||
const liveEventsQueryKey = ['live-events']
|
const liveEventsQueryKey = ['live-events']
|
||||||
|
|
||||||
|
export const DEFAULT_LIVE_EVENTS = {
|
||||||
|
feeds: [],
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchLiveEvents(): Promise<LiveEventsWorkerResponse | null> {
|
async function fetchLiveEvents(): Promise<LiveEventsWorkerResponse | null> {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${LIVE_EVENTS_URL}/config`)
|
const res = await fetch(`${LIVE_EVENTS_URL}/config`)
|
||||||
@@ -18,17 +25,29 @@ async function fetchLiveEvents(): Promise<LiveEventsWorkerResponse | null> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Context = createContext<LiveEventsWorkerResponse>({
|
const Context = createContext<LiveEventsWorkerResponse>(DEFAULT_LIVE_EVENTS)
|
||||||
feeds: [],
|
|
||||||
})
|
|
||||||
|
|
||||||
export function Provider({children}: React.PropsWithChildren<{}>) {
|
export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||||
|
const [isDevMode] = useDevMode()
|
||||||
|
const isBskyTeam = useIsBskyTeam()
|
||||||
const {data} = useQuery(
|
const {data} = useQuery(
|
||||||
{
|
{
|
||||||
staleTime: IS_DEV ? 5e3 : 1000 * 60,
|
staleTime: IS_DEV ? 5e3 : 1000 * 60,
|
||||||
queryKey: liveEventsQueryKey,
|
queryKey: liveEventsQueryKey,
|
||||||
async queryFn() {
|
async queryFn() {
|
||||||
return fetchLiveEvents()
|
const events = await fetchLiveEvents()
|
||||||
|
if (!events) return null
|
||||||
|
const feeds = events.feeds.filter(f => {
|
||||||
|
if (f.preview && !isBskyTeam) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
...events,
|
||||||
|
// only one at a time for now, unless bsky team and dev mode
|
||||||
|
feeds: isBskyTeam && isDevMode ? feeds : feeds.slice(0, 1),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
qc,
|
qc,
|
||||||
@@ -53,3 +72,19 @@ export function useLiveEvents() {
|
|||||||
}
|
}
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useUserPreferencedLiveEvents() {
|
||||||
|
const events = useLiveEvents()
|
||||||
|
const {data, isLoading} = useLiveEventPreferences()
|
||||||
|
if (isLoading) return DEFAULT_LIVE_EVENTS
|
||||||
|
const {hideAllFeeds, hiddenFeedIds} = data
|
||||||
|
return {
|
||||||
|
...events,
|
||||||
|
feeds: hideAllFeeds
|
||||||
|
? []
|
||||||
|
: events.feeds.filter(f => {
|
||||||
|
const hidden = f?.id ? hiddenFeedIds.includes(f?.id || '') : false
|
||||||
|
return !hidden
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import {useMemo} from 'react'
|
||||||
|
|
||||||
|
import {useGate} from '#/lib/statsig/statsig'
|
||||||
|
|
||||||
|
export function useIsBskyTeam() {
|
||||||
|
const gate = useGate()
|
||||||
|
return useMemo(() => gate('is_bsky_team_member'), [gate])
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ export type Gate =
|
|||||||
| 'disable_settings_find_contacts'
|
| 'disable_settings_find_contacts'
|
||||||
| 'explore_show_suggested_feeds'
|
| 'explore_show_suggested_feeds'
|
||||||
| 'feed_reply_button_open_thread'
|
| 'feed_reply_button_open_thread'
|
||||||
|
| 'is_bsky_team_member' // special, do not remove
|
||||||
| 'old_postonboarding'
|
| 'old_postonboarding'
|
||||||
| 'onboarding_add_video_feed'
|
| 'onboarding_add_video_feed'
|
||||||
| 'onboarding_suggested_starterpacks'
|
| 'onboarding_suggested_starterpacks'
|
||||||
|
|||||||
Reference in New Issue
Block a user