[APP-1783] Clean up some feature gates and logging (#9729)

* Remove gates we don't need

* Clean up some logging

* Keep disable gates around for now

* Add missing gate

* Revert file

* Revert package changes
This commit is contained in:
Eric Bailey
2026-01-19 15:32:02 -06:00
committed by GitHub
parent 5989bf7fad
commit bd9e8244f1
25 changed files with 60 additions and 278 deletions
+1
View File
@@ -72,6 +72,7 @@ export default defineConfig(
sourceType: 'module', sourceType: 'module',
globals: { globals: {
...globals.browser, ...globals.browser,
...globals.node,
}, },
parserOptions: { parserOptions: {
parser: tsParser, parser: tsParser,
-1
View File
@@ -114,5 +114,4 @@ jest.mock('statsig-react-native-expo', () => ({
}, },
})) }))
jest.mock('../src/logger/bitdrift/lib', () => ({}))
jest.mock('../src/lib/statsig/statsig', () => ({})) jest.mock('../src/lib/statsig/statsig', () => ({}))
+4 -3
View File
@@ -1,5 +1,4 @@
import '#/logger/sentry/setup' import '#/logger/sentry/setup'
import '#/logger/bitdrift/setup'
import '#/view/icons' import '#/view/icons'
import React, {useEffect, useState} from 'react' import React, {useEffect, useState} from 'react'
@@ -66,8 +65,10 @@ import {Provider as PolicyUpdateOverlayProvider} from '#/components/PolicyUpdate
import {Provider as PortalProvider} from '#/components/Portal' import {Provider as PortalProvider} from '#/components/Portal'
import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext' import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext'
import {ToastOutlet} from '#/components/Toast' import {ToastOutlet} from '#/components/Toast'
import {Provider as AgeAssuranceV2Provider} from '#/ageAssurance' import {
import {prefetchAgeAssuranceConfig} from '#/ageAssurance' prefetchAgeAssuranceConfig,
Provider as AgeAssuranceV2Provider,
} from '#/ageAssurance'
import {IS_ANDROID, IS_IOS} from '#/env' import {IS_ANDROID, IS_IOS} from '#/env'
import { import {
prefetchLiveEvents, prefetchLiveEvents,
+3 -5
View File
@@ -7,7 +7,7 @@ import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native' import {useNavigation} from '@react-navigation/native'
import {type NavigationProp} from '#/lib/routes/types' import {type NavigationProp} from '#/lib/routes/types'
import {logEvent, useGate} from '#/lib/statsig/statsig' import {logEvent} from '#/lib/statsig/statsig'
import {logger} from '#/logger' import {logger} from '#/logger'
import {type MetricEvents} from '#/logger/metrics' import {type MetricEvents} from '#/logger/metrics'
import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useModerationOpts} from '#/state/preferences/moderation-opts'
@@ -435,7 +435,6 @@ export function ProfileGrid({
}) { }) {
const t = useTheme() const t = useTheme()
const {_} = useLingui() const {_} = useLingui()
const gate = useGate()
const moderationOpts = useModerationOpts() const moderationOpts = useModerationOpts()
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
const followDialogControl = useDialogControl() const followDialogControl = useDialogControl()
@@ -443,7 +442,6 @@ export function ProfileGrid({
const isLoading = isSuggestionsLoading || !moderationOpts const isLoading = isSuggestionsLoading || !moderationOpts
const isProfileHeaderContext = viewContext === 'profileHeader' const isProfileHeaderContext = viewContext === 'profileHeader'
const isFeedContext = viewContext === 'feed' const isFeedContext = viewContext === 'feed'
const showDismissButton = onDismiss && gate('suggested_users_dismiss')
const maxLength = gtMobile ? 3 : isProfileHeaderContext ? 12 : 6 const maxLength = gtMobile ? 3 : isProfileHeaderContext ? 12 : 6
const minLength = gtMobile ? 3 : 4 const minLength = gtMobile ? 3 : 4
@@ -584,12 +582,12 @@ export function ProfileGrid({
(hovered || pressed) && t.atoms.border_contrast_high, (hovered || pressed) && t.atoms.border_contrast_high,
]}> ]}>
<ProfileCard.Outer> <ProfileCard.Outer>
{showDismissButton && ( {onDismiss && (
<Button <Button
label={_(msg`Dismiss this suggestion`)} label={_(msg`Dismiss this suggestion`)}
onPress={e => { onPress={e => {
e.preventDefault() e.preventDefault()
onDismiss!(profile.did) onDismiss(profile.did)
logEvent('suggestedUser:dismiss', { logEvent('suggestedUser:dismiss', {
logContext: isFeedContext logContext: isFeedContext
? 'InterstitialDiscover' ? 'InterstitialDiscover'
@@ -12,14 +12,12 @@ import {useLingui} from '@lingui/react'
import {makeProfileLink} from '#/lib/routes/links' import {makeProfileLink} from '#/lib/routes/links'
import {shareUrl} from '#/lib/sharing' import {shareUrl} from '#/lib/sharing'
import {useGate} from '#/lib/statsig/statsig'
import {toShareUrl} from '#/lib/strings/url-helpers' import {toShareUrl} from '#/lib/strings/url-helpers'
import {logger} from '#/logger' import {logger} from '#/logger'
import {type Shadow} from '#/state/cache/post-shadow' import {type Shadow} from '#/state/cache/post-shadow'
import {useFeedFeedbackContext} from '#/state/feed-feedback' import {useFeedFeedbackContext} from '#/state/feed-feedback'
import {EventStopper} from '#/view/com/util/EventStopper' import {EventStopper} from '#/view/com/util/EventStopper'
import {native} from '#/alf' import {native} from '#/alf'
import {ArrowOutOfBoxModified_Stroke2_Corner2_Rounded as ArrowOutOfBoxIcon} from '#/components/icons/ArrowOutOfBox'
import {ArrowShareRight_Stroke2_Corner2_Rounded as ArrowShareRightIcon} from '#/components/icons/ArrowShareRight' import {ArrowShareRight_Stroke2_Corner2_Rounded as ArrowShareRightIcon} from '#/components/icons/ArrowShareRight'
import {useMenuControl} from '#/components/Menu' import {useMenuControl} from '#/components/Menu'
import * as Menu from '#/components/Menu' import * as Menu from '#/components/Menu'
@@ -50,13 +48,8 @@ let ShareMenuButton = ({
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo' logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
}): React.ReactNode => { }): React.ReactNode => {
const {_} = useLingui() const {_} = useLingui()
const gate = useGate()
const {feedDescriptor} = useFeedFeedbackContext() const {feedDescriptor} = useFeedFeedbackContext()
const ShareIcon = gate('alt_share_icon')
? ArrowShareRightIcon
: ArrowOutOfBoxIcon
const menuControl = useMenuControl() const menuControl = useMenuControl()
const [hasBeenOpen, setHasBeenOpen] = useState(false) const [hasBeenOpen, setHasBeenOpen] = useState(false)
const lazyMenuControl = useMemo( const lazyMenuControl = useMemo(
@@ -114,7 +107,7 @@ let ShareMenuButton = ({
{...props} {...props}
onLongPress={native(onNativeLongPress)} onLongPress={native(onNativeLongPress)}
hitSlop={hitSlop}> hitSlop={hitSlop}>
<PostControlButtonIcon icon={ShareIcon} /> <PostControlButtonIcon icon={ArrowShareRightIcon} />
</PostControlButton> </PostControlButton>
) )
}} }}
@@ -6,7 +6,6 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {HITSLOP_10} from '#/lib/constants' import {HITSLOP_10} from '#/lib/constants'
import {useGate} from '#/lib/statsig/statsig'
import {logger} from '#/logger' import {logger} from '#/logger'
import {Nux, useNux, useSaveNux} from '#/state/queries/nuxs' import {Nux, useNux, useSaveNux} from '#/state/queries/nuxs'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
@@ -89,16 +88,14 @@ function useInternalState() {
const {mutate: save, variables} = useSaveNux() const {mutate: save, variables} = useSaveNux()
const hidden = !!variables const hidden = !!variables
const isFeatureEnabled = useIsFindContactsFeatureEnabledBasedOnGeolocation() const isFeatureEnabled = useIsFindContactsFeatureEnabledBasedOnGeolocation()
const gate = useGate()
const visible = useMemo(() => { const visible = useMemo(() => {
if (IS_WEB) return false if (IS_WEB) return false
if (hidden) return false if (hidden) return false
if (nux && nux.completed) return false if (nux && nux.completed) return false
if (!isFeatureEnabled) return false if (!isFeatureEnabled) return false
if (gate('disable_settings_find_contacts')) return false
return true return true
}, [hidden, nux, isFeatureEnabled, gate]) }, [hidden, nux, isFeatureEnabled])
const close = () => { const close = () => {
save({ save({
@@ -15,8 +15,7 @@ import {
} from '#/components/dialogs/nuxs/utils' } from '#/components/dialogs/nuxs/utils'
import {Beaker_Stroke2_Corner2_Rounded as BeakerIcon} from '#/components/icons/Beaker' import {Beaker_Stroke2_Corner2_Rounded as BeakerIcon} from '#/components/icons/Beaker'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import {IS_WEB} from '#/env' import {IS_E2E, IS_WEB} from '#/env'
import {IS_E2E} from '#/env'
export const enabled = createIsEnabledCheck(props => { export const enabled = createIsEnabledCheck(props => {
return ( return (
+2 -14
View File
@@ -1,19 +1,7 @@
export type Gate = export type Gate =
// Keep this alphabetic please. // Keep this alphabetic please.
| 'alt_share_icon'
| 'debug_show_feedcontext' | 'debug_show_feedcontext'
| 'debug_subscriptions' | 'is_bsky_team_member' // special, do not remove
| 'disable_live_now_beta'
| 'disable_onboarding_find_contacts' | 'disable_onboarding_find_contacts'
| 'disable_settings_find_contacts' | 'disable_settings_find_contacts'
| 'explore_show_suggested_feeds' | 'disable_live_now_beta'
| 'feed_reply_button_open_thread'
| 'is_bsky_team_member' // special, do not remove
| 'old_postonboarding'
| 'onboarding_add_video_feed'
| 'onboarding_suggested_starterpacks'
| 'remove_show_latest_button'
| 'show_composer_prompt'
| 'suggested_users_dismiss'
| 'test_gate_1'
| 'test_gate_2'
-1
View File
@@ -1 +0,0 @@
export {debug, error, info, warn} from '@bitdrift/react-native'
-4
View File
@@ -1,4 +0,0 @@
export function debug() {}
export function error() {}
export function info() {}
export function warn() {}
-27
View File
@@ -1,27 +0,0 @@
import {init, SessionStrategy} from '@bitdrift/react-native'
import {Statsig} from 'statsig-react-native-expo'
import {initPromise} from '#/lib/statsig/statsig'
import {BITDRIFT_API_KEY} from '#/env'
initPromise.then(() => {
let isEnabled = false
let isNetworkEnabled = false
try {
if (Statsig.checkGate('enable_bitdrift_v2')) {
isEnabled = true
}
if (Statsig.checkGate('enable_bitdrift_v2_networking')) {
isNetworkEnabled = true
}
} catch (e) {
// Statsig may complain about it being called too early.
}
if (isEnabled && BITDRIFT_API_KEY) {
init(BITDRIFT_API_KEY, SessionStrategy.Activity, {
url: 'https://api-bsky.bitdrift.io',
// Only effects iOS, Android instrumentation is set via Gradle Plugin
enableNetworkInstrumentation: isNetworkEnabled,
})
}
})
+1 -5
View File
@@ -3,7 +3,6 @@ import {nanoid} from 'nanoid/non-secure'
import {logEvent} from '#/lib/statsig/statsig' import {logEvent} from '#/lib/statsig/statsig'
import {add} from '#/logger/logDump' import {add} from '#/logger/logDump'
import {type MetricEvents} from '#/logger/metrics' import {type MetricEvents} from '#/logger/metrics'
import {bitdriftTransport} from '#/logger/transports/bitdrift'
import {consoleTransport} from '#/logger/transports/console' import {consoleTransport} from '#/logger/transports/console'
import {sentryTransport} from '#/logger/transports/sentry' import {sentryTransport} from '#/logger/transports/sentry'
import { import {
@@ -13,7 +12,6 @@ import {
type Transport, type Transport,
} from '#/logger/types' } from '#/logger/types'
import {enabledLogLevels} from '#/logger/util' import {enabledLogLevels} from '#/logger/util'
import {IS_NATIVE} from '#/env'
import {ENV} from '#/env' import {ENV} from '#/env'
export {type MetricEvents as Metrics} from '#/logger/metrics' export {type MetricEvents as Metrics} from '#/logger/metrics'
@@ -21,9 +19,7 @@ export {type MetricEvents as Metrics} from '#/logger/metrics'
const TRANSPORTS: Transport[] = (function configureTransports() { const TRANSPORTS: Transport[] = (function configureTransports() {
switch (ENV) { switch (ENV) {
case 'production': { case 'production': {
return [sentryTransport, IS_NATIVE && bitdriftTransport].filter( return [sentryTransport].filter(Boolean)
Boolean,
) as Transport[]
} }
case 'test': { case 'test': {
return [] return []
-24
View File
@@ -1,24 +0,0 @@
import {debug, error, info, warn} from '#/logger/bitdrift/lib'
import {LogLevel, type Transport} from '#/logger/types'
import {prepareMetadata} from '#/logger/util'
const logFunctions = {
[LogLevel.Debug]: debug,
[LogLevel.Info]: info,
[LogLevel.Log]: info,
[LogLevel.Warn]: warn,
[LogLevel.Error]: error,
} as const
export const bitdriftTransport: Transport = (
level,
context,
message,
metadata,
) => {
const log = logFunctions[level]
log(message.toString(), {
__context__: context,
...prepareMetadata(metadata),
})
}
+5 -11
View File
@@ -20,7 +20,7 @@ import {
VIDEO_SAVED_FEED, VIDEO_SAVED_FEED,
} from '#/lib/constants' } from '#/lib/constants'
import {useRequestNotificationsPermission} from '#/lib/notifications/notifications' import {useRequestNotificationsPermission} from '#/lib/notifications/notifications'
import {logEvent, useGate} from '#/lib/statsig/statsig' import {logEvent} from '#/lib/statsig/statsig'
import {logger} from '#/logger' import {logger} from '#/logger'
import {useSetHasCheckedForStarterPack} from '#/state/preferences/used-starter-packs' import {useSetHasCheckedForStarterPack} from '#/state/preferences/used-starter-packs'
import {getAllListMembers} from '#/state/queries/list-members' import {getAllListMembers} from '#/state/queries/list-members'
@@ -61,7 +61,6 @@ export function StepFinished() {
const setActiveStarterPack = useSetActiveStarterPack() const setActiveStarterPack = useSetActiveStarterPack()
const setHasCheckedForStarterPack = useSetHasCheckedForStarterPack() const setHasCheckedForStarterPack = useSetHasCheckedForStarterPack()
const {startProgressGuide} = useProgressGuideControls() const {startProgressGuide} = useProgressGuideControls()
const gate = useGate()
const finishOnboarding = useCallback(async () => { const finishOnboarding = useCallback(async () => {
setSaving(true) setSaving(true)
@@ -114,13 +113,11 @@ export function StepFinished() {
...TIMELINE_SAVED_FEED, ...TIMELINE_SAVED_FEED,
id: TID.nextStr(), id: TID.nextStr(),
}, },
] {
if (gate('onboarding_add_video_feed')) {
feedsToSave.push({
...VIDEO_SAVED_FEED, ...VIDEO_SAVED_FEED,
id: TID.nextStr(), id: TID.nextStr(),
}) },
} ]
// Any starter pack feeds will be pinned _after_ the defaults // Any starter pack feeds will be pinned _after_ the defaults
if (starterPack && starterPack.feeds?.length) { if (starterPack && starterPack.feeds?.length) {
@@ -200,9 +197,7 @@ export function StepFinished() {
setSaving(false) setSaving(false)
setActiveStarterPack(undefined) setActiveStarterPack(undefined)
setHasCheckedForStarterPack(true) setHasCheckedForStarterPack(true)
startProgressGuide( startProgressGuide('follow-10')
gate('old_postonboarding') ? 'like-10-and-follow-7' : 'follow-10',
)
dispatch({type: 'finish'}) dispatch({type: 'finish'})
onboardDispatch({type: 'finish'}) onboardDispatch({type: 'finish'})
logEvent('onboarding:finished:nextPressed', { logEvent('onboarding:finished:nextPressed', {
@@ -238,7 +233,6 @@ export function StepFinished() {
setActiveStarterPack, setActiveStarterPack,
setHasCheckedForStarterPack, setHasCheckedForStarterPack,
startProgressGuide, startProgressGuide,
gate,
]) ])
return ( return (
+3 -7
View File
@@ -23,16 +23,15 @@ import {useIsFindContactsFeatureEnabledBasedOnGeolocation} from '#/components/co
import {useFindContactsFlowState} from '#/components/contacts/state' import {useFindContactsFlowState} from '#/components/contacts/state'
import {Portal} from '#/components/Portal' import {Portal} from '#/components/Portal'
import {ScreenTransition} from '#/components/ScreenTransition' import {ScreenTransition} from '#/components/ScreenTransition'
import {IS_NATIVE} from '#/env' import {ENV, IS_NATIVE} from '#/env'
import {ENV} from '#/env'
import {StepFindContacts} from './StepFindContacts' import {StepFindContacts} from './StepFindContacts'
import {StepFindContactsIntro} from './StepFindContactsIntro' import {StepFindContactsIntro} from './StepFindContactsIntro'
import {StepSuggestedAccounts} from './StepSuggestedAccounts' import {StepSuggestedAccounts} from './StepSuggestedAccounts'
import {StepSuggestedStarterpacks} from './StepSuggestedStarterpacks' import {StepSuggestedStarterpacks} from './StepSuggestedStarterpacks'
export function Onboarding() { export function Onboarding() {
const gate = useGate()
const t = useTheme() const t = useTheme()
const gate = useGate()
const {contentLanguages} = useLanguagePrefs() const {contentLanguages} = useLanguagePrefs()
const probablySpeaksEnglish = useMemo(() => { const probablySpeaksEnglish = useMemo(() => {
@@ -41,10 +40,7 @@ export function Onboarding() {
}, [contentLanguages]) }, [contentLanguages])
// starter packs screen is currently geared towards english-speaking accounts // starter packs screen is currently geared towards english-speaking accounts
const showSuggestedStarterpacks = const showSuggestedStarterpacks = ENV !== 'e2e' && probablySpeaksEnglish
ENV !== 'e2e' &&
probablySpeaksEnglish &&
gate('onboarding_suggested_starterpacks')
const findContactsEnabled = const findContactsEnabled =
useIsFindContactsFeatureEnabledBasedOnGeolocation() useIsFindContactsFeatureEnabledBasedOnGeolocation()
@@ -7,7 +7,6 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack'
import {PressableScale} from '#/lib/custom-animations/PressableScale' import {PressableScale} from '#/lib/custom-animations/PressableScale'
import {type CommonNavigatorParams} from '#/lib/routes/types' import {type CommonNavigatorParams} from '#/lib/routes/types'
import {useGate} from '#/lib/statsig/statsig'
import {AppIconImage} from '#/screens/Settings/AppIconSettings/AppIconImage' import {AppIconImage} from '#/screens/Settings/AppIconSettings/AppIconImage'
import {type AppIconSet} from '#/screens/Settings/AppIconSettings/types' import {type AppIconSet} from '#/screens/Settings/AppIconSettings/types'
import {useAppIconSets} from '#/screens/Settings/AppIconSettings/useAppIconSets' import {useAppIconSets} from '#/screens/Settings/AppIconSettings/useAppIconSets'
@@ -15,15 +14,13 @@ import {atoms as a, useTheme} from '#/alf'
import * as Toggle from '#/components/forms/Toggle' import * as Toggle from '#/components/forms/Toggle'
import * as Layout from '#/components/Layout' import * as Layout from '#/components/Layout'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import {IS_ANDROID} from '#/env' import {IS_ANDROID, IS_INTERNAL} from '#/env'
import {IS_INTERNAL} from '#/env'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppIconSettings'> type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppIconSettings'>
export function AppIconSettingsScreen({}: Props) { export function AppIconSettingsScreen({}: Props) {
const t = useTheme() const t = useTheme()
const {_} = useLingui() const {_} = useLingui()
const sets = useAppIconSets() const sets = useAppIconSets()
const gate = useGate()
const [currentAppIcon, setCurrentAppIcon] = useState(() => const [currentAppIcon, setCurrentAppIcon] = useState(() =>
getAppIconName(DynamicAppIcon.getAppIcon()), getAppIconName(DynamicAppIcon.getAppIcon()),
) )
@@ -86,7 +83,7 @@ export function AppIconSettingsScreen({}: Props) {
))} ))}
</Group> </Group>
{IS_INTERNAL && gate('debug_subscriptions') && ( {IS_INTERNAL && (
<> <>
<Text <Text
style={[ style={[
+2 -4
View File
@@ -1,6 +1,5 @@
import {useState} from 'react' import {useState} from 'react'
import {Alert, LayoutAnimation, Pressable, View} from 'react-native' import {Alert, LayoutAnimation, Linking, Pressable, View} from 'react-native'
import {Linking} from 'react-native'
import {useReducedMotion} from 'react-native-reanimated' import {useReducedMotion} from 'react-native-reanimated'
import {type AppBskyActorDefs, moderateProfile} from '@atproto/api' import {type AppBskyActorDefs, moderateProfile} from '@atproto/api'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
@@ -70,8 +69,7 @@ import {
shouldShowVerificationCheckButton, shouldShowVerificationCheckButton,
VerificationCheckButton, VerificationCheckButton,
} from '#/components/verification/VerificationCheckButton' } from '#/components/verification/VerificationCheckButton'
import {IS_IOS, IS_NATIVE} from '#/env' import {IS_INTERNAL, IS_IOS, IS_NATIVE} from '#/env'
import {IS_INTERNAL} from '#/env'
import {device, useStorage} from '#/storage' import {device, useStorage} from '#/storage'
import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged' import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged'
+6 -92
View File
@@ -1,8 +1,5 @@
import {type AtpSessionData, type AtpSessionEvent} from '@atproto/api' import {type AtpSessionData, type AtpSessionEvent} from '@atproto/api'
import {sha256} from 'js-sha256'
import {Statsig} from 'statsig-react-native-expo'
import {IS_INTERNAL} from '#/env'
import {type Schema} from '../persisted' import {type Schema} from '../persisted'
import {type Action, type State} from './reducer' import {type Action, type State} from './reducer'
import {type SessionAccount} from './types' import {type SessionAccount} from './types'
@@ -68,92 +65,9 @@ export function wrapSessionReducerForLogging(reducer: Reducer): Reducer {
} }
} }
let nextMessageIndex = 0 /**
const MAX_SLICE_LENGTH = 1000 * Stubs, previously used to log session errors to Statsig. We may revive this
* using Sentry or Bitdrift in the future.
// Not gated. */
export function addSessionErrorLog(did: string, event: AtpSessionEvent) { export function addSessionErrorLog(_did: string, _event: AtpSessionEvent) {}
try { export function addSessionDebugLog(_log: Log) {}
if (!Statsig.initializeCalled() || !Statsig.getStableID()) {
return
}
const stack = (new Error().stack ?? '').slice(0, MAX_SLICE_LENGTH)
Statsig.logEvent('session:error', null, {
did,
event,
stack,
})
} catch (e) {
console.error(e)
}
}
export function addSessionDebugLog(log: Log) {
try {
if (!Statsig.initializeCalled() || !Statsig.getStableID()) {
// Drop these logs for now.
return
}
// DISABLING THIS GATE DUE TO EME @TODO EME-GATE
if (!IS_INTERNAL) {
return
}
// if (!Statsig.checkGate('debug_session')) {
// return
// }
const messageIndex = nextMessageIndex++
const {type, ...content} = log
let payload = JSON.stringify(content, replacer)
let nextSliceIndex = 0
while (payload.length > 0) {
const sliceIndex = nextSliceIndex++
const slice = payload.slice(0, MAX_SLICE_LENGTH)
payload = payload.slice(MAX_SLICE_LENGTH)
Statsig.logEvent('session:debug', null, {
realmId,
messageIndex: String(messageIndex),
messageType: type,
sliceIndex: String(sliceIndex),
slice,
})
}
} catch (e) {
console.error(e)
}
}
let agentIds = new WeakMap<object, string>()
let realmId = Math.random().toString(36).slice(2)
let nextAgentId = 1
function getAgentId(agent: object) {
let id = agentIds.get(agent)
if (id === undefined) {
id = realmId + '::' + nextAgentId++
agentIds.set(agent, id)
}
return id
}
function replacer(key: string, value: unknown) {
if (typeof value === 'object' && value != null && 'api' in value) {
return getAgentId(value)
}
if (
key === 'service' ||
key === 'email' ||
key === 'emailConfirmed' ||
key === 'emailAuthFactor' ||
key === 'pdsUrl'
) {
return undefined
}
if (
typeof value === 'string' &&
(key === 'refreshJwt' || key === 'accessJwt')
) {
return sha256(value)
}
return value
}
+3 -6
View File
@@ -31,7 +31,7 @@ import {isStatusStillActive, validateStatus} from '#/lib/actor-status'
import {DISCOVER_FEED_URI, KNOWN_SHUTDOWN_FEEDS} from '#/lib/constants' import {DISCOVER_FEED_URI, KNOWN_SHUTDOWN_FEEDS} from '#/lib/constants'
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {logEvent, useGate} from '#/lib/statsig/statsig' import {logEvent} from '#/lib/statsig/statsig'
import {isNetworkError} from '#/lib/strings/errors' import {isNetworkError} from '#/lib/strings/errors'
import {logger} from '#/logger' import {logger} from '#/logger'
import {usePostAuthorShadowFilter} from '#/state/cache/profile-shadow' import {usePostAuthorShadowFilter} from '#/state/cache/profile-shadow'
@@ -235,7 +235,6 @@ let PostFeed = ({
const {_} = useLingui() const {_} = useLingui()
const queryClient = useQueryClient() const queryClient = useQueryClient()
const {currentAccount, hasSession} = useSession() const {currentAccount, hasSession} = useSession()
const gate = useGate()
const initialNumToRender = useInitialNumToRender() const initialNumToRender = useInitialNumToRender()
const feedFeedback = useFeedFeedbackContext() const feedFeedback = useFeedFeedbackContext()
const [isPTRing, setIsPTRing] = useState(false) const [isPTRing, setIsPTRing] = useState(false)
@@ -522,8 +521,7 @@ let PostFeed = ({
if ( if (
hasSession && hasSession &&
(feedUriOrActorDid === DISCOVER_FEED_URI || (feedUriOrActorDid === DISCOVER_FEED_URI ||
feed === 'following') && feed === 'following')
gate('show_composer_prompt')
) { ) {
arr.push({ arr.push({
type: 'composerPrompt', type: 'composerPrompt',
@@ -546,7 +544,7 @@ let PostFeed = ({
} else if (feedKind === 'following') { } else if (feedKind === 'following') {
if (sliceIndex === 0) { if (sliceIndex === 0) {
// Show composer prompt for Following feed // Show composer prompt for Following feed
if (hasSession && gate('show_composer_prompt')) { if (hasSession) {
arr.push({ arr.push({
type: 'composerPrompt', type: 'composerPrompt',
key: 'composerPrompt-' + sliceIndex, key: 'composerPrompt-' + sliceIndex,
@@ -680,7 +678,6 @@ let PostFeed = ({
hasPressedShowLessUris, hasPressedShowLessUris,
ageAssuranceBannerState, ageAssuranceBannerState,
isCurrentFeedAtStartupSelected, isCurrentFeedAtStartupSelected,
gate,
blockedOrMutedAuthors, blockedOrMutedAuthors,
]) ])
+1 -14
View File
@@ -9,7 +9,6 @@ import {
type ModerationDecision, type ModerationDecision,
RichText as RichTextAPI, RichText as RichTextAPI,
} from '@atproto/api' } from '@atproto/api'
import {useNavigation} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query' import {useQueryClient} from '@tanstack/react-query'
import {useActorStatus} from '#/lib/actor-status' import {useActorStatus} from '#/lib/actor-status'
@@ -18,8 +17,6 @@ import {MAX_POST_LINES} from '#/lib/constants'
import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
import {makeProfileLink} from '#/lib/routes/links' import {makeProfileLink} from '#/lib/routes/links'
import {type NavigationProp} from '#/lib/routes/types'
import {useGate} from '#/lib/statsig/statsig'
import {countLines} from '#/lib/strings/helpers' import {countLines} from '#/lib/strings/helpers'
import {logger} from '#/logger' import {logger} from '#/logger'
import { import {
@@ -51,7 +48,6 @@ import {PostControls} from '#/components/PostControls'
import {DiscoverDebug} from '#/components/PostControls/DiscoverDebug' import {DiscoverDebug} from '#/components/PostControls/DiscoverDebug'
import {RichText} from '#/components/RichText' import {RichText} from '#/components/RichText'
import {SubtleHover} from '#/components/SubtleHover' import {SubtleHover} from '#/components/SubtleHover'
import {ENV} from '#/env'
import * as bsky from '#/types/bsky' import * as bsky from '#/types/bsky'
import {PostFeedReason} from './PostFeedReason' import {PostFeedReason} from './PostFeedReason'
@@ -164,13 +160,11 @@ let FeedItemInner = ({
}): React.ReactNode => { }): React.ReactNode => {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const {openComposer} = useOpenComposer() const {openComposer} = useOpenComposer()
const navigation = useNavigation<NavigationProp>()
const pal = usePalette('default') const pal = usePalette('default')
const gate = useGate()
const [hover, setHover] = useState(false) const [hover, setHover] = useState(false)
const [href, rkey] = useMemo(() => { const [href] = useMemo(() => {
const urip = new AtUri(post.uri) const urip = new AtUri(post.uri)
return [makeProfileLink(post.author, 'post', urip.rkey), urip.rkey] return [makeProfileLink(post.author, 'post', urip.rkey), urip.rkey]
}, [post.uri, post.author]) }, [post.uri, post.author])
@@ -184,12 +178,6 @@ let FeedItemInner = ({
feedContext, feedContext,
reqId, reqId,
}) })
if (gate('feed_reply_button_open_thread') && ENV !== 'e2e') {
navigation.navigate('PostThread', {
name: post.author.did,
rkey,
})
} else {
openComposer({ openComposer({
replyTo: { replyTo: {
uri: post.uri, uri: post.uri,
@@ -202,7 +190,6 @@ let FeedItemInner = ({
}, },
}) })
} }
}
const onOpenAuthor = () => { const onOpenAuthor = () => {
sendInteraction({ sendInteraction({
@@ -8,7 +8,6 @@ import {PressableScale} from '#/lib/custom-animations/PressableScale'
import {useMinimalShellFabTransform} from '#/lib/hooks/useMinimalShellTransform' import {useMinimalShellFabTransform} from '#/lib/hooks/useMinimalShellTransform'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {clamp} from '#/lib/numbers' import {clamp} from '#/lib/numbers'
import {useGate} from '#/lib/statsig/statsig'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {atoms as a, useLayoutBreakpoints, useTheme, web} from '#/alf' import {atoms as a, useLayoutBreakpoints, useTheme, web} from '#/alf'
import {useInteractionState} from '#/components/hooks/useInteractionState' import {useInteractionState} from '#/components/hooks/useInteractionState'
@@ -40,11 +39,6 @@ export function LoadLatestBtn({
// move button inline if it starts overlapping the left nav // move button inline if it starts overlapping the left nav
const isTallViewport = useMediaQuery({minHeight: 700}) const isTallViewport = useMediaQuery({minHeight: 700})
const gate = useGate()
if (gate('remove_show_latest_button')) {
return null
}
// Adjust height of the fab if we have a session only on mobile web. If we don't have a session, we want to adjust // Adjust height of the fab if we have a session only on mobile web. If we don't have a session, we want to adjust
// it on both tablet and mobile since we are showing the bottom bar (see createNativeStackNavigatorWithAuth) // it on both tablet and mobile since we are showing the bottom bar (see createNativeStackNavigatorWithAuth)
const showBottomBar = hasSession ? isMobile : isTabletOrMobile const showBottomBar = hasSession ? isMobile : isTabletOrMobile
+4 -7
View File
@@ -18,9 +18,7 @@ import {useNavigationTabState} from '#/lib/hooks/useNavigationTabState'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
import {clamp} from '#/lib/numbers' import {clamp} from '#/lib/numbers'
import {getTabState, TabState} from '#/lib/routes/helpers' import {getTabState, TabState} from '#/lib/routes/helpers'
import {useGate} from '#/lib/statsig/statsig'
import {emitSoftReset} from '#/state/events' import {emitSoftReset} from '#/state/events'
import {useHomeBadge} from '#/state/home-badge'
import {useUnreadMessageCount} from '#/state/queries/messages/list-conversations' import {useUnreadMessageCount} from '#/state/queries/messages/list-conversations'
import {useUnreadNotifications} from '#/state/queries/notifications/unread' import {useUnreadNotifications} from '#/state/queries/notifications/unread'
import {useProfileQuery} from '#/state/queries/profile' import {useProfileQuery} from '#/state/queries/profile'
@@ -43,8 +41,10 @@ import {
HomeOpen_Filled_Corner0_Rounded as HomeFilled, HomeOpen_Filled_Corner0_Rounded as HomeFilled,
HomeOpen_Stoke2_Corner0_Rounded as Home, HomeOpen_Stoke2_Corner0_Rounded as Home,
} from '#/components/icons/HomeOpen' } from '#/components/icons/HomeOpen'
import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass' import {
import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass' MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled,
MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlass,
} from '#/components/icons/MagnifyingGlass'
import { import {
Message_Stroke2_Corner0_Rounded as Message, Message_Stroke2_Corner0_Rounded as Message,
Message_Stroke2_Corner0_Rounded_Filled as MessageFilled, Message_Stroke2_Corner0_Rounded_Filled as MessageFilled,
@@ -72,8 +72,6 @@ export function BottomBar({navigation}: BottomTabBarProps) {
const dedupe = useDedupe() const dedupe = useDedupe()
const accountSwitchControl = useDialogControl() const accountSwitchControl = useDialogControl()
const playHaptic = useHaptics() const playHaptic = useHaptics()
const hasHomeBadge = useHomeBadge()
const gate = useGate()
const hideBorder = useHideBottomBarBorder() const hideBorder = useHideBottomBarBorder()
const iconWidth = 28 const iconWidth = 28
@@ -172,7 +170,6 @@ export function BottomBar({navigation}: BottomTabBarProps) {
/> />
) )
} }
hasNew={hasHomeBadge && gate('remove_show_latest_button')}
onPress={onPressHome} onPress={onPressHome}
accessibilityRole="tab" accessibilityRole="tab"
accessibilityLabel={_(msg`Home`)} accessibilityLabel={_(msg`Home`)}
+5 -10
View File
@@ -10,8 +10,6 @@ import {useMinimalShellFooterTransform} from '#/lib/hooks/useMinimalShellTransfo
import {getCurrentRoute, isTab} from '#/lib/routes/helpers' import {getCurrentRoute, isTab} from '#/lib/routes/helpers'
import {makeProfileLink} from '#/lib/routes/links' import {makeProfileLink} from '#/lib/routes/links'
import {type CommonNavigatorParams} from '#/lib/routes/types' import {type CommonNavigatorParams} from '#/lib/routes/types'
import {useGate} from '#/lib/statsig/statsig'
import {useHomeBadge} from '#/state/home-badge'
import {useUnreadMessageCount} from '#/state/queries/messages/list-conversations' import {useUnreadMessageCount} from '#/state/queries/messages/list-conversations'
import {useUnreadNotifications} from '#/state/queries/notifications/unread' import {useUnreadNotifications} from '#/state/queries/notifications/unread'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
@@ -31,8 +29,10 @@ import {
HomeOpen_Filled_Corner0_Rounded as HomeFilled, HomeOpen_Filled_Corner0_Rounded as HomeFilled,
HomeOpen_Stoke2_Corner0_Rounded as Home, HomeOpen_Stoke2_Corner0_Rounded as Home,
} from '#/components/icons/HomeOpen' } from '#/components/icons/HomeOpen'
import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass' import {
import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass' MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled,
MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlass,
} from '#/components/icons/MagnifyingGlass'
import { import {
Message_Stroke2_Corner0_Rounded as Message, Message_Stroke2_Corner0_Rounded as Message,
Message_Stroke2_Corner0_Rounded_Filled as MessageFilled, Message_Stroke2_Corner0_Rounded_Filled as MessageFilled,
@@ -57,8 +57,6 @@ export function BottomBarWeb() {
const unreadMessageCount = useUnreadMessageCount() const unreadMessageCount = useUnreadMessageCount()
const notificationCountStr = useUnreadNotifications() const notificationCountStr = useUnreadNotifications()
const hasHomeBadge = useHomeBadge()
const gate = useGate()
const showSignIn = React.useCallback(() => { const showSignIn = React.useCallback(() => {
closeAllActiveElements() closeAllActiveElements()
@@ -86,10 +84,7 @@ export function BottomBarWeb() {
onLayout={event => footerHeight.set(event.nativeEvent.layout.height)}> onLayout={event => footerHeight.set(event.nativeEvent.layout.height)}>
{hasSession ? ( {hasSession ? (
<> <>
<NavItem <NavItem routeName="Home" href="/">
routeName="Home"
href="/"
hasNew={hasHomeBadge && gate('remove_show_latest_button')}>
{({isActive}) => { {({isActive}) => {
const Icon = isActive ? HomeFilled : Home const Icon = isActive ? HomeFilled : Home
return ( return (
+4 -7
View File
@@ -16,11 +16,9 @@ import {
type CommonNavigatorParams, type CommonNavigatorParams,
type NavigationProp, type NavigationProp,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import {useGate} from '#/lib/statsig/statsig'
import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {isInvalidHandle, sanitizeHandle} from '#/lib/strings/handles' import {isInvalidHandle, sanitizeHandle} from '#/lib/strings/handles'
import {emitSoftReset} from '#/state/events' import {emitSoftReset} from '#/state/events'
import {useHomeBadge} from '#/state/home-badge'
import {useFetchHandle} from '#/state/queries/handle' import {useFetchHandle} from '#/state/queries/handle'
import {useUnreadMessageCount} from '#/state/queries/messages/list-conversations' import {useUnreadMessageCount} from '#/state/queries/messages/list-conversations'
import {useUnreadNotifications} from '#/state/queries/notifications/unread' import {useUnreadNotifications} from '#/state/queries/notifications/unread'
@@ -55,8 +53,10 @@ import {
HomeOpen_Filled_Corner0_Rounded as HomeFilled, HomeOpen_Filled_Corner0_Rounded as HomeFilled,
HomeOpen_Stoke2_Corner0_Rounded as Home, HomeOpen_Stoke2_Corner0_Rounded as Home,
} from '#/components/icons/HomeOpen' } from '#/components/icons/HomeOpen'
import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass' import {
import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass' MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled,
MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlass,
} from '#/components/icons/MagnifyingGlass'
import { import {
Message_Stroke2_Corner0_Rounded as Message, Message_Stroke2_Corner0_Rounded as Message,
Message_Stroke2_Corner0_Rounded_Filled as MessageFilled, Message_Stroke2_Corner0_Rounded_Filled as MessageFilled,
@@ -617,8 +617,6 @@ export function DesktopLeftNav() {
const {isDesktop} = useWebMediaQueries() const {isDesktop} = useWebMediaQueries()
const {leftNavMinimal, centerColumnOffset} = useLayoutBreakpoints() const {leftNavMinimal, centerColumnOffset} = useLayoutBreakpoints()
const numUnreadNotifications = useUnreadNotifications() const numUnreadNotifications = useUnreadNotifications()
const hasHomeBadge = useHomeBadge()
const gate = useGate()
if (!hasSession && !isDesktop) { if (!hasSession && !isDesktop) {
return null return null
@@ -654,7 +652,6 @@ export function DesktopLeftNav() {
<> <>
<NavItem <NavItem
href="/" href="/"
hasNew={hasHomeBadge && gate('remove_show_latest_button')}
icon={ icon={
<Home <Home
aria-hidden={true} aria-hidden={true}