diff --git a/src/analytics/features/index.ts b/src/analytics/features/index.ts index 81eb9eced0..afd2d2b089 100644 --- a/src/analytics/features/index.ts +++ b/src/analytics/features/index.ts @@ -16,7 +16,7 @@ setPolyfills({ return value != null ? JSON.parse(value) : null }, setItem: async (key, value) => { - CACHE.set(key, JSON.stringify(value)) + CACHE.set(key, value) }, }, }) diff --git a/src/analytics/index.tsx b/src/analytics/index.tsx index 3596464ebd..47e024ae88 100644 --- a/src/analytics/index.tsx +++ b/src/analytics/index.tsx @@ -180,6 +180,13 @@ export function AnalyticsFeaturesContext({ }) { const parentContext = useContext(Context) + /** + * Side-effect: we need to synchronously set this during the + * same render cycle. It does not trigger a re-render, it just + * sets properties on the singleton GrowthBook instance. + */ + setAttributes(parentContext.metadata) + useEffect(() => { feats.setTrackingCallback((experiment, result) => { parentContext.metric('experiment:viewed', { @@ -189,10 +196,6 @@ export function AnalyticsFeaturesContext({ }) }, [parentContext.metric]) - useEffect(() => { - setAttributes(parentContext.metadata) - }, [parentContext.metadata]) - const childContext = useMemo(() => { return { ...parentContext, diff --git a/src/features/liveEvents/components/DiscoverFeedLiveEventFeedsAndTrendingBanner.tsx b/src/features/liveEvents/components/DiscoverFeedLiveEventFeedsAndTrendingBanner.tsx index de8bc81e7a..daf59440f4 100644 --- a/src/features/liveEvents/components/DiscoverFeedLiveEventFeedsAndTrendingBanner.tsx +++ b/src/features/liveEvents/components/DiscoverFeedLiveEventFeedsAndTrendingBanner.tsx @@ -1,18 +1,16 @@ import {View} from 'react-native' -import {msg} from '@lingui/macro' +import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useTrendingSettings} from '#/state/preferences/trending' import {atoms as a, useLayoutBreakpoints} from '#/alf' import {Button} from '#/components/Button' -import {DotGrid_Stroke2_Corner0_Rounded as EllipsisIcon} from '#/components/icons/DotGrid' +import {TimesLarge_Stroke2_Corner0_Rounded as CloseIcon} from '#/components/icons/Times' import {TrendingInterstitial} from '#/components/interstitials/Trending' +import * as Toast from '#/components/Toast' import {LiveEventFeedCardWide} from '#/features/liveEvents/components/LiveEventFeedCardWide' -import { - LiveEventFeedOptionsMenu, - useDialogControl, -} from '#/features/liveEvents/components/LiveEventFeedOptionsMenu' import {useUserPreferencedLiveEvents} from '#/features/liveEvents/context' +import {useUpdateLiveEventPreferences} from '#/features/liveEvents/preferences' import {type LiveEventFeed} from '#/features/liveEvents/types' export function DiscoverFeedLiveEventFeedsAndTrendingBanner() { @@ -38,9 +36,41 @@ export function DiscoverFeedLiveEventFeedsAndTrendingBanner() { function Inner({feed}: {feed: LiveEventFeed}) { const {_} = useLingui() - const optionsMenuControl = useDialogControl() const layout = feed.layouts.wide + const {mutate: update, variables} = useUpdateLiveEventPreferences({ + feed, + metricContext: 'discover', + onUpdateSuccess({undoAction}) { + Toast.show( + + + + {undoAction ? ( + Live event hidden + ) : ( + Live event unhidden + )} + + {undoAction && ( + { + if (undoAction) { + update(undoAction) + } + }}> + Undo + + )} + , + {type: 'success'}, + ) + }, + }) + + if (variables) return null + return ( <> @@ -48,12 +78,12 @@ function Inner({feed}: {feed: LiveEventFeed}) { - - ) } diff --git a/src/features/liveEvents/components/LiveEventFeedCardCompact.tsx b/src/features/liveEvents/components/LiveEventFeedCardCompact.tsx index 562b4eb205..a4090b8570 100644 --- a/src/features/liveEvents/components/LiveEventFeedCardCompact.tsx +++ b/src/features/liveEvents/components/LiveEventFeedCardCompact.tsx @@ -1,10 +1,11 @@ -import {useEffect, useMemo} from 'react' +import {useMemo} from 'react' import {View} from 'react-native' import {Image} from 'expo-image' import {LinearGradient} from 'expo-linear-gradient' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {useCallOnce} from '#/lib/once' import {isBskyCustomFeedUrl} from '#/lib/strings/url-helpers' import {atoms as a, utils} from '#/alf' import {Live_Stroke2_Corner0_Rounded as LiveIcon} from '#/components/icons/Live' @@ -39,13 +40,12 @@ export function LiveEventFeedCardCompact({ return '/' }, [feed.url]) - useEffect(() => { + useCallOnce(() => { ax.metric('liveEvents:feedBanner:seen', { feed: feed.url, context: metricContext, }) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + })() return ( ax.features.enabled(ax.features.IsBskyTeam), [ax]) + return useMemo( + () => ax.features.enabled(ax.features.IsBskyTeam), + [ax.features], + ) } diff --git a/src/screens/Settings/ContentAndMediaSettings.tsx b/src/screens/Settings/ContentAndMediaSettings.tsx index ac7c1db48a..ba1e3b4506 100644 --- a/src/screens/Settings/ContentAndMediaSettings.tsx +++ b/src/screens/Settings/ContentAndMediaSettings.tsx @@ -26,7 +26,6 @@ import {Window_Stroke2_Corner2_Rounded as WindowIcon} from '#/components/icons/W import * as Layout from '#/components/Layout' import {useAnalytics} from '#/analytics' import {IS_NATIVE} from '#/env' -import {LiveEventFeedsSettingsToggle} from '#/features/liveEvents/components/LiveEventFeedsSettingsToggle' type Props = NativeStackScreenProps< CommonNavigatorParams, @@ -150,7 +149,6 @@ export function ContentAndMediaSettingsScreen({}: Props) { - - ) : ( - <> - - - - )} + ) : null}