Move /platform/detection vars into /env (#9707)

* Add platform vars to env

* Replace /platform/detection with /env
This commit is contained in:
Eric Bailey
2026-01-16 16:28:17 -06:00
committed by GitHub
parent bd510d8468
commit 0589bd7d9e
244 changed files with 789 additions and 789 deletions
@@ -7,8 +7,8 @@ import Animated, {
} from 'react-native-reanimated'
import type React from 'react'
import {isIOS} from '#/platform/detection'
import {usePagerHeaderContext} from '#/view/com/pager/PagerHeaderContext'
import {IS_IOS} from '#/env'
export function GrowableAvatar({
children,
@@ -20,7 +20,7 @@ export function GrowableAvatar({
const pagerContext = usePagerHeaderContext()
// pagerContext should only be present on iOS, but better safe than sorry
if (!pagerContext || !isIOS) {
if (!pagerContext || !IS_IOS) {
return <View style={style}>{children}</View>
}
@@ -15,13 +15,13 @@ import {BlurView} from 'expo-blur'
import {useIsFetching} from '@tanstack/react-query'
import type React from 'react'
import {isIOS} from '#/platform/detection'
import {RQKEY_ROOT as STARTERPACK_RQKEY_ROOT} from '#/state/queries/actor-starter-packs'
import {RQKEY_ROOT as FEED_RQKEY_ROOT} from '#/state/queries/post-feed'
import {RQKEY_ROOT as FEEDGEN_RQKEY_ROOT} from '#/state/queries/profile-feedgens'
import {RQKEY_ROOT as LIST_RQKEY_ROOT} from '#/state/queries/profile-lists'
import {usePagerHeaderContext} from '#/view/com/pager/PagerHeaderContext'
import {atoms as a} from '#/alf'
import {IS_IOS} from '#/env'
const AnimatedBlurView = Animated.createAnimatedComponent(BlurView)
@@ -39,7 +39,7 @@ export function GrowableBanner({
const pagerContext = usePagerHeaderContext()
// plain non-growable mode for Android/Web
if (!pagerContext || !isIOS) {
if (!pagerContext || !IS_IOS) {
return (
<Pressable
onPress={onPress}
@@ -164,7 +164,7 @@ function GrowableBannerInner({
style={[
a.absolute,
a.inset_0,
{top: topInset - (isIOS ? 15 : 0)},
{top: topInset - (IS_IOS ? 15 : 0)},
a.justify_center,
a.align_center,
]}>
+3 -3
View File
@@ -4,11 +4,11 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {isInvalidHandle, sanitizeHandle} from '#/lib/strings/handles'
import {isIOS, isNative} from '#/platform/detection'
import {type Shadow} from '#/state/cache/types'
import {atoms as a, useTheme, web} from '#/alf'
import {NewskieDialog} from '#/components/NewskieDialog'
import {Text} from '#/components/Typography'
import {IS_IOS, IS_NATIVE} from '#/env'
export function ProfileHeaderHandle({
profile,
@@ -24,7 +24,7 @@ export function ProfileHeaderHandle({
return (
<View
style={[a.flex_row, a.gap_sm, a.align_center, {maxWidth: '100%'}]}
pointerEvents={disableTaps ? 'none' : isIOS ? 'auto' : 'box-none'}>
pointerEvents={disableTaps ? 'none' : IS_IOS ? 'auto' : 'box-none'}>
<NewskieDialog profile={profile} disabled={disableTaps} />
{profile.viewer?.followedBy && !blockHide ? (
<View style={[t.atoms.bg_contrast_50, a.rounded_xs, a.px_sm, a.py_xs]}>
@@ -59,7 +59,7 @@ export function ProfileHeaderHandle({
profile.handle,
'@',
// forceLTR handled by CSS above on web
isNative,
IS_NATIVE,
)}
</Text>
</View>
@@ -15,7 +15,6 @@ import {MAX_LABELERS} from '#/lib/constants'
import {useHaptics} from '#/lib/haptics'
import {isAppLabeler} from '#/lib/moderation'
import {logger} from '#/logger'
import {isIOS} from '#/platform/detection'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {type Shadow} from '#/state/cache/types'
import {useLabelerSubscriptionMutation} from '#/state/queries/labeler'
@@ -35,6 +34,7 @@ import * as Prompt from '#/components/Prompt'
import {RichText} from '#/components/RichText'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {IS_IOS} from '#/env'
import {ProfileHeaderDisplayName} from './DisplayName'
import {EditProfileDialog} from './EditProfileDialog'
import {ProfileHeaderHandle} from './Handle'
@@ -111,10 +111,10 @@ let ProfileHeaderLabeler = ({
isPlaceholderProfile={isPlaceholderProfile}>
<View
style={[a.px_lg, a.pt_md, a.pb_sm]}
pointerEvents={isIOS ? 'auto' : 'box-none'}>
pointerEvents={IS_IOS ? 'auto' : 'box-none'}>
<View
style={[a.flex_row, a.justify_end, a.align_center, a.gap_xs, a.pb_lg]}
pointerEvents={isIOS ? 'auto' : 'box-none'}>
pointerEvents={IS_IOS ? 'auto' : 'box-none'}>
<HeaderLabelerButtons profile={profile} />
</View>
<View style={[a.flex_col, a.gap_2xs, a.pt_2xs, a.pb_md]}>
@@ -15,7 +15,6 @@ import {useHaptics} from '#/lib/haptics'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {logger} from '#/logger'
import {isIOS} from '#/platform/detection'
import {type Shadow, useProfileShadow} from '#/state/cache/profile-shadow'
import {
useProfileBlockMutationQueue,
@@ -39,6 +38,7 @@ import {RichText} from '#/components/RichText'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton'
import {IS_IOS} from '#/env'
import {EditProfileDialog} from './EditProfileDialog'
import {ProfileHeaderHandle} from './Handle'
import {ProfileHeaderMetrics} from './Metrics'
@@ -103,7 +103,7 @@ let ProfileHeaderStandard = ({
isPlaceholderProfile={isPlaceholderProfile}>
<View
style={[a.px_lg, a.pt_md, a.pb_sm, a.overflow_hidden]}
pointerEvents={isIOS ? 'auto' : 'box-none'}>
pointerEvents={IS_IOS ? 'auto' : 'box-none'}>
<View
style={[
{paddingLeft: 90},
@@ -114,7 +114,7 @@ let ProfileHeaderStandard = ({
a.pb_sm,
a.flex_wrap,
]}
pointerEvents={isIOS ? 'auto' : 'box-none'}>
pointerEvents={IS_IOS ? 'auto' : 'box-none'}>
<HeaderStandardButtons
profile={profile}
moderation={moderation}
+5 -5
View File
@@ -19,7 +19,6 @@ import {BACK_HITSLOP} from '#/lib/constants'
import {useHaptics} from '#/lib/haptics'
import {type NavigationProp} from '#/lib/routes/types'
import {logger} from '#/logger'
import {isIOS} from '#/platform/detection'
import {type Shadow} from '#/state/cache/types'
import {useLightboxControls} from '#/state/lightbox'
import {useSession} from '#/state/session'
@@ -35,6 +34,7 @@ import {LiveIndicator} from '#/components/live/LiveIndicator'
import {LiveStatusDialog} from '#/components/live/LiveStatusDialog'
import {LabelsOnMe} from '#/components/moderation/LabelsOnMe'
import {ProfileHeaderAlerts} from '#/components/moderation/ProfileHeaderAlerts'
import {IS_IOS} from '#/env'
import {GrowableAvatar} from './GrowableAvatar'
import {GrowableBanner} from './GrowableBanner'
import {StatusBarShadow} from './StatusBarShadow'
@@ -167,9 +167,9 @@ let ProfileHeaderShell = ({
}, [profile.banner, moderation, _openLightbox, bannerRef])
return (
<View style={t.atoms.bg} pointerEvents={isIOS ? 'auto' : 'box-none'}>
<View style={t.atoms.bg} pointerEvents={IS_IOS ? 'auto' : 'box-none'}>
<View
pointerEvents={isIOS ? 'auto' : 'box-none'}
pointerEvents={IS_IOS ? 'auto' : 'box-none'}
style={[a.relative, {height: 150}]}>
<StatusBarShadow />
<GrowableBanner
@@ -244,7 +244,7 @@ let ProfileHeaderShell = ({
a.px_lg,
a.pt_xs,
a.pb_sm,
isIOS ? a.pointer_events_auto : {pointerEvents: 'box-none'},
IS_IOS ? a.pointer_events_auto : {pointerEvents: 'box-none'},
]}
/>
) : (
@@ -254,7 +254,7 @@ let ProfileHeaderShell = ({
a.px_lg,
a.pt_xs,
a.pb_sm,
isIOS ? a.pointer_events_auto : {pointerEvents: 'box-none'},
IS_IOS ? a.pointer_events_auto : {pointerEvents: 'box-none'},
]}
/>
))}
@@ -5,9 +5,9 @@ import Animated, {
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {LinearGradient} from 'expo-linear-gradient'
import {isIOS} from '#/platform/detection'
import {usePagerHeaderContext} from '#/view/com/pager/PagerHeaderContext'
import {atoms as a} from '#/alf'
import {IS_IOS} from '#/env'
const AnimatedLinearGradient = Animated.createAnimatedComponent(LinearGradient)
@@ -15,7 +15,7 @@ export function StatusBarShadow() {
const {top: topInset} = useSafeAreaInsets()
const pagerContext = usePagerHeaderContext()
if (isIOS && pagerContext) {
if (IS_IOS && pagerContext) {
const {scrollY} = pagerContext
return <StatusBarShadowInnner scrollY={scrollY} />
}
@@ -2,7 +2,6 @@ import React from 'react'
import {type AppBskyActorDefs} from '@atproto/api'
import {AccordionAnimation} from '#/lib/custom-animations/AccordionAnimation'
import {isAndroid} from '#/platform/detection'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {
useSuggestedFollowsByActorQuery,
@@ -10,6 +9,7 @@ import {
} from '#/state/queries/suggested-follows'
import {useBreakpoints} from '#/alf'
import {ProfileGrid} from '#/components/FeedInterstitials'
import {IS_ANDROID} from '#/env'
const DISMISS_ANIMATION_DURATION = 200
@@ -210,7 +210,7 @@ export function AnimatedProfileHeaderSuggestedFollows({
* This issue stems from Android not allowing dragging on clickable elements in the profile header.
* Blocking the ability to scroll on Android is too much of a trade-off for now.
**/
if (isAndroid) return null
if (IS_ANDROID) return null
return (
<AccordionAnimation isExpanded={isExpanded}>
+2 -2
View File
@@ -17,7 +17,6 @@ import {
import {useIsFocused} from '@react-navigation/native'
import {sanitizeHandle} from '#/lib/strings/handles'
import {isNative} from '#/platform/detection'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useSetLightStatusBar} from '#/state/shell/light-status-bar'
@@ -26,6 +25,7 @@ import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
import {atoms as a, useTheme} from '#/alf'
import {Header} from '#/components/Layout'
import * as ProfileCard from '#/components/ProfileCard'
import {IS_NATIVE} from '#/env'
import {
HeaderLabelerButtons,
ProfileHeaderLabeler,
@@ -83,7 +83,7 @@ let ProfileHeader = ({setMinimumHeight, ...props}: Props): React.ReactNode => {
return (
<>
{isNative && (
{IS_NATIVE && (
<MinimalHeader
onLayout={evt => setMinimumHeight(evt.nativeEvent.layout.height)}
profile={props.profile}
+3 -3
View File
@@ -17,7 +17,6 @@ import {type CommonNavigatorParams} from '#/lib/routes/types'
import {type NavigationProp} from '#/lib/routes/types'
import {makeRecordUri} from '#/lib/strings/url-helpers'
import {s} from '#/lib/styles'
import {isNative} from '#/platform/detection'
import {listenSoftReset} from '#/state/events'
import {FeedFeedbackProvider, useFeedFeedback} from '#/state/feed-feedback'
import {
@@ -47,6 +46,7 @@ import {
} from '#/screens/Profile/components/ProfileFeedHeader'
import {HashtagWide_Stroke1_Corner0_Rounded as HashtagWideIcon} from '#/components/icons/Hashtag'
import * as Layout from '#/components/Layout'
import {IS_NATIVE} from '#/env'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFeed'>
export function ProfileFeedScreen(props: Props) {
@@ -175,7 +175,7 @@ export function ProfileFeedScreenInner({
const onScrollToTop = useCallback(() => {
scrollElRef.current?.scrollToOffset({
animated: isNative,
animated: IS_NATIVE,
offset: 0, // -headerHeight,
})
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
@@ -204,7 +204,7 @@ export function ProfileFeedScreenInner({
const feedIsVideoMode =
feedInfo.contentMode === AppBskyFeedDefs.CONTENTMODEVIDEO
const _isVideoFeed = isBskyVideoFeed || feedIsVideoMode
return isNative && _isVideoFeed
return IS_NATIVE && _isVideoFeed
}, [feedInfo])
return (
+4 -4
View File
@@ -5,7 +5,6 @@ import {useLingui} from '@lingui/react'
import {useQueryClient} from '@tanstack/react-query'
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
import {isIOS, isNative} from '#/platform/detection'
import {
type FeedDescriptor,
RQKEY as FEED_RQKEY,
@@ -21,6 +20,7 @@ import {LoadLatestBtn} from '#/view/com/util/load-latest/LoadLatestBtn'
import {atoms as a, ios, useTheme} from '#/alf'
import {EditBig_Stroke1_Corner0_Rounded as EditIcon} from '#/components/icons/EditBig'
import {Text} from '#/components/Typography'
import {IS_IOS, IS_NATIVE} from '#/env'
import {type SectionRef} from './types'
interface FeedSectionProps {
@@ -53,13 +53,13 @@ export function ProfileFeedSection({
const [hasNew, setHasNew] = useState(false)
const [isScrolledDown, setIsScrolledDown] = useState(false)
const shouldUseAdjustedNumToRender = feed.endsWith('posts_and_author_threads')
const isVideoFeed = isNative && feed.endsWith('posts_with_video')
const isVideoFeed = IS_NATIVE && feed.endsWith('posts_with_video')
const adjustedInitialNumToRender = useInitialNumToRender({
screenHeightOffset: headerHeight,
})
const onScrollToTop = useCallback(() => {
scrollElRef.current?.scrollToOffset({
animated: isNative,
animated: IS_NATIVE,
offset: -headerHeight,
})
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
@@ -85,7 +85,7 @@ export function ProfileFeedSection({
}, [_, emptyStateButton, emptyStateIcon, emptyStateMessage])
useEffect(() => {
if (isIOS && isFocused && scrollElRef.current) {
if (IS_IOS && isFocused && scrollElRef.current) {
const nativeTag = findNodeHandle(scrollElRef.current)
setScrollViewTag(nativeTag)
}
+3 -3
View File
@@ -10,7 +10,6 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {isLabelerSubscribed, lookupLabelValueDefinition} from '#/lib/moderation'
import {isIOS, isNative} from '#/platform/detection'
import {List, type ListRef} from '#/view/com/util/List'
import {atoms as a, ios, tokens, useTheme} from '#/alf'
import {Divider} from '#/components/Divider'
@@ -19,6 +18,7 @@ import {ListFooter} from '#/components/Lists'
import {Loader} from '#/components/Loader'
import {LabelerLabelPreference} from '#/components/moderation/LabelPreference'
import {Text} from '#/components/Typography'
import {IS_IOS, IS_NATIVE} from '#/env'
import {ErrorState} from '../ErrorState'
import {type SectionRef} from './types'
@@ -49,7 +49,7 @@ export function ProfileLabelsSection({
const onScrollToTop = useCallback(() => {
scrollElRef.current?.scrollToOffset({
animated: isNative,
animated: IS_NATIVE,
offset: -headerHeight,
})
}, [scrollElRef, headerHeight])
@@ -59,7 +59,7 @@ export function ProfileLabelsSection({
}))
useEffect(() => {
if (isIOS && isFocused && scrollElRef.current) {
if (IS_IOS && isFocused && scrollElRef.current) {
const nativeTag = findNodeHandle(scrollElRef.current)
setScrollViewTag(nativeTag)
}
@@ -11,7 +11,6 @@ import {shareUrl} from '#/lib/sharing'
import {sanitizeHandle} from '#/lib/strings/handles'
import {toShareUrl} from '#/lib/strings/url-helpers'
import {logger} from '#/logger'
import {isWeb} from '#/platform/detection'
import {type FeedSourceFeedInfo} from '#/state/queries/feed'
import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
import {
@@ -52,6 +51,7 @@ import {
} from '#/components/moderation/ReportDialog'
import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography'
import {IS_WEB} from '#/env'
export function ProfileFeedHeaderSkeleton() {
const t = useTheme()
@@ -192,7 +192,7 @@ export function ProfileFeedHeader({info}: {info: FeedSourceFeedInfo}) {
style={[
a.justify_start,
{
paddingVertical: isWeb ? 2 : 4,
paddingVertical: IS_WEB ? 2 : 4,
paddingRight: 8,
},
]}
@@ -211,7 +211,7 @@ export function ProfileFeedHeader({info}: {info: FeedSourceFeedInfo}) {
t.atoms.bg_contrast_25,
{
opacity: 0,
left: isWeb ? -2 : -4,
left: IS_WEB ? -2 : -4,
right: 0,
},
pressed && {