Move /platform/detection vars into /env (#9707)
* Add platform vars to env * Replace /platform/detection with /env
This commit is contained in:
@@ -439,9 +439,9 @@ Example from Dialog:
|
||||
|
||||
Platform detection:
|
||||
```tsx
|
||||
import {isWeb, isNative, isIOS, isAndroid} from '#/platform/detection'
|
||||
import {IS_WEB, IS_NATIVE, IS_IOS, IS_ANDROID} from '#/env'
|
||||
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
// Native-specific logic
|
||||
}
|
||||
```
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {requireNativeModule, requireNativeViewManager} from 'expo-modules-core'
|
||||
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {IS_IOS} from '#/env'
|
||||
import {
|
||||
type BottomSheetState,
|
||||
type BottomSheetViewProps,
|
||||
@@ -30,7 +30,7 @@ const NativeView: React.ComponentType<
|
||||
|
||||
const NativeModule = requireNativeModule('BottomSheet')
|
||||
|
||||
const isIOS15 =
|
||||
const IS_IOS15 =
|
||||
Platform.OS === 'ios' &&
|
||||
// semvar - can be 3 segments, so can't use Number(Platform.Version)
|
||||
Number(Platform.Version.split('.').at(0)) < 16
|
||||
@@ -91,7 +91,7 @@ export class BottomSheetNativeComponent extends React.Component<
|
||||
}
|
||||
|
||||
let extraStyles
|
||||
if (isIOS15 && this.state.viewHeight) {
|
||||
if (IS_IOS15 && this.state.viewHeight) {
|
||||
const {viewHeight} = this.state
|
||||
const cornerRadius = this.props.cornerRadius ?? 0
|
||||
if (viewHeight < screenHeight / 2) {
|
||||
@@ -112,7 +112,7 @@ export class BottomSheetNativeComponent extends React.Component<
|
||||
onStateChange={this.onStateChange}
|
||||
extraStyles={extraStyles}
|
||||
onLayout={e => {
|
||||
if (isIOS15) {
|
||||
if (IS_IOS15) {
|
||||
const {height} = e.nativeEvent.layout
|
||||
this.setState({viewHeight: height})
|
||||
}
|
||||
@@ -153,7 +153,7 @@ function BottomSheetNativeComponentInner({
|
||||
const insets = useSafeAreaInsets()
|
||||
const cornerRadius = rest.cornerRadius ?? 0
|
||||
|
||||
const sheetHeight = isIOS ? screenHeight - insets.top : screenHeight
|
||||
const sheetHeight = IS_IOS ? screenHeight - insets.top : screenHeight
|
||||
|
||||
return (
|
||||
<NativeView
|
||||
|
||||
+3
-3
@@ -23,7 +23,6 @@ import {s} from '#/lib/styles'
|
||||
import {ThemeProvider} from '#/lib/ThemeContext'
|
||||
import I18nProvider from '#/locale/i18nProvider'
|
||||
import {logger} from '#/logger'
|
||||
import {isAndroid, isIOS} from '#/platform/detection'
|
||||
import {Provider as A11yProvider} from '#/state/a11y'
|
||||
import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes'
|
||||
import {Provider as DialogStateProvider} from '#/state/dialogs'
|
||||
@@ -69,6 +68,7 @@ import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbe
|
||||
import {ToastOutlet} from '#/components/Toast'
|
||||
import {Provider as AgeAssuranceV2Provider} from '#/ageAssurance'
|
||||
import {prefetchAgeAssuranceConfig} from '#/ageAssurance'
|
||||
import {IS_ANDROID, IS_IOS} from '#/env'
|
||||
import {
|
||||
prefetchLiveEvents,
|
||||
Provider as LiveEventsProvider,
|
||||
@@ -79,10 +79,10 @@ import {BottomSheetProvider} from '../modules/bottom-sheet'
|
||||
import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
|
||||
|
||||
SplashScreen.preventAutoHideAsync()
|
||||
if (isIOS) {
|
||||
if (IS_IOS) {
|
||||
SystemUI.setBackgroundColorAsync('black')
|
||||
}
|
||||
if (isAndroid) {
|
||||
if (IS_ANDROID) {
|
||||
// iOS is handled by the config plugin -sfn
|
||||
ScreenOrientation.lockAsync(
|
||||
ScreenOrientation.OrientationLock.PORTRAIT_UP,
|
||||
|
||||
+6
-6
@@ -44,7 +44,6 @@ import {type RouteParams, type State} from '#/lib/routes/types'
|
||||
import {attachRouteToLogEvents, logEvent} from '#/lib/statsig/statsig'
|
||||
import {bskyTitle} from '#/lib/strings/headings'
|
||||
import {logger} from '#/logger'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {useUnreadNotifications} from '#/state/queries/notifications/unread'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||
@@ -138,6 +137,7 @@ import {
|
||||
EmailDialogScreenID,
|
||||
useEmailDialogControl,
|
||||
} from '#/components/dialogs/EmailDialog'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
import {router} from '#/routes'
|
||||
import {Referrer} from '../modules/expo-bluesky-swiss-army'
|
||||
|
||||
@@ -842,11 +842,11 @@ const LINKING = {
|
||||
// native, since the home tab and the home screen are defined as initial routes, we don't need to return a state
|
||||
// since it will be created by react-navigation.
|
||||
if (path.includes('intent/')) {
|
||||
if (isNative) return
|
||||
if (IS_NATIVE) return
|
||||
return buildStateObject('Flat', 'Home', params)
|
||||
}
|
||||
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
if (name === 'Search') {
|
||||
return buildStateObject('SearchTab', 'Search', params)
|
||||
}
|
||||
@@ -921,7 +921,7 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) {
|
||||
)
|
||||
|
||||
async function handlePushNotificationEntry() {
|
||||
if (!isNative) return
|
||||
if (!IS_NATIVE) return
|
||||
|
||||
// deep links take precedence - on android,
|
||||
// getLastNotificationResponseAsync returns a "notification"
|
||||
@@ -1069,7 +1069,7 @@ function reset(): Promise<void> {
|
||||
navigationRef.dispatch(
|
||||
CommonActions.reset({
|
||||
index: 0,
|
||||
routes: [{name: isNative ? 'HomeTab' : 'Home'}],
|
||||
routes: [{name: IS_NATIVE ? 'HomeTab' : 'Home'}],
|
||||
}),
|
||||
)
|
||||
return Promise.race([
|
||||
@@ -1103,7 +1103,7 @@ function logModuleInitTime() {
|
||||
initMs,
|
||||
})
|
||||
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
const referrerInfo = Referrer.getReferrerInfo()
|
||||
if (referrerInfo && referrerInfo.hostname !== 'bsky.app') {
|
||||
logEvent('deepLink:referrerReceived', {
|
||||
|
||||
@@ -10,8 +10,6 @@ import {
|
||||
} from '#/lib/hooks/useCreateSupportLink'
|
||||
import {dateDiff, useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useIsBirthdateUpdateAllowed} from '#/state/birthdate'
|
||||
import {useSessionApi} from '#/state/session'
|
||||
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
||||
@@ -38,6 +36,8 @@ import {
|
||||
isLegacyBirthdateBug,
|
||||
useAgeAssuranceRegionConfig,
|
||||
} from '#/ageAssurance/util'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {useDeviceGeolocationApi} from '#/geolocation'
|
||||
|
||||
const textStyles = [a.text_md, a.leading_snug]
|
||||
@@ -74,7 +74,7 @@ export function NoAccessScreen() {
|
||||
}, [])
|
||||
|
||||
const onPressLogout = useCallback(() => {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
// We're switching accounts, which remounts the entire app.
|
||||
// On mobile, this gets us Home, but on the web we also need reset the URL.
|
||||
// We can't change the URL via a navigate() call because the navigator
|
||||
@@ -139,7 +139,7 @@ export function NoAccessScreen() {
|
||||
contentContainerStyle={[
|
||||
a.px_2xl,
|
||||
{
|
||||
paddingTop: isWeb
|
||||
paddingTop: IS_WEB
|
||||
? a.p_5xl.padding
|
||||
: insets.top + a.p_2xl.padding,
|
||||
paddingBottom: 100,
|
||||
@@ -359,7 +359,7 @@ function AccessSection() {
|
||||
)}
|
||||
|
||||
<View style={[a.gap_xs]}>
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<>
|
||||
<Admonition>
|
||||
<Trans>
|
||||
|
||||
@@ -15,8 +15,6 @@ import {useLingui} from '@lingui/react'
|
||||
import {retry} from '#/lib/async/retry'
|
||||
import {wait} from '#/lib/async/wait'
|
||||
import {parseLinkingUrl} from '#/lib/parseLinkingUrl'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {atoms as a, platform, useBreakpoints, useTheme} from '#/alf'
|
||||
import {AgeAssuranceBadge} from '#/components/ageAssurance/AgeAssuranceBadge'
|
||||
@@ -28,6 +26,8 @@ import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {refetchAgeAssuranceServerState} from '#/ageAssurance'
|
||||
import {logger} from '#/ageAssurance'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {IS_IOS} from '#/env'
|
||||
|
||||
export type RedirectOverlayState = {
|
||||
result: 'success' | 'unknown'
|
||||
@@ -92,7 +92,7 @@ export function Provider({children}: {children?: React.ReactNode}) {
|
||||
actorDid: params.get('actorDid') ?? undefined,
|
||||
})
|
||||
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
// Clear the URL parameters so they don't re-trigger
|
||||
history.pushState(null, '', '/')
|
||||
}
|
||||
@@ -145,7 +145,7 @@ export function RedirectOverlay() {
|
||||
// setting a zIndex when using FullWindowOverlay on iOS
|
||||
// means the taps pass straight through to the underlying content (???)
|
||||
// so don't set it on iOS. FullWindowOverlay already does the job.
|
||||
!isIOS && {zIndex: 9999},
|
||||
!IS_IOS && {zIndex: 9999},
|
||||
t.atoms.bg,
|
||||
gtMobile ? a.p_2xl : a.p_xl,
|
||||
a.align_center,
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
import {type TextStyle} from 'react-native'
|
||||
|
||||
import {isAndroid, isWeb} from '#/platform/detection'
|
||||
import {IS_ANDROID, IS_WEB} from '#/env'
|
||||
import {type Device, device} from '#/storage'
|
||||
|
||||
const WEB_FONT_FAMILIES = `system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"`
|
||||
@@ -39,7 +39,7 @@ export function setFontFamily(fontFamily: Device['fontFamily']) {
|
||||
*/
|
||||
export function applyFonts(style: TextStyle, fontFamily: 'system' | 'theme') {
|
||||
if (fontFamily === 'theme') {
|
||||
if (isAndroid) {
|
||||
if (IS_ANDROID) {
|
||||
style.fontFamily =
|
||||
{
|
||||
400: 'Inter-Regular',
|
||||
@@ -71,7 +71,7 @@ export function applyFonts(style: TextStyle, fontFamily: 'system' | 'theme') {
|
||||
}
|
||||
}
|
||||
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
// fallback families only supported on web
|
||||
style.fontFamily += `, ${WEB_FONT_FAMILIES}`
|
||||
}
|
||||
@@ -83,7 +83,7 @@ export function applyFonts(style: TextStyle, fontFamily: 'system' | 'theme') {
|
||||
style.fontVariant = (style.fontVariant || []).concat('no-contextual')
|
||||
} else {
|
||||
// fallback families only supported on web
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
style.fontFamily = style.fontFamily || WEB_FONT_FAMILIES
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ import {type StyleProp, type TextStyle} from 'react-native'
|
||||
import {UITextView} from 'react-native-uitextview'
|
||||
import createEmojiRegex from 'emoji-regex'
|
||||
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {type Alf, applyFonts, atoms, flatten} from '#/alf'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {IS_IOS} from '#/env'
|
||||
|
||||
/**
|
||||
* Ensures that `lineHeight` defaults to a relative value of `1`, or applies
|
||||
@@ -34,7 +34,7 @@ export function normalizeTextStyles(
|
||||
if (s.lineHeight !== 0 && s.lineHeight <= 2) {
|
||||
s.lineHeight = Math.round(s.fontSize * s.lineHeight)
|
||||
}
|
||||
} else if (!isNative) {
|
||||
} else if (!IS_NATIVE) {
|
||||
s.lineHeight = s.fontSize
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ export function renderChildrenWithEmoji(
|
||||
props: Omit<TextProps, 'children'> = {},
|
||||
emoji: boolean,
|
||||
) {
|
||||
if (!isIOS || !emoji) {
|
||||
if (!IS_IOS || !emoji) {
|
||||
return children
|
||||
}
|
||||
return Children.map(children, child => {
|
||||
|
||||
@@ -2,10 +2,10 @@ import * as SystemUI from 'expo-system-ui'
|
||||
import {type Theme} from '@bsky.app/alf'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
import {isAndroid} from '#/platform/detection'
|
||||
import {IS_ANDROID} from '#/env'
|
||||
|
||||
export function setSystemUITheme(themeType: 'theme' | 'lightbox', t: Theme) {
|
||||
if (isAndroid) {
|
||||
if (IS_ANDROID) {
|
||||
try {
|
||||
if (themeType === 'theme') {
|
||||
SystemUI.setBackgroundColorAsync(t.atoms.bg.backgroundColor)
|
||||
|
||||
@@ -2,9 +2,9 @@ import React from 'react'
|
||||
import {type ColorSchemeName, useColorScheme} from 'react-native'
|
||||
import {type ThemeName} from '@bsky.app/alf'
|
||||
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useThemePrefs} from '#/state/shell'
|
||||
import {dark, dim, light} from '#/alf/themes'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
export function useColorModeTheme(): ThemeName {
|
||||
const theme = useThemeName()
|
||||
@@ -40,7 +40,7 @@ function getThemeName(
|
||||
|
||||
function updateDocument(theme: ThemeName) {
|
||||
// @ts-ignore web only
|
||||
if (isWeb && typeof window !== 'undefined') {
|
||||
if (IS_WEB && typeof window !== 'undefined') {
|
||||
// @ts-ignore web only
|
||||
const html = window.document.documentElement
|
||||
// @ts-ignore web only
|
||||
|
||||
@@ -49,7 +49,6 @@ import {HITSLOP_10} from '#/lib/constants'
|
||||
import {useHaptics} from '#/lib/haptics'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {logger} from '#/logger'
|
||||
import {isAndroid, isIOS} from '#/platform/detection'
|
||||
import {atoms as a, platform, tokens, useTheme} from '#/alf'
|
||||
import {
|
||||
Context,
|
||||
@@ -71,6 +70,7 @@ import {
|
||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||
import {createPortalGroup} from '#/components/Portal'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_ANDROID, IS_IOS} from '#/env'
|
||||
import {Backdrop} from './Backdrop'
|
||||
|
||||
export {
|
||||
@@ -81,14 +81,14 @@ export {
|
||||
const {Provider: PortalProvider, Outlet, Portal} = createPortalGroup()
|
||||
|
||||
const SPRING_IN: WithSpringConfig = {
|
||||
mass: isIOS ? 1.25 : 0.75,
|
||||
mass: IS_IOS ? 1.25 : 0.75,
|
||||
damping: 50,
|
||||
stiffness: 1100,
|
||||
restDisplacementThreshold: 0.01,
|
||||
}
|
||||
|
||||
const SPRING_OUT: WithSpringConfig = {
|
||||
mass: isIOS ? 1.25 : 0.75,
|
||||
mass: IS_IOS ? 1.25 : 0.75,
|
||||
damping: 150,
|
||||
stiffness: 1000,
|
||||
restDisplacementThreshold: 0.01,
|
||||
@@ -209,7 +209,7 @@ export function Root({children}: {children: React.ReactNode}) {
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (isAndroid && context.isOpen) {
|
||||
if (IS_ANDROID && context.isOpen) {
|
||||
const listener = BackHandler.addEventListener('hardwareBackPress', () => {
|
||||
context.close()
|
||||
return true
|
||||
@@ -331,7 +331,7 @@ export function Trigger({children, label, contentLabel, style}: TriggerProps) {
|
||||
<GestureDetector gesture={composedGestures}>
|
||||
<View ref={ref} style={[{opacity: context.isOpen ? 0 : 1}, style]}>
|
||||
{children({
|
||||
isNative: true,
|
||||
IS_NATIVE: true,
|
||||
control: {isOpen: context.isOpen, open},
|
||||
state: {
|
||||
pressed: false,
|
||||
|
||||
@@ -85,7 +85,7 @@ export type TriggerProps = {
|
||||
}
|
||||
export type TriggerChildProps =
|
||||
| {
|
||||
isNative: true
|
||||
IS_NATIVE: true
|
||||
control: {
|
||||
isOpen: boolean
|
||||
open: (mode: 'full' | 'auxiliary-only') => void
|
||||
@@ -115,7 +115,7 @@ export type TriggerChildProps =
|
||||
}
|
||||
}
|
||||
| {
|
||||
isNative: false
|
||||
IS_NATIVE: false
|
||||
control: Dialog.DialogOuterProps['control']
|
||||
state: {
|
||||
hovered: false
|
||||
|
||||
@@ -18,7 +18,7 @@ import {BottomSheetSnapPoint} from '../../../modules/bottom-sheet/src/BottomShee
|
||||
|
||||
export const Context = createContext<DialogContextProps>({
|
||||
close: () => {},
|
||||
isNativeDialog: false,
|
||||
IS_NATIVEDialog: false,
|
||||
nativeSnapPoint: BottomSheetSnapPoint.Hidden,
|
||||
disableDrag: false,
|
||||
setDisableDrag: () => {},
|
||||
|
||||
@@ -26,7 +26,6 @@ import {useLingui} from '@lingui/react'
|
||||
import {useEnableKeyboardController} from '#/lib/hooks/useEnableKeyboardController'
|
||||
import {ScrollProvider} from '#/lib/ScrollContext'
|
||||
import {logger} from '#/logger'
|
||||
import {isAndroid, isIOS} from '#/platform/detection'
|
||||
import {useA11y} from '#/state/a11y'
|
||||
import {useDialogStateControlContext} from '#/state/dialogs'
|
||||
import {List, type ListMethods, type ListProps} from '#/view/com/util/List'
|
||||
@@ -39,6 +38,7 @@ import {
|
||||
type DialogOuterProps,
|
||||
} from '#/components/Dialog/types'
|
||||
import {createInput} from '#/components/forms/TextField'
|
||||
import {IS_ANDROID, IS_IOS} from '#/env'
|
||||
import {BottomSheet, BottomSheetSnapPoint} from '../../../modules/bottom-sheet'
|
||||
import {
|
||||
type BottomSheetSnapPointChangeEvent,
|
||||
@@ -154,7 +154,7 @@ export function Outer({
|
||||
const context = React.useMemo(
|
||||
() => ({
|
||||
close,
|
||||
isNativeDialog: true,
|
||||
IS_NATIVEDialog: true,
|
||||
nativeSnapPoint: snapPoint,
|
||||
disableDrag,
|
||||
setDisableDrag,
|
||||
@@ -209,7 +209,7 @@ export const ScrollableInner = React.forwardRef<ScrollView, DialogInnerProps>(
|
||||
const {nativeSnapPoint, disableDrag, setDisableDrag} = useDialogContext()
|
||||
const insets = useSafeAreaInsets()
|
||||
|
||||
useEnableKeyboardController(isIOS)
|
||||
useEnableKeyboardController(IS_IOS)
|
||||
|
||||
const [keyboardHeight, setKeyboardHeight] = React.useState(0)
|
||||
|
||||
@@ -224,7 +224,7 @@ export const ScrollableInner = React.forwardRef<ScrollView, DialogInnerProps>(
|
||||
)
|
||||
|
||||
let paddingBottom = 0
|
||||
if (isIOS) {
|
||||
if (IS_IOS) {
|
||||
paddingBottom += keyboardHeight / 4
|
||||
if (nativeSnapPoint === BottomSheetSnapPoint.Full) {
|
||||
paddingBottom += insets.bottom + tokens.space.md
|
||||
@@ -240,7 +240,7 @@ export const ScrollableInner = React.forwardRef<ScrollView, DialogInnerProps>(
|
||||
}
|
||||
|
||||
const onScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
||||
if (!isAndroid) {
|
||||
if (!IS_ANDROID) {
|
||||
return
|
||||
}
|
||||
const {contentOffset} = e.nativeEvent
|
||||
@@ -260,12 +260,12 @@ export const ScrollableInner = React.forwardRef<ScrollView, DialogInnerProps>(
|
||||
contentContainerStyle,
|
||||
]}
|
||||
ref={ref}
|
||||
showsVerticalScrollIndicator={isAndroid ? false : undefined}
|
||||
showsVerticalScrollIndicator={IS_ANDROID ? false : undefined}
|
||||
{...props}
|
||||
bounces={nativeSnapPoint === BottomSheetSnapPoint.Full}
|
||||
bottomOffset={30}
|
||||
scrollEventThrottle={50}
|
||||
onScroll={isAndroid ? onScroll : undefined}
|
||||
onScroll={IS_ANDROID ? onScroll : undefined}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
// TODO: figure out why this positions the header absolutely (rather than stickily)
|
||||
// on Android. fine to disable for now, because we don't have any
|
||||
@@ -289,11 +289,11 @@ export const InnerFlatList = React.forwardRef<
|
||||
const insets = useSafeAreaInsets()
|
||||
const {nativeSnapPoint, disableDrag, setDisableDrag} = useDialogContext()
|
||||
|
||||
useEnableKeyboardController(isIOS)
|
||||
useEnableKeyboardController(IS_IOS)
|
||||
|
||||
const onScroll = (e: ScrollEvent) => {
|
||||
'worklet'
|
||||
if (!isAndroid) {
|
||||
if (!IS_ANDROID) {
|
||||
return
|
||||
}
|
||||
const {contentOffset} = e
|
||||
@@ -311,7 +311,7 @@ export const InnerFlatList = React.forwardRef<
|
||||
bounces={nativeSnapPoint === BottomSheetSnapPoint.Full}
|
||||
ListFooterComponent={<View style={{height: insets.bottom + 100}} />}
|
||||
ref={ref}
|
||||
showsVerticalScrollIndicator={isAndroid ? false : undefined}
|
||||
showsVerticalScrollIndicator={IS_ANDROID ? false : undefined}
|
||||
{...props}
|
||||
style={[a.h_full, style]}
|
||||
/>
|
||||
@@ -326,7 +326,7 @@ export function FlatListFooter({children}: {children: React.ReactNode}) {
|
||||
const {height} = useReanimatedKeyboardAnimation()
|
||||
|
||||
const animatedStyle = useAnimatedStyle(() => {
|
||||
if (!isIOS) return {}
|
||||
if (!IS_IOS) return {}
|
||||
return {
|
||||
transform: [{translateY: Math.min(0, height.get() + bottom - 10)}],
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ export function Outer({
|
||||
const context = React.useMemo(
|
||||
() => ({
|
||||
close,
|
||||
isNativeDialog: false,
|
||||
IS_NATIVEDialog: false,
|
||||
nativeSnapPoint: 0,
|
||||
disableDrag: false,
|
||||
setDisableDrag: () => {},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {useCallback} from 'react'
|
||||
import {SystemBars} from 'react-native-edge-to-edge'
|
||||
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {IS_IOS} from '#/env'
|
||||
|
||||
/**
|
||||
* If we're calling a system API like the image picker that opens a sheet
|
||||
@@ -9,7 +9,7 @@ import {isIOS} from '#/platform/detection'
|
||||
*/
|
||||
export function useSheetWrapper() {
|
||||
return useCallback(async <T>(promise: Promise<T>): Promise<T> => {
|
||||
if (isIOS) {
|
||||
if (IS_IOS) {
|
||||
const entry = SystemBars.pushStackEntry({
|
||||
style: {
|
||||
statusBar: 'light',
|
||||
|
||||
@@ -39,7 +39,7 @@ export type DialogControlProps = DialogControlRefProps & {
|
||||
|
||||
export type DialogContextProps = {
|
||||
close: DialogControlProps['close']
|
||||
isNativeDialog: boolean
|
||||
IS_NATIVEDialog: boolean
|
||||
nativeSnapPoint: BottomSheetSnapPoint
|
||||
disableDrag: boolean
|
||||
setDisableDrag: React.Dispatch<React.SetStateAction<boolean>>
|
||||
|
||||
@@ -10,7 +10,6 @@ import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {logEvent, useGate} from '#/lib/statsig/statsig'
|
||||
import {logger} from '#/logger'
|
||||
import {type MetricEvents} from '#/logger/metrics'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {useGetPopularFeedsQuery} from '#/state/queries/feed'
|
||||
import {type FeedDescriptor} from '#/state/queries/post-feed'
|
||||
@@ -39,6 +38,7 @@ import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import * as ProfileCard from '#/components/ProfileCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_IOS} from '#/env'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import {FollowDialogWithoutGuide} from './ProgressGuide/FollowDialog'
|
||||
import {ProgressGuideList} from './ProgressGuide/List'
|
||||
@@ -692,7 +692,7 @@ export function ProfileGrid({
|
||||
t.atoms.border_contrast_low,
|
||||
t.atoms.bg_contrast_25,
|
||||
]}
|
||||
pointerEvents={isIOS ? 'auto' : 'box-none'}>
|
||||
pointerEvents={IS_IOS ? 'auto' : 'box-none'}>
|
||||
<View
|
||||
style={[
|
||||
a.px_lg,
|
||||
@@ -701,7 +701,7 @@ export function ProfileGrid({
|
||||
a.align_center,
|
||||
a.justify_between,
|
||||
]}
|
||||
pointerEvents={isIOS ? 'auto' : 'box-none'}>
|
||||
pointerEvents={IS_IOS ? 'auto' : 'box-none'}>
|
||||
<Text style={[a.text_sm, a.font_semi_bold, t.atoms.text]}>
|
||||
{isFeedContext ? (
|
||||
<Trans>Suggested for you</Trans>
|
||||
|
||||
@@ -9,7 +9,6 @@ import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {DraggableScrollView} from '#/view/com/pager/DraggableScrollView'
|
||||
import {atoms as a, tokens, useTheme, web} from '#/alf'
|
||||
import {transparentifyColor} from '#/alf/util/colorGeneration'
|
||||
@@ -19,6 +18,7 @@ import {
|
||||
ArrowRight_Stroke2_Corner0_Rounded as ArrowRight,
|
||||
} from '#/components/icons/Arrow'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
/**
|
||||
* Tab component that automatically scrolls the selected tab into view - used for interests
|
||||
@@ -236,7 +236,7 @@ export function InterestTabs({
|
||||
)
|
||||
})}
|
||||
</DraggableScrollView>
|
||||
{isWeb && canScrollLeft && (
|
||||
{IS_WEB && canScrollLeft && (
|
||||
<View
|
||||
style={[
|
||||
a.absolute,
|
||||
@@ -270,7 +270,7 @@ export function InterestTabs({
|
||||
</Button>
|
||||
</View>
|
||||
)}
|
||||
{isWeb && canScrollRight && (
|
||||
{IS_WEB && canScrollRight && (
|
||||
<View
|
||||
style={[
|
||||
a.absolute,
|
||||
|
||||
@@ -10,9 +10,9 @@ import {
|
||||
INTERNATIONAL_TELEPHONE_CODES,
|
||||
} from '#/lib/international-telephone-codes'
|
||||
import {regionName} from '#/locale/helpers'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a, web} from '#/alf'
|
||||
import * as Select from '#/components/Select'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {useGeolocation} from '#/geolocation'
|
||||
|
||||
/**
|
||||
@@ -84,7 +84,7 @@ export function InternationalPhoneCodeSelect({
|
||||
<Select.Item value={item.value} label={item.label}>
|
||||
<Select.ItemIndicator />
|
||||
<Select.ItemText style={[a.flex_1]} emoji>
|
||||
{isWeb ? <Flag {...item} /> : item.unicodeFlag + ' '}
|
||||
{IS_WEB ? <Flag {...item} /> : item.unicodeFlag + ' '}
|
||||
{item.name}
|
||||
</Select.ItemText>
|
||||
<Select.ItemText style={[a.text_right]}>
|
||||
@@ -101,7 +101,7 @@ export function InternationalPhoneCodeSelect({
|
||||
}
|
||||
|
||||
function Flag({unicodeFlag, svgFlag}: {unicodeFlag: string; svgFlag: any}) {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
return (
|
||||
<Image
|
||||
source={svgFlag}
|
||||
|
||||
@@ -6,7 +6,6 @@ import {useNavigation} from '@react-navigation/native'
|
||||
|
||||
import {HITSLOP_30} from '#/lib/constants'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {useSetDrawerOpen} from '#/state/shell'
|
||||
import {
|
||||
atoms as a,
|
||||
@@ -29,6 +28,7 @@ import {
|
||||
} from '#/components/Layout/const'
|
||||
import {ScrollbarOffsetContext} from '#/components/Layout/context'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_IOS} from '#/env'
|
||||
|
||||
export function Outer({
|
||||
children,
|
||||
@@ -91,7 +91,7 @@ export function Content({
|
||||
style={[
|
||||
a.flex_1,
|
||||
a.justify_center,
|
||||
isIOS && align === 'platform' && a.align_center,
|
||||
IS_IOS && align === 'platform' && a.align_center,
|
||||
{minHeight: HEADER_SLOT_SIZE},
|
||||
]}>
|
||||
<AlignmentContext.Provider value={align}>
|
||||
@@ -186,7 +186,7 @@ export function TitleText({
|
||||
a.text_lg,
|
||||
a.font_semi_bold,
|
||||
a.leading_tight,
|
||||
isIOS && align === 'platform' && a.text_center,
|
||||
IS_IOS && align === 'platform' && a.text_center,
|
||||
gtMobile && a.text_xl,
|
||||
style,
|
||||
]}
|
||||
@@ -205,7 +205,7 @@ export function SubtitleText({children}: {children: React.ReactNode}) {
|
||||
style={[
|
||||
a.text_sm,
|
||||
a.leading_snug,
|
||||
isIOS && align === 'platform' && a.text_center,
|
||||
IS_IOS && align === 'platform' && a.text_center,
|
||||
t.atoms.text_contrast_medium,
|
||||
]}
|
||||
numberOfLines={2}>
|
||||
|
||||
@@ -11,7 +11,6 @@ import Animated, {
|
||||
} from 'react-native-reanimated'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useShellLayout} from '#/state/shell/shell-layout'
|
||||
import {
|
||||
atoms as a,
|
||||
@@ -23,6 +22,7 @@ import {
|
||||
import {useDialogContext} from '#/components/Dialog'
|
||||
import {CENTER_COLUMN_OFFSET, SCROLLBAR_OFFSET} from '#/components/Layout/const'
|
||||
import {ScrollbarOffsetContext} from '#/components/Layout/context'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
export * from '#/components/Layout/const'
|
||||
export * as Header from '#/components/Layout/Header'
|
||||
@@ -43,7 +43,7 @@ export const Screen = memo(function Screen({
|
||||
const {top} = useSafeAreaInsets()
|
||||
return (
|
||||
<>
|
||||
{isWeb && <WebCenterBorders />}
|
||||
{IS_WEB && <WebCenterBorders />}
|
||||
<View
|
||||
style={[a.util_screen_outer, {paddingTop: noInsetTop ? 0 : top}, style]}
|
||||
{...props}
|
||||
@@ -98,7 +98,7 @@ export const Content = memo(
|
||||
contentContainerStyle,
|
||||
]}
|
||||
{...props}>
|
||||
{isWeb ? (
|
||||
{IS_WEB ? (
|
||||
<Center ignoreTabletLayoutOffset={ignoreTabletLayoutOffset}>
|
||||
{/* @ts-expect-error web only -esb */}
|
||||
{children}
|
||||
@@ -145,7 +145,7 @@ export const KeyboardAwareContent = memo(function LayoutKeyboardAwareContent({
|
||||
]}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
{...props}>
|
||||
{isWeb ? <Center>{children}</Center> : children}
|
||||
{IS_WEB ? <Center>{children}</Center> : children}
|
||||
</KeyboardAwareScrollView>
|
||||
)
|
||||
})
|
||||
|
||||
+11
-11
@@ -18,12 +18,12 @@ import {
|
||||
isExternalUrl,
|
||||
linkRequiresWarning,
|
||||
} from '#/lib/strings/url-helpers'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {atoms as a, flatten, type TextStyleProp, useTheme, web} from '#/alf'
|
||||
import {Button, type ButtonProps} from '#/components/Button'
|
||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||
import {Text, type TextProps} from '#/components/Typography'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
import {router} from '#/routes'
|
||||
import {useGlobalDialogsControlContext} from './dialogs/Context'
|
||||
|
||||
@@ -130,7 +130,7 @@ export function useLink({
|
||||
linkRequiresWarning(href, displayText),
|
||||
)
|
||||
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ export function useLink({
|
||||
]
|
||||
|
||||
// does not apply to web's flat navigator
|
||||
if (isNative && screen !== 'NotFound') {
|
||||
if (IS_NATIVE && screen !== 'NotFound') {
|
||||
const state = navigation.getState()
|
||||
// if screen is not in the current navigator, it means it's
|
||||
// most likely a tab screen. note: state can be undefined
|
||||
@@ -246,7 +246,7 @@ export function useLink({
|
||||
(e: GestureResponderEvent) => {
|
||||
const exitEarlyIfFalse = outerOnLongPress?.(e)
|
||||
if (exitEarlyIfFalse === false) return
|
||||
return isNative && shareOnLongPress ? handleLongPress() : undefined
|
||||
return IS_NATIVE && shareOnLongPress ? handleLongPress() : undefined
|
||||
},
|
||||
[outerOnLongPress, handleLongPress, shareOnLongPress],
|
||||
)
|
||||
@@ -501,7 +501,7 @@ export function WebOnlyInlineLinkText({
|
||||
onPress,
|
||||
...props
|
||||
}: Omit<InlineLinkProps, 'onLongPress'>) {
|
||||
return isWeb ? (
|
||||
return IS_WEB ? (
|
||||
<InlineLinkText {...props} to={to} onPress={onPress}>
|
||||
{children}
|
||||
</InlineLinkText>
|
||||
@@ -547,7 +547,7 @@ export function createStaticClickIfUnmodified(
|
||||
): {onPress: Exclude<BaseLinkProps['onPress'], undefined>} {
|
||||
return {
|
||||
onPress(e: GestureResponderEvent) {
|
||||
if (!isWeb || !isModifiedClickEvent(e)) {
|
||||
if (!IS_WEB || !isModifiedClickEvent(e)) {
|
||||
e.preventDefault()
|
||||
onPressHandler(e)
|
||||
return false
|
||||
@@ -561,7 +561,7 @@ export function createStaticClickIfUnmodified(
|
||||
* intends to deviate from default behavior.
|
||||
*/
|
||||
export function isClickEventWithMetaKey(e: GestureResponderEvent) {
|
||||
if (!isWeb) return false
|
||||
if (!IS_WEB) return false
|
||||
const event = e as unknown as MouseEvent
|
||||
return event.metaKey || event.altKey || event.ctrlKey || event.shiftKey
|
||||
}
|
||||
@@ -570,7 +570,7 @@ export function isClickEventWithMetaKey(e: GestureResponderEvent) {
|
||||
* Determines if the web click target is anything other than `_self`
|
||||
*/
|
||||
export function isClickTargetExternal(e: GestureResponderEvent) {
|
||||
if (!isWeb) return false
|
||||
if (!IS_WEB) return false
|
||||
const event = e as unknown as MouseEvent
|
||||
const el = event.currentTarget as HTMLAnchorElement
|
||||
return el && el.target && el.target !== '_self'
|
||||
@@ -582,7 +582,7 @@ export function isClickTargetExternal(e: GestureResponderEvent) {
|
||||
* {@link https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button}
|
||||
*/
|
||||
export function isModifiedClickEvent(e: GestureResponderEvent): boolean {
|
||||
if (!isWeb) return false
|
||||
if (!IS_WEB) return false
|
||||
const event = e as unknown as MouseEvent
|
||||
const isPrimaryButton = event.button === 0
|
||||
return (
|
||||
@@ -596,8 +596,8 @@ export function isModifiedClickEvent(e: GestureResponderEvent): boolean {
|
||||
* {@link https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button}
|
||||
*/
|
||||
export function shouldClickOpenNewTab(e: GestureResponderEvent) {
|
||||
if (!isWeb) return false
|
||||
if (!IS_WEB) return false
|
||||
const event = e as unknown as MouseEvent
|
||||
const isMiddleClick = isWeb && event.button === 1
|
||||
const isMiddleClick = IS_WEB && event.button === 1
|
||||
return isClickEventWithMetaKey(e) || isClickTargetExternal(e) || isMiddleClick
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import flattenReactChildren from 'react-keyed-flatten-children'
|
||||
|
||||
import {isAndroid, isIOS, isNative} from '#/platform/detection'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
@@ -30,6 +29,7 @@ import {
|
||||
type TriggerProps,
|
||||
} from '#/components/Menu/types'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_ANDROID, IS_IOS, IS_NATIVE} from '#/env'
|
||||
|
||||
export {
|
||||
type DialogControlProps as MenuControlProps,
|
||||
@@ -70,7 +70,7 @@ export function Trigger({
|
||||
} = useInteractionState()
|
||||
|
||||
return children({
|
||||
isNative: true,
|
||||
IS_NATIVE: true,
|
||||
control: context.control,
|
||||
state: {
|
||||
hovered: false,
|
||||
@@ -111,7 +111,7 @@ export function Outer({
|
||||
<Dialog.ScrollableInner label={_(msg`Menu`)}>
|
||||
<View style={[a.gap_lg]}>
|
||||
{children}
|
||||
{isNative && showCancel && <Cancel />}
|
||||
{IS_NATIVE && showCancel && <Cancel />}
|
||||
</View>
|
||||
</Dialog.ScrollableInner>
|
||||
</Context.Provider>
|
||||
@@ -137,13 +137,13 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) {
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
onPress={async e => {
|
||||
if (isAndroid) {
|
||||
if (IS_ANDROID) {
|
||||
/**
|
||||
* Below fix for iOS doesn't work for Android, this does.
|
||||
*/
|
||||
onPress?.(e)
|
||||
context.control.close()
|
||||
} else if (isIOS) {
|
||||
} else if (IS_IOS) {
|
||||
/**
|
||||
* Fixes a subtle bug on iOS
|
||||
* {@link https://github.com/bluesky-social/social-app/pull/5849/files#diff-de516ef5e7bd9840cd639213301df38cf03acfcad5bda85a1d63efd249ba79deL124-L127}
|
||||
|
||||
@@ -138,7 +138,7 @@ export function Trigger({
|
||||
<RadixTriggerPassThrough>
|
||||
{props =>
|
||||
children({
|
||||
isNative: false,
|
||||
IS_NATIVE: false,
|
||||
control,
|
||||
state: {
|
||||
hovered,
|
||||
|
||||
@@ -43,7 +43,7 @@ export type TriggerProps = {
|
||||
}
|
||||
export type TriggerChildProps =
|
||||
| {
|
||||
isNative: true
|
||||
IS_NATIVE: true
|
||||
control: Dialog.DialogOuterProps['control']
|
||||
state: {
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ export type TriggerChildProps =
|
||||
}
|
||||
}
|
||||
| {
|
||||
isNative: false
|
||||
IS_NATIVE: false
|
||||
control: Dialog.DialogOuterProps['control']
|
||||
state: {
|
||||
hovered: boolean
|
||||
|
||||
@@ -8,7 +8,6 @@ import {differenceInSeconds} from 'date-fns'
|
||||
import {HITSLOP_10} from '#/lib/constants'
|
||||
import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {useSession} from '#/state/session'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
@@ -18,6 +17,7 @@ import {useDialogControl} from '#/components/Dialog'
|
||||
import {Newskie} from '#/components/icons/Newskie'
|
||||
import * as StarterPackCard from '#/components/StarterPack/StarterPackCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export function NewskieDialog({
|
||||
profile,
|
||||
@@ -162,7 +162,7 @@ function DialogInner({
|
||||
</StarterPackCard.Link>
|
||||
) : null}
|
||||
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
color="secondary"
|
||||
|
||||
@@ -7,11 +7,11 @@ import {
|
||||
import {LinearGradient} from 'expo-linear-gradient'
|
||||
import {utils} from '@bsky.app/alf'
|
||||
|
||||
import {isAndroid, isNative} from '#/platform/detection'
|
||||
import {useA11y} from '#/state/a11y'
|
||||
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
||||
import {FocusScope} from '#/components/FocusScope'
|
||||
import {LockScroll} from '#/components/LockScroll'
|
||||
import {IS_ANDROID, IS_NATIVE} from '#/env'
|
||||
|
||||
const GUTTER = 24
|
||||
|
||||
@@ -80,7 +80,7 @@ export function Overlay({
|
||||
a.z_20,
|
||||
a.align_center,
|
||||
!gtPhone && [a.justify_end, {minHeight: frame.height}],
|
||||
isNative && [
|
||||
IS_NATIVE && [
|
||||
{
|
||||
paddingBottom: Math.max(insets.bottom, a.p_2xl.padding),
|
||||
},
|
||||
@@ -109,7 +109,7 @@ export function Overlay({
|
||||
|
||||
<FocusScope>
|
||||
<View
|
||||
accessible={isAndroid}
|
||||
accessible={IS_ANDROID}
|
||||
role="dialog"
|
||||
aria-role="dialog"
|
||||
aria-label={label}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import {useEffect} from 'react'
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {FullWindowOverlay} from '#/components/FullWindowOverlay'
|
||||
import {usePolicyUpdateContext} from '#/components/PolicyUpdateOverlay/context'
|
||||
import {Portal} from '#/components/PolicyUpdateOverlay/Portal'
|
||||
import {Content} from '#/components/PolicyUpdateOverlay/updates/202508'
|
||||
import {IS_IOS} from '#/env'
|
||||
|
||||
export {Provider} from '#/components/PolicyUpdateOverlay/context'
|
||||
export {usePolicyUpdateContext} from '#/components/PolicyUpdateOverlay/context'
|
||||
@@ -39,7 +39,7 @@ export function PolicyUpdateOverlay() {
|
||||
// setting a zIndex when using FullWindowOverlay on iOS
|
||||
// means the taps pass straight through to the underlying content (???)
|
||||
// so don't set it on iOS. FullWindowOverlay already does the job.
|
||||
!isIOS && {zIndex: 9999},
|
||||
!IS_IOS && {zIndex: 9999},
|
||||
]}>
|
||||
<Content state={state} />
|
||||
</View>
|
||||
|
||||
@@ -3,7 +3,6 @@ import {View} from 'react-native'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {isAndroid} from '#/platform/detection'
|
||||
import {useA11y} from '#/state/a11y'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
@@ -12,6 +11,7 @@ import {Badge} from '#/components/PolicyUpdateOverlay/Badge'
|
||||
import {Overlay} from '#/components/PolicyUpdateOverlay/Overlay'
|
||||
import {type PolicyUpdateState} from '#/components/PolicyUpdateOverlay/usePolicyUpdateState'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_ANDROID} from '#/env'
|
||||
|
||||
export function Content({state}: {state: PolicyUpdateState}) {
|
||||
const t = useTheme()
|
||||
@@ -56,7 +56,7 @@ export function Content({state}: {state: PolicyUpdateState}) {
|
||||
size: 'small',
|
||||
} as const
|
||||
|
||||
const label = isAndroid
|
||||
const label = IS_ANDROID
|
||||
? _(
|
||||
msg`We’re updating our Terms of Service, Privacy Policy, and Copyright Policy, effective September 15th, 2025. We're also updating our Community Guidelines, and we want your input! These new guidelines will take effect on October 15th, 2025. Learn more about these changes and how to share your thoughts with us by reading our blog post.`,
|
||||
)
|
||||
|
||||
@@ -10,13 +10,13 @@ import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {type EmbedPlayerParams} from '#/lib/strings/embed-player'
|
||||
import {isIOS, isNative, isWeb} from '#/platform/detection'
|
||||
import {useExternalEmbedsPrefs} from '#/state/preferences'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {useDialogControl} from '#/components/Dialog'
|
||||
import {EmbedConsentDialog} from '#/components/dialogs/EmbedConsent'
|
||||
import {Fill} from '#/components/Fill'
|
||||
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
|
||||
import {IS_IOS, IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
export function ExternalGif({
|
||||
link,
|
||||
@@ -66,12 +66,12 @@ export function ExternalGif({
|
||||
// Control animation on native
|
||||
setIsAnimating(prev => {
|
||||
if (prev) {
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
imageRef.current?.stopAnimating()
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
imageRef.current?.startAnimating()
|
||||
}
|
||||
return true
|
||||
@@ -112,7 +112,7 @@ export function ExternalGif({
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
!isPrefetched || (isWeb && !isAnimating)
|
||||
!isPrefetched || (IS_WEB && !isAnimating)
|
||||
? link.thumb
|
||||
: params.playerUri,
|
||||
}} // Web uses the thumb to control playback
|
||||
@@ -123,7 +123,7 @@ export function ExternalGif({
|
||||
accessibilityIgnoresInvertColors
|
||||
accessibilityLabel={link.title}
|
||||
accessibilityHint={link.title}
|
||||
cachePolicy={isIOS ? 'disk' : 'memory-disk'} // cant control playback with memory-disk on ios
|
||||
cachePolicy={IS_IOS ? 'disk' : 'memory-disk'} // cant control playback with memory-disk on ios
|
||||
/>
|
||||
|
||||
{(!isPrefetched || !isAnimating) && (
|
||||
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
type EmbedPlayerParams,
|
||||
getPlayerAspect,
|
||||
} from '#/lib/strings/embed-player'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useExternalEmbedsPrefs} from '#/state/preferences'
|
||||
import {EventStopper} from '#/view/com/util/EventStopper'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
@@ -34,6 +33,7 @@ import {useDialogControl} from '#/components/Dialog'
|
||||
import {EmbedConsentDialog} from '#/components/dialogs/EmbedConsent'
|
||||
import {Fill} from '#/components/Fill'
|
||||
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
interface ShouldStartLoadRequest {
|
||||
url: string
|
||||
@@ -148,7 +148,7 @@ export function ExternalPlayer({
|
||||
const {height: winHeight, width: winWidth} = windowDims
|
||||
|
||||
// Get the proper screen height depending on what is going on
|
||||
const realWinHeight = isNative // If it is native, we always want the larger number
|
||||
const realWinHeight = IS_NATIVE // If it is native, we always want the larger number
|
||||
? winHeight > winWidth
|
||||
? winHeight
|
||||
: winWidth
|
||||
|
||||
@@ -13,7 +13,6 @@ import {useLingui} from '@lingui/react'
|
||||
import {HITSLOP_20} from '#/lib/constants'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {type EmbedPlayerParams} from '#/lib/strings/embed-player'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useAutoplayDisabled} from '#/state/preferences'
|
||||
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
@@ -22,6 +21,7 @@ import {Loader} from '#/components/Loader'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {GifView} from '../../../../../modules/expo-bluesky-gif-view'
|
||||
import {type GifViewStateChangeEvent} from '../../../../../modules/expo-bluesky-gif-view/src/GifView.types'
|
||||
|
||||
@@ -218,18 +218,18 @@ const styles = StyleSheet.create({
|
||||
altContainer: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.75)',
|
||||
borderRadius: 6,
|
||||
paddingHorizontal: isWeb ? 8 : 6,
|
||||
paddingVertical: isWeb ? 6 : 3,
|
||||
paddingHorizontal: IS_WEB ? 8 : 6,
|
||||
paddingVertical: IS_WEB ? 6 : 3,
|
||||
position: 'absolute',
|
||||
// Related to margin/gap hack. This keeps the alt label in the same position
|
||||
// on all platforms
|
||||
right: isWeb ? 8 : 5,
|
||||
bottom: isWeb ? 8 : 5,
|
||||
right: IS_WEB ? 8 : 5,
|
||||
bottom: IS_WEB ? 8 : 5,
|
||||
zIndex: 2,
|
||||
},
|
||||
alt: {
|
||||
color: 'white',
|
||||
fontSize: isWeb ? 10 : 7,
|
||||
fontSize: IS_WEB ? 10 : 7,
|
||||
fontWeight: '600',
|
||||
},
|
||||
})
|
||||
|
||||
@@ -10,13 +10,13 @@ import {useHaptics} from '#/lib/haptics'
|
||||
import {shareUrl} from '#/lib/sharing'
|
||||
import {parseEmbedPlayerFromUrl} from '#/lib/strings/embed-player'
|
||||
import {toNiceDomain} from '#/lib/strings/url-helpers'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useExternalEmbedsPrefs} from '#/state/preferences'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Divider} from '#/components/Divider'
|
||||
import {Earth_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
|
||||
import {Link} from '#/components/Link'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {ExternalGif} from './ExternalGif'
|
||||
import {ExternalPlayer} from './ExternalPlayer'
|
||||
import {GifEmbed} from './Gif'
|
||||
@@ -53,7 +53,7 @@ export const ExternalEmbed = ({
|
||||
}, [playHaptic, onOpen])
|
||||
|
||||
const onShareExternal = useCallback(() => {
|
||||
if (link.uri && isNative) {
|
||||
if (link.uri && IS_NATIVE) {
|
||||
playHaptic('Heavy')
|
||||
shareUrl(link.uri)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import React, {
|
||||
} from 'react'
|
||||
import {useWindowDimensions} from 'react-native'
|
||||
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
const Context = React.createContext<{
|
||||
activeViewId: string | null
|
||||
@@ -18,7 +18,7 @@ const Context = React.createContext<{
|
||||
Context.displayName = 'ActiveVideoWebContext'
|
||||
|
||||
export function Provider({children}: {children: React.ReactNode}) {
|
||||
if (!isWeb) {
|
||||
if (!IS_WEB) {
|
||||
throw new Error('ActiveVideoWebContext may only be used on web.')
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ export function Provider({children}: {children: React.ReactNode}) {
|
||||
|
||||
const sendViewPosition = useCallback(
|
||||
(viewId: string, y: number) => {
|
||||
if (isNative) return
|
||||
if (IS_NATIVE) return
|
||||
|
||||
if (viewId === activeViewIdRef.current) {
|
||||
activeViewLocationRef.current = y
|
||||
|
||||
@@ -6,7 +6,6 @@ import type Hls from 'hls.js'
|
||||
|
||||
import {isTouchDevice} from '#/lib/browser'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {isIPhoneWeb} from '#/platform/detection'
|
||||
import {
|
||||
useAutoplayDisabled,
|
||||
useSetSubtitlesEnabled,
|
||||
@@ -28,6 +27,7 @@ import {Pause_Filled_Corner0_Rounded as PauseIcon} from '#/components/icons/Paus
|
||||
import {Play_Filled_Corner0_Rounded as PlayIcon} from '#/components/icons/Play'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB_MOBILE_IOS} from '#/env'
|
||||
import {TimeIndicator} from '../TimeIndicator'
|
||||
import {ControlButton} from './ControlButton'
|
||||
import {Scrubber} from './Scrubber'
|
||||
@@ -400,7 +400,7 @@ export function Controls({
|
||||
onEndHover={onVolumeEndHover}
|
||||
drawFocus={drawFocus}
|
||||
/>
|
||||
{!isIPhoneWeb && (
|
||||
{!IS_WEB_MOBILE_IOS && (
|
||||
<ControlButton
|
||||
active={isFullscreen}
|
||||
activeLabel={_(msg`Exit fullscreen`)}
|
||||
|
||||
@@ -10,7 +10,6 @@ import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {shareText, shareUrl} from '#/lib/sharing'
|
||||
import {toShareUrl} from '#/lib/strings/url-helpers'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {useSession} from '#/state/session'
|
||||
import * as Toast from '#/view/com/util/Toast'
|
||||
@@ -24,6 +23,7 @@ import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/i
|
||||
import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlaneIcon} from '#/components/icons/PaperPlane'
|
||||
import * as Menu from '#/components/Menu'
|
||||
import {useAgeAssurance} from '#/ageAssurance'
|
||||
import {IS_IOS} from '#/env'
|
||||
import {useDevMode} from '#/storage/hooks/dev-mode'
|
||||
import {RecentChats} from './RecentChats'
|
||||
import {type ShareMenuItemsProps} from './ShareMenuItems.types'
|
||||
@@ -63,7 +63,7 @@ let ShareMenuItems = ({
|
||||
const onCopyLink = async () => {
|
||||
logger.metric('share:press:copyLink', {}, {statsig: true})
|
||||
const url = toShareUrl(href)
|
||||
if (isIOS) {
|
||||
if (IS_IOS) {
|
||||
// iOS only
|
||||
await ExpoClipboard.setUrlAsync(url)
|
||||
} else {
|
||||
|
||||
@@ -9,7 +9,6 @@ import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {shareText, shareUrl} from '#/lib/sharing'
|
||||
import {toShareUrl} from '#/lib/strings/url-helpers'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useBreakpoints} from '#/alf'
|
||||
@@ -22,6 +21,7 @@ import {CodeBrackets_Stroke2_Corner0_Rounded as CodeBracketsIcon} from '#/compon
|
||||
import {PaperPlane_Stroke2_Corner0_Rounded as Send} from '#/components/icons/PaperPlane'
|
||||
import * as Menu from '#/components/Menu'
|
||||
import {useAgeAssurance} from '#/ageAssurance'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {useDevMode} from '#/storage/hooks/dev-mode'
|
||||
import {type ShareMenuItemsProps} from './ShareMenuItems.types'
|
||||
|
||||
@@ -70,7 +70,7 @@ let ShareMenuItems = ({
|
||||
})
|
||||
}
|
||||
|
||||
const canEmbed = isWeb && gtMobile && !hideInPWI
|
||||
const canEmbed = IS_WEB && gtMobile && !hideInPWI
|
||||
|
||||
const onShareATURI = () => {
|
||||
shareText(postUri)
|
||||
|
||||
@@ -12,7 +12,6 @@ import {useLingui} from '@lingui/react'
|
||||
import {popularInterests, useInterestsDisplayNames} from '#/lib/interests'
|
||||
import {logEvent} from '#/lib/statsig/statsig'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {useActorSearch} from '#/state/queries/actor-search'
|
||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||
@@ -37,6 +36,7 @@ import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
||||
import {boostInterests, InterestTabs} from '#/components/InterestTabs'
|
||||
import * as ProfileCard from '#/components/ProfileCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import {ProgressGuideTask} from './Task'
|
||||
|
||||
@@ -431,7 +431,7 @@ function HeaderTop({guide}: {guide?: Follow10ProgressGuide}) {
|
||||
<Trans>Find people to follow</Trans>
|
||||
</Text>
|
||||
{guide && (
|
||||
<View style={isWeb && {paddingRight: 36}}>
|
||||
<View style={IS_WEB && {paddingRight: 36}}>
|
||||
<ProgressGuideTask
|
||||
current={guide.numFollows + 1}
|
||||
total={10 + 1}
|
||||
@@ -440,12 +440,12 @@ function HeaderTop({guide}: {guide?: Follow10ProgressGuide}) {
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
{isWeb ? (
|
||||
{IS_WEB ? (
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
size="small"
|
||||
shape="round"
|
||||
variant={isWeb ? 'ghost' : 'solid'}
|
||||
variant={IS_WEB ? 'ghost' : 'solid'}
|
||||
color="secondary"
|
||||
style={[
|
||||
a.absolute,
|
||||
@@ -579,7 +579,7 @@ function FollowProfileCardInner({
|
||||
<ProfileCard.Outer>
|
||||
<ProfileCard.Header>
|
||||
<ProfileCard.Avatar
|
||||
disabledPreview={!isWeb}
|
||||
disabledPreview={!IS_WEB}
|
||||
profile={profile}
|
||||
moderationOpts={moderationOpts}
|
||||
/>
|
||||
|
||||
@@ -11,9 +11,9 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Portal} from '#/components/Portal'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {AnimatedCheck, type AnimatedCheckRef} from '../anim/AnimatedCheck'
|
||||
import {Text} from '../Typography'
|
||||
|
||||
@@ -108,11 +108,11 @@ export const ProgressGuideToast = React.forwardRef<
|
||||
const containerStyle = React.useMemo(() => {
|
||||
let left = 10
|
||||
let right = 10
|
||||
if (isWeb && winDim.width > 400) {
|
||||
if (IS_WEB && winDim.width > 400) {
|
||||
left = right = (winDim.width - 380) / 2
|
||||
}
|
||||
return {
|
||||
position: isWeb ? 'fixed' : 'absolute',
|
||||
position: IS_WEB ? 'fixed' : 'absolute',
|
||||
top: 0,
|
||||
left,
|
||||
right,
|
||||
|
||||
@@ -6,7 +6,6 @@ import {useNavigation} from '@react-navigation/native'
|
||||
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {isInvalidHandle} from '#/lib/strings/handles'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {
|
||||
usePreferencesQuery,
|
||||
useRemoveMutedWordsMutation,
|
||||
@@ -22,6 +21,7 @@ import {
|
||||
} from '#/components/Link'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import * as Menu from '#/components/Menu'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
export function RichTextTag({
|
||||
tag,
|
||||
@@ -50,7 +50,7 @@ export function RichTextTag({
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
const isCashtag = tag.startsWith('$')
|
||||
const label = isCashtag ? _(msg`Cashtag ${tag}`) : _(msg`Hashtag ${tag}`)
|
||||
const hint = isNative
|
||||
const hint = IS_NATIVE
|
||||
? _(msg`Long press to open tag menu for ${isCashtag ? tag : `#${tag}`}`)
|
||||
: _(msg`Click to open tag menu for ${isCashtag ? tag : `#${tag}`}`)
|
||||
|
||||
@@ -86,9 +86,9 @@ export function RichTextTag({
|
||||
}}
|
||||
{...menuProps}
|
||||
onPress={e => {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
return createStaticClickIfUnmodified(() => {
|
||||
if (!isNative) {
|
||||
if (!IS_NATIVE) {
|
||||
menuProps.onPress()
|
||||
}
|
||||
}).onPress(e)
|
||||
@@ -99,7 +99,7 @@ export function RichTextTag({
|
||||
label={label}
|
||||
style={textStyle}
|
||||
emoji>
|
||||
{isNative ? (
|
||||
{IS_NATIVE ? (
|
||||
display
|
||||
) : (
|
||||
<RNText ref={menuProps.ref}>{display}</RNText>
|
||||
|
||||
@@ -8,7 +8,7 @@ import Animated, {
|
||||
} from 'react-native-reanimated'
|
||||
import type React from 'react'
|
||||
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
export function ScreenTransition({
|
||||
direction,
|
||||
@@ -31,8 +31,8 @@ export function ScreenTransition({
|
||||
|
||||
return (
|
||||
<Animated.View
|
||||
entering={isWeb ? webEntering : entering}
|
||||
exiting={isWeb ? webExiting : exiting}
|
||||
entering={IS_WEB ? webEntering : entering}
|
||||
exiting={IS_WEB ? webExiting : exiting}
|
||||
style={style}>
|
||||
{children}
|
||||
</Animated.View>
|
||||
|
||||
@@ -82,7 +82,7 @@ export function Trigger({children, label}: TriggerProps) {
|
||||
|
||||
if (typeof children === 'function') {
|
||||
return children({
|
||||
isNative: true,
|
||||
IS_NATIVE: true,
|
||||
control,
|
||||
state: {
|
||||
hovered: false,
|
||||
|
||||
@@ -68,7 +68,7 @@ export function Trigger({children, label}: TriggerProps) {
|
||||
<RadixTriggerPassThrough>
|
||||
{props =>
|
||||
children({
|
||||
isNative: false,
|
||||
IS_NATIVE: false,
|
||||
state: {
|
||||
hovered,
|
||||
focused,
|
||||
|
||||
@@ -65,7 +65,7 @@ export type TriggerProps = {
|
||||
|
||||
export type TriggerChildProps =
|
||||
| {
|
||||
isNative: true
|
||||
IS_NATIVE: true
|
||||
control: DialogControlProps
|
||||
state: {
|
||||
/**
|
||||
@@ -92,7 +92,7 @@ export type TriggerChildProps =
|
||||
}
|
||||
}
|
||||
| {
|
||||
isNative: false
|
||||
IS_NATIVE: false
|
||||
state: {
|
||||
hovered: boolean
|
||||
focused: boolean
|
||||
|
||||
@@ -3,11 +3,11 @@ import {type ListRenderItemInfo, View} from 'react-native'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
|
||||
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {List, type ListRef} from '#/view/com/util/List'
|
||||
import {type SectionRef} from '#/screens/Profile/Sections/types'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import * as FeedCard from '#/components/FeedCard'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
function keyExtractor(item: AppBskyFeedDefs.GeneratorView) {
|
||||
return item.uri
|
||||
@@ -27,7 +27,7 @@ export const FeedsList = React.forwardRef<SectionRef, ProfilesListProps>(
|
||||
|
||||
const onScrollToTop = useCallback(() => {
|
||||
scrollElRef.current?.scrollToOffset({
|
||||
animated: isNative,
|
||||
animated: IS_NATIVE,
|
||||
offset: -headerHeight,
|
||||
})
|
||||
}, [scrollElRef, headerHeight])
|
||||
@@ -44,7 +44,7 @@ export const FeedsList = React.forwardRef<SectionRef, ProfilesListProps>(
|
||||
<View
|
||||
style={[
|
||||
a.p_lg,
|
||||
(isWeb || index !== 0) && a.border_t,
|
||||
(IS_WEB || index !== 0) && a.border_t,
|
||||
t.atoms.border_contrast_low,
|
||||
]}>
|
||||
<FeedCard.Default view={item} />
|
||||
|
||||
@@ -3,13 +3,13 @@ import {View} from 'react-native'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {type FeedDescriptor} from '#/state/queries/post-feed'
|
||||
import {PostFeed} from '#/view/com/posts/PostFeed'
|
||||
import {EmptyState} from '#/view/com/util/EmptyState'
|
||||
import {type ListRef} from '#/view/com/util/List'
|
||||
import {type SectionRef} from '#/screens/Profile/Sections/types'
|
||||
import {HashtagWide_Stroke1_Corner0_Rounded as HashtagWideIcon} from '#/components/icons/Hashtag'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
interface ProfilesListProps {
|
||||
listUri: string
|
||||
@@ -24,7 +24,7 @@ export const PostsList = React.forwardRef<SectionRef, ProfilesListProps>(
|
||||
|
||||
const onScrollToTop = useCallback(() => {
|
||||
scrollElRef.current?.scrollToOffset({
|
||||
animated: isNative,
|
||||
animated: IS_NATIVE,
|
||||
offset: -headerHeight,
|
||||
})
|
||||
}, [scrollElRef, headerHeight])
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
|
||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {useAllListMembersQuery} from '#/state/queries/list-members'
|
||||
import {useSession} from '#/state/session'
|
||||
import {List, type ListRef} from '#/view/com/util/List'
|
||||
@@ -22,6 +21,7 @@ import {type SectionRef} from '#/screens/Profile/Sections/types'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
||||
import {Default as ProfileCard} from '#/components/ProfileCard'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
function keyExtractor(item: AppBskyActorDefs.ProfileViewBasic, index: number) {
|
||||
return `${item.did}-${index}`
|
||||
@@ -75,7 +75,7 @@ export const ProfilesList = React.forwardRef<SectionRef, ProfilesListProps>(
|
||||
}
|
||||
const onScrollToTop = useCallback(() => {
|
||||
scrollElRef.current?.scrollToOffset({
|
||||
animated: isNative,
|
||||
animated: IS_NATIVE,
|
||||
offset: -headerHeight,
|
||||
})
|
||||
}, [scrollElRef, headerHeight])
|
||||
@@ -93,7 +93,7 @@ export const ProfilesList = React.forwardRef<SectionRef, ProfilesListProps>(
|
||||
style={[
|
||||
a.p_lg,
|
||||
t.atoms.border_contrast_low,
|
||||
(isWeb || index !== 0) && a.border_t,
|
||||
(IS_WEB || index !== 0) && a.border_t,
|
||||
]}>
|
||||
<ProfileCard
|
||||
profile={item}
|
||||
|
||||
@@ -19,7 +19,6 @@ import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {parseStarterPackUri} from '#/lib/strings/starter-pack'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {useActorStarterPacksQuery} from '#/state/queries/actor-starter-packs'
|
||||
import {
|
||||
EmptyState,
|
||||
@@ -36,6 +35,7 @@ import {Loader} from '#/components/Loader'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {Default as StarterPackCard} from '#/components/StarterPack/StarterPackCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_IOS} from '#/env'
|
||||
|
||||
interface SectionRef {
|
||||
scrollToTop: () => void
|
||||
@@ -136,7 +136,7 @@ export function ProfileStarterPacks({
|
||||
}, [isFetchingNextPage, hasNextPage, isError, fetchNextPage])
|
||||
|
||||
useEffect(() => {
|
||||
if (isIOS && enabled && scrollElRef.current) {
|
||||
if (IS_IOS && enabled && scrollElRef.current) {
|
||||
const nativeTag = findNodeHandle(scrollElRef.current)
|
||||
setScrollViewTag(nativeTag)
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ import type ViewShot from 'react-native-view-shot'
|
||||
import {type AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api'
|
||||
import {Trans} from '@lingui/macro'
|
||||
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {Logo} from '#/view/icons/Logo'
|
||||
import {Logotype} from '#/view/icons/Logotype'
|
||||
import {useTheme} from '#/alf'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {LinearGradientBackground} from '#/components/LinearGradientBackground'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
const LazyViewShot = lazy(
|
||||
@@ -121,7 +121,7 @@ export function QrCodeInner({link}: {link: string}) {
|
||||
return (
|
||||
<View style={{position: 'relative'}}>
|
||||
{/* An SVG version of the logo is placed on top of normal `QRCode` `logo` prop, since the PNG fails to load before the export completes on web. */}
|
||||
{isWeb && logoArea && (
|
||||
{IS_WEB && logoArea && (
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
@@ -139,9 +139,9 @@ export function QrCodeInner({link}: {link: string}) {
|
||||
a.rounded_sm,
|
||||
{height: 225, width: 225, backgroundColor: '#f3f3f3'},
|
||||
]}
|
||||
pieceSize={isWeb ? 8 : 6}
|
||||
pieceSize={IS_WEB ? 8 : 6}
|
||||
padding={20}
|
||||
pieceBorderRadius={isWeb ? 4.5 : 3.5}
|
||||
pieceBorderRadius={IS_WEB ? 4.5 : 3.5}
|
||||
outerEyesOptions={{
|
||||
topLeft: {
|
||||
borderRadius: [12, 12, 0, 12],
|
||||
@@ -159,11 +159,11 @@ export function QrCodeInner({link}: {link: string}) {
|
||||
innerEyesOptions={{borderRadius: 3}}
|
||||
logo={{
|
||||
href: require('../../../assets/logo.png'),
|
||||
...(isWeb && {
|
||||
...(IS_WEB && {
|
||||
onChange: onLogoAreaChange,
|
||||
padding: 28,
|
||||
}),
|
||||
...(!isWeb && {
|
||||
...(!IS_WEB && {
|
||||
padding: 2,
|
||||
scale: 0.95,
|
||||
}),
|
||||
|
||||
@@ -9,7 +9,6 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useBreakpoints} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
@@ -20,6 +19,7 @@ import {FloppyDisk_Stroke2_Corner0_Rounded as FloppyDiskIcon} from '#/components
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {QrCode} from '#/components/StarterPack/QrCode'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
export function QrCodeDialog({
|
||||
@@ -56,7 +56,7 @@ export function QrCodeDialog({
|
||||
|
||||
const onSavePress = async () => {
|
||||
ref.current?.capture?.().then(async (uri: string) => {
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
const res = await requestMediaLibraryPermissionsAsync()
|
||||
|
||||
if (!res.granted) {
|
||||
@@ -111,7 +111,7 @@ export function QrCodeDialog({
|
||||
})
|
||||
setIsSaveProcessing(false)
|
||||
Toast.show(
|
||||
isWeb
|
||||
IS_WEB
|
||||
? _(msg`QR code has been downloaded!`)
|
||||
: _(msg`QR code saved to your camera roll!`),
|
||||
)
|
||||
@@ -178,18 +178,18 @@ export function QrCodeDialog({
|
||||
label={_(msg`Copy QR code`)}
|
||||
color="primary_subtle"
|
||||
size="large"
|
||||
onPress={isWeb ? onCopyPress : onSharePress}>
|
||||
onPress={IS_WEB ? onCopyPress : onSharePress}>
|
||||
<ButtonIcon
|
||||
icon={
|
||||
isCopyProcessing
|
||||
? Loader
|
||||
: isWeb
|
||||
: IS_WEB
|
||||
? ChainLinkIcon
|
||||
: ShareIcon
|
||||
}
|
||||
/>
|
||||
<ButtonText>
|
||||
{isWeb ? <Trans>Copy</Trans> : <Trans>Share</Trans>}
|
||||
{IS_WEB ? <Trans>Copy</Trans> : <Trans>Share</Trans>}
|
||||
</ButtonText>
|
||||
</Button>
|
||||
<Button
|
||||
|
||||
@@ -8,7 +8,6 @@ import {useSaveImageToMediaLibrary} from '#/lib/media/save-image'
|
||||
import {shareUrl} from '#/lib/sharing'
|
||||
import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
|
||||
import {logger} from '#/logger'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import {type DialogControlProps} from '#/components/Dialog'
|
||||
@@ -18,6 +17,7 @@ import {Download_Stroke2_Corner0_Rounded as DownloadIcon} from '#/components/ico
|
||||
import {QrCode_Stroke2_Corner0_Rounded as QrCodeIcon} from '#/components/icons/QrCode'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
interface Props {
|
||||
starterPack: AppBskyGraphDefs.StarterPackView
|
||||
@@ -110,13 +110,17 @@ function ShareDialogInner({
|
||||
],
|
||||
]}>
|
||||
<Button
|
||||
label={isWeb ? _(msg`Copy link`) : _(msg`Share link`)}
|
||||
label={IS_WEB ? _(msg`Copy link`) : _(msg`Share link`)}
|
||||
color="primary_subtle"
|
||||
size="large"
|
||||
onPress={onShareLink}>
|
||||
<ButtonIcon icon={ChainLinkIcon} />
|
||||
<ButtonText>
|
||||
{isWeb ? <Trans>Copy Link</Trans> : <Trans>Share link</Trans>}
|
||||
{IS_WEB ? (
|
||||
<Trans>Copy Link</Trans>
|
||||
) : (
|
||||
<Trans>Share link</Trans>
|
||||
)}
|
||||
</ButtonText>
|
||||
</Button>
|
||||
<Button
|
||||
@@ -133,7 +137,7 @@ function ShareDialogInner({
|
||||
<Trans>Share QR code</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<Button
|
||||
label={_(msg`Save image`)}
|
||||
color="secondary"
|
||||
|
||||
@@ -10,7 +10,6 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {type ListMethods} from '#/view/com/util/List'
|
||||
import {
|
||||
type WizardAction,
|
||||
@@ -24,6 +23,7 @@ import {
|
||||
WizardProfileCard,
|
||||
} from '#/components/StarterPack/Wizard/WizardListCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
function keyExtractor(
|
||||
item: AppBskyActorDefs.ProfileViewBasic | AppBskyFeedDefs.GeneratorView,
|
||||
@@ -95,7 +95,7 @@ export function WizardEditListDialog({
|
||||
a.mb_sm,
|
||||
t.atoms.bg,
|
||||
t.atoms.border_contrast_medium,
|
||||
isWeb
|
||||
IS_WEB
|
||||
? [
|
||||
a.align_center,
|
||||
{
|
||||
@@ -113,7 +113,7 @@ export function WizardEditListDialog({
|
||||
)}
|
||||
</Text>
|
||||
<View style={{width: 60}}>
|
||||
{isWeb && (
|
||||
{IS_WEB && (
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
variant="ghost"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {View} from 'react-native'
|
||||
|
||||
import {isTouchDevice} from '#/lib/browser'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme, type ViewStyleProp} from '#/alf'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
export function SubtleHover({
|
||||
style,
|
||||
@@ -39,9 +39,9 @@ export function SubtleHover({
|
||||
/>
|
||||
)
|
||||
|
||||
if (isWeb && web) {
|
||||
if (IS_WEB && web) {
|
||||
return isTouchDevice ? null : el
|
||||
} else if (isNative && native) {
|
||||
} else if (IS_NATIVE && native) {
|
||||
return el
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ import {useLingui} from '@lingui/react'
|
||||
import {HITSLOP_10} from '#/lib/constants'
|
||||
import {makeListLink, makeProfileLink} from '#/lib/routes/links'
|
||||
import {logger} from '#/logger'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {
|
||||
type ThreadgateAllowUISetting,
|
||||
threadgateViewToAllowUISetting,
|
||||
@@ -37,6 +36,7 @@ import {Earth_Stroke2_Corner0_Rounded as EarthIcon} from '#/components/icons/Glo
|
||||
import {Group3_Stroke2_Corner0_Rounded as GroupIcon} from '#/components/icons/Group'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
interface WhoCanReplyProps {
|
||||
@@ -86,7 +86,7 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) {
|
||||
: _(msg`Some people can reply`)
|
||||
|
||||
const onPressOpen = () => {
|
||||
if (isNative && Keyboard.isVisible()) {
|
||||
if (IS_NATIVE && Keyboard.isVisible()) {
|
||||
Keyboard.dismiss()
|
||||
}
|
||||
if (isThreadAuthor) {
|
||||
@@ -229,7 +229,7 @@ function WhoCanReplyDialog({
|
||||
embeddingDisabled={embeddingDisabled}
|
||||
/>
|
||||
</View>
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
onPress={() => control.close()}
|
||||
|
||||
@@ -18,7 +18,6 @@ import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-disp
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {updateProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {RQKEY_getActivitySubscriptions} from '#/state/queries/activity-subscriptions'
|
||||
import {useAgent} from '#/state/session'
|
||||
@@ -37,6 +36,7 @@ import * as Toggle from '#/components/forms/Toggle'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import * as ProfileCard from '#/components/ProfileCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
|
||||
export function SubscribeProfileDialog({
|
||||
@@ -195,7 +195,7 @@ function DialogInner({
|
||||
}
|
||||
} else {
|
||||
// on web, a disabled save button feels more natural than a massive close button
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
return {
|
||||
label: _(msg`Save changes`),
|
||||
color: 'secondary',
|
||||
|
||||
@@ -3,7 +3,6 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {dateDiff, useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {atoms as a, useBreakpoints, useTheme, type ViewStyleProp} from '#/alf'
|
||||
import {Admonition} from '#/components/Admonition'
|
||||
import {AgeAssuranceAppealDialog} from '#/components/ageAssurance/AgeAssuranceAppealDialog'
|
||||
@@ -23,6 +22,7 @@ import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {logger, useAgeAssurance} from '#/ageAssurance'
|
||||
import {useComputeAgeAssuranceRegionAccess} from '#/ageAssurance/useComputeAgeAssuranceRegionAccess'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {useDeviceGeolocationApi} from '#/geolocation'
|
||||
|
||||
export function AgeAssuranceAccountCard({style}: ViewStyleProp & {}) {
|
||||
@@ -86,7 +86,7 @@ function Inner({style}: ViewStyleProp & {}) {
|
||||
<View style={[a.pb_md, a.gap_xs]}>
|
||||
<Text style={[a.text_sm, a.leading_snug]}>{copy.notice}</Text>
|
||||
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<>
|
||||
<Text style={[a.text_sm, a.leading_snug]}>
|
||||
<Trans>
|
||||
|
||||
@@ -5,7 +5,6 @@ import {useLingui} from '@lingui/react'
|
||||
|
||||
import {retry} from '#/lib/async/retry'
|
||||
import {wait} from '#/lib/async/wait'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {AgeAssuranceBadge} from '#/components/ageAssurance/AgeAssuranceBadge'
|
||||
@@ -18,6 +17,7 @@ import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {refetchAgeAssuranceServerState} from '#/ageAssurance'
|
||||
import {logger} from '#/ageAssurance'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export type AgeAssuranceRedirectDialogState = {
|
||||
result: 'success' | 'unknown'
|
||||
@@ -166,7 +166,7 @@ export function Inner({}: {optimisticState?: AgeAssuranceRedirectDialogState}) {
|
||||
</Trans>
|
||||
</Text>
|
||||
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<View style={[a.w_full, a.pt_lg]}>
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
@@ -225,7 +225,7 @@ export function Inner({}: {optimisticState?: AgeAssuranceRedirectDialogState}) {
|
||||
)}
|
||||
</Text>
|
||||
|
||||
{error && isNative && (
|
||||
{error && IS_NATIVE && (
|
||||
<View style={[a.w_full, a.pt_lg]}>
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
|
||||
@@ -8,12 +8,12 @@ import {useLingui} from '@lingui/react'
|
||||
import {HITSLOP_10} from '#/lib/constants'
|
||||
import {useGate} from '#/lib/statsig/statsig'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {Nux, useNux, useSaveNux} from '#/state/queries/nuxs'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Button} from '#/components/Button'
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {Link} from '../Link'
|
||||
import {useIsFindContactsFeatureEnabledBasedOnGeolocation} from './country-allowlist'
|
||||
|
||||
@@ -92,7 +92,7 @@ function useInternalState() {
|
||||
const gate = useGate()
|
||||
|
||||
const visible = useMemo(() => {
|
||||
if (isWeb) return false
|
||||
if (IS_WEB) return false
|
||||
if (hidden) return false
|
||||
if (nux && nux.completed) return false
|
||||
if (!isFeatureEnabled) return false
|
||||
|
||||
@@ -9,10 +9,10 @@ import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {mergeRefs} from '#/lib/merge-refs'
|
||||
import {isAndroid, isIOS} from '#/platform/detection'
|
||||
import {atoms as a, ios, platform, useTheme} from '#/alf'
|
||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_ANDROID, IS_IOS} from '#/env'
|
||||
|
||||
export function OTPInput({
|
||||
label,
|
||||
@@ -95,7 +95,7 @@ export function OTPInput({
|
||||
<TextInput
|
||||
// SMS autofill is borked on iOS if you open the keyboard immediately -sfn
|
||||
onLayout={ios(() => setTimeout(() => innerRef.current?.focus(), 100))}
|
||||
autoFocus={isAndroid}
|
||||
autoFocus={IS_ANDROID}
|
||||
accessible
|
||||
accessibilityLabel={label}
|
||||
accessibilityHint=""
|
||||
@@ -135,7 +135,7 @@ export function OTPInput({
|
||||
android: {opacity: 0},
|
||||
}),
|
||||
]}
|
||||
caretHidden={isIOS}
|
||||
caretHidden={IS_IOS}
|
||||
clearTextOnFocus
|
||||
/>
|
||||
</Pressable>
|
||||
|
||||
@@ -7,7 +7,6 @@ import {useCleanError} from '#/lib/hooks/useCleanError'
|
||||
import {isAppPassword} from '#/lib/jwt'
|
||||
import {getAge, getDateAgo} from '#/lib/strings/time'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS, isWeb} from '#/platform/detection'
|
||||
import {
|
||||
useBirthdateMutation,
|
||||
useIsBirthdateUpdateAllowed,
|
||||
@@ -26,6 +25,7 @@ import {DateField} from '#/components/forms/DateField'
|
||||
import {SimpleInlineLinkText} from '#/components/Link'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Span, Text} from '#/components/Typography'
|
||||
import {IS_IOS, IS_WEB} from '#/env'
|
||||
|
||||
export function BirthDateSettingsDialog({
|
||||
control,
|
||||
@@ -154,7 +154,7 @@ function BirthdayInner({
|
||||
|
||||
return (
|
||||
<View style={a.gap_lg} testID="birthDateSettingsDialog">
|
||||
<View style={isIOS && [a.w_full, a.align_center]}>
|
||||
<View style={IS_IOS && [a.w_full, a.align_center]}>
|
||||
<DateField
|
||||
testID="birthdayInput"
|
||||
value={date}
|
||||
@@ -191,7 +191,7 @@ function BirthdayInner({
|
||||
<ErrorMessage message={errorMessage} style={[a.rounded_sm]} />
|
||||
) : undefined}
|
||||
|
||||
<View style={isWeb && [a.flex_row, a.justify_end]}>
|
||||
<View style={IS_WEB && [a.flex_row, a.justify_end]}>
|
||||
<Button
|
||||
label={hasChanged ? _(msg`Save birthdate`) : _(msg`Done`)}
|
||||
size="large"
|
||||
|
||||
@@ -6,7 +6,6 @@ import {useLingui} from '@lingui/react'
|
||||
import {wait} from '#/lib/async/wait'
|
||||
import {isNetworkError, useCleanError} from '#/lib/hooks/useCleanError'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {Admonition} from '#/components/Admonition'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
@@ -14,6 +13,7 @@ import * as Dialog from '#/components/Dialog'
|
||||
import {PinLocation_Stroke2_Corner0_Rounded as LocationIcon} from '#/components/icons/PinLocation'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {type Geolocation, useRequestDeviceGeolocation} from '#/geolocation'
|
||||
|
||||
export type Props = {
|
||||
@@ -138,7 +138,7 @@ function DeviceLocationRequestDialogInner({onLocationAcquired}: Props) {
|
||||
disabled={isRequesting}
|
||||
label={_(msg`Allow location access`)}
|
||||
onPress={onPressConfirm}
|
||||
size={isWeb ? 'small' : 'large'}
|
||||
size={IS_WEB ? 'small' : 'large'}
|
||||
color="primary">
|
||||
<ButtonIcon icon={isRequesting ? Loader : LocationIcon} />
|
||||
<ButtonText>
|
||||
@@ -147,11 +147,11 @@ function DeviceLocationRequestDialogInner({onLocationAcquired}: Props) {
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!isWeb && (
|
||||
{!IS_WEB && (
|
||||
<Button
|
||||
label={_(msg`Cancel`)}
|
||||
onPress={() => close()}
|
||||
size={isWeb ? 'small' : 'large'}
|
||||
size={IS_WEB ? 'small' : 'large'}
|
||||
color="secondary">
|
||||
<ButtonText>
|
||||
<Trans>Cancel</Trans>
|
||||
|
||||
@@ -13,7 +13,6 @@ import {useLingui} from '@lingui/react'
|
||||
|
||||
import {logEvent} from '#/lib/statsig/statsig'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {
|
||||
type Gif,
|
||||
tenorUrlToBskyGifUrl,
|
||||
@@ -31,6 +30,7 @@ import {useThrottledValue} from '#/components/hooks/useThrottledValue'
|
||||
import {ArrowLeft_Stroke2_Corner0_Rounded as Arrow} from '#/components/icons/Arrow'
|
||||
import {MagnifyingGlass_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass'
|
||||
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
export function GifSelectDialog({
|
||||
controlRef,
|
||||
@@ -149,7 +149,7 @@ function GifList({
|
||||
a.pb_sm,
|
||||
t.atoms.bg,
|
||||
]}>
|
||||
{!gtMobile && isWeb && (
|
||||
{!gtMobile && IS_WEB && (
|
||||
<Button
|
||||
size="small"
|
||||
variant="ghost"
|
||||
@@ -161,7 +161,7 @@ function GifList({
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<TextField.Root style={[!gtMobile && isWeb && a.flex_1]}>
|
||||
<TextField.Root style={[!gtMobile && IS_WEB && a.flex_1]}>
|
||||
<TextField.Icon icon={Search} />
|
||||
<TextField.Input
|
||||
label={_(msg`Search GIFs`)}
|
||||
|
||||
@@ -4,19 +4,19 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {useOpenLink} from '#/lib/hooks/useOpenLink'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useSetInAppBrowser} from '#/state/preferences/in-app-browser'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import {SquareArrowTopRight_Stroke2_Corner0_Rounded as External} from '#/components/icons/SquareArrowTopRight'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {useGlobalDialogsControlContext} from './Context'
|
||||
|
||||
export function InAppBrowserConsentDialog() {
|
||||
const {inAppBrowserConsentControl} = useGlobalDialogsControlContext()
|
||||
|
||||
if (isWeb) return null
|
||||
if (IS_WEB) return null
|
||||
|
||||
return (
|
||||
<Dialog.Outer
|
||||
|
||||
@@ -5,7 +5,6 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {
|
||||
usePreferencesQuery,
|
||||
useRemoveMutedWordMutation,
|
||||
@@ -32,6 +31,7 @@ import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
const ONE_DAY = 24 * 60 * 60 * 1000
|
||||
|
||||
@@ -406,7 +406,7 @@ function MutedWordsInner() {
|
||||
)}
|
||||
</View>
|
||||
|
||||
{isNative && <View style={{height: 20}} />}
|
||||
{IS_NATIVE && <View style={{height: 20}} />}
|
||||
</View>
|
||||
|
||||
<Dialog.Close />
|
||||
|
||||
@@ -12,7 +12,6 @@ import {useQueryClient} from '@tanstack/react-query'
|
||||
import {useHaptics} from '#/lib/haptics'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {STALE} from '#/state/queries'
|
||||
import {useMyListsQuery} from '#/state/queries/my-lists'
|
||||
import {useGetPost} from '#/state/queries/post'
|
||||
@@ -52,6 +51,7 @@ import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/ico
|
||||
import {CloseQuote_Stroke2_Corner1_Rounded as QuoteIcon} from '#/components/icons/Quote'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_IOS} from '#/env'
|
||||
|
||||
export type PostInteractionSettingsFormProps = {
|
||||
canSave?: boolean
|
||||
@@ -531,7 +531,7 @@ export function PostInteractionSettingsForm({
|
||||
hitSlop={0}
|
||||
onPress={() => {
|
||||
playHaptic('Light')
|
||||
if (isIOS && !showLists) {
|
||||
if (IS_IOS && !showLists) {
|
||||
LayoutAnimation.configureNext({
|
||||
...LayoutAnimation.Presets.linear,
|
||||
duration: 175,
|
||||
|
||||
@@ -13,7 +13,6 @@ import {useLingui} from '@lingui/react'
|
||||
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
||||
import {useListConvosQuery} from '#/state/queries/messages/list-conversations'
|
||||
@@ -29,6 +28,7 @@ import {MagnifyingGlass_Stroke2_Corner0_Rounded as Search} from '#/components/ic
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
||||
import * as ProfileCard from '#/components/ProfileCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
|
||||
export type ProfileItem = {
|
||||
@@ -254,7 +254,7 @@ export function SearchablePeopleList({
|
||||
)
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
setImmediate(() => {
|
||||
inputRef?.current?.focus()
|
||||
})
|
||||
@@ -290,12 +290,12 @@ export function SearchablePeopleList({
|
||||
]}>
|
||||
{title}
|
||||
</Text>
|
||||
{isWeb ? (
|
||||
{IS_WEB ? (
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
size="small"
|
||||
shape="round"
|
||||
variant={isWeb ? 'ghost' : 'solid'}
|
||||
variant={IS_WEB ? 'ghost' : 'solid'}
|
||||
color="secondary"
|
||||
style={[
|
||||
a.absolute,
|
||||
|
||||
@@ -3,7 +3,6 @@ import {View} from 'react-native'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||
import {useCloseAllActiveElements} from '#/state/util'
|
||||
import {Logo} from '#/view/icons/Logo'
|
||||
@@ -13,6 +12,7 @@ import {Button, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import {useGlobalDialogsControlContext} from '#/components/dialogs/Context'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export function SigninDialog() {
|
||||
const {signinDialogControl: control} = useGlobalDialogsControlContext()
|
||||
@@ -45,7 +45,7 @@ function SigninDialogInner({}: {control: Dialog.DialogOuterProps['control']}) {
|
||||
<Dialog.ScrollableInner
|
||||
label={_(msg`Sign in to Bluesky or create a new account`)}
|
||||
style={[gtMobile ? {width: 'auto', maxWidth: 420} : a.w_full]}>
|
||||
<View style={[!isNative && a.p_2xl]}>
|
||||
<View style={[!IS_NATIVE && a.p_2xl]}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_row,
|
||||
@@ -101,7 +101,7 @@ function SigninDialogInner({}: {control: Dialog.DialogOuterProps['control']}) {
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
{isNative && <View style={{height: 10}} />}
|
||||
{IS_NATIVE && <View style={{height: 10}} />}
|
||||
</View>
|
||||
|
||||
<Dialog.Close />
|
||||
|
||||
@@ -12,7 +12,6 @@ import {useQueryClient} from '@tanstack/react-query'
|
||||
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {
|
||||
invalidateActorStarterPacksWithMembershipQuery,
|
||||
useActorStarterPacksWithMembershipsQuery,
|
||||
@@ -32,6 +31,7 @@ import {StarterPack} from '#/components/icons/StarterPack'
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
type StarterPackWithMembership =
|
||||
@@ -91,7 +91,7 @@ function Empty({onStartWizard}: {onStartWizard: () => void}) {
|
||||
const t = useTheme()
|
||||
|
||||
return (
|
||||
<View style={[a.gap_2xl, {paddingTop: isWeb ? 100 : 64}]}>
|
||||
<View style={[a.gap_2xl, {paddingTop: IS_WEB ? 100 : 64}]}>
|
||||
<View style={[a.gap_xs, a.align_center]}>
|
||||
<StarterPack
|
||||
width={48}
|
||||
@@ -169,7 +169,7 @@ function StarterPackList({
|
||||
<View
|
||||
style={[
|
||||
{justifyContent: 'space-between', flexDirection: 'row'},
|
||||
isWeb ? a.mb_2xl : a.my_lg,
|
||||
IS_WEB ? a.mb_2xl : a.my_lg,
|
||||
a.align_center,
|
||||
]}>
|
||||
<Text style={[a.text_lg, a.font_semi_bold]}>
|
||||
@@ -232,7 +232,7 @@ function StarterPackList({
|
||||
onEndReachedThreshold={0.1}
|
||||
ListHeaderComponent={listHeader}
|
||||
ListEmptyComponent={<Empty onStartWizard={onStartWizard} />}
|
||||
style={isWeb ? [a.px_md, {minHeight: 500}] : [a.px_2xl, a.pt_lg]}
|
||||
style={IS_WEB ? [a.px_md, {minHeight: 500}] : [a.px_2xl, a.pt_lg]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import {isOverMaxGraphemeCount} from '#/lib/strings/helpers'
|
||||
import {richTextToString} from '#/lib/strings/rich-text-helpers'
|
||||
import {shortenLinks, stripInvalidMentions} from '#/lib/strings/rich-text-manip'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {type ImageMeta} from '#/state/gallery'
|
||||
import {
|
||||
useListCreateMutation,
|
||||
@@ -26,6 +25,7 @@ import * as TextField from '#/components/forms/TextField'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
const DISPLAY_NAME_MAX_GRAPHEMES = 64
|
||||
const DESCRIPTION_MAX_GRAPHEMES = 300
|
||||
@@ -48,7 +48,7 @@ export function CreateOrEditListDialog({
|
||||
|
||||
// 'You might lose unsaved changes' warning
|
||||
useEffect(() => {
|
||||
if (isWeb && dirty) {
|
||||
if (IS_WEB && dirty) {
|
||||
const abortController = new AbortController()
|
||||
const {signal} = abortController
|
||||
window.addEventListener('beforeunload', evt => evt.preventDefault(), {
|
||||
|
||||
@@ -4,13 +4,13 @@ import {Image} from 'expo-image'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import {useNuxDialogContext} from '#/components/dialogs/nuxs'
|
||||
import {Sparkle_Stroke2_Corner0_Rounded as SparkleIcon} from '#/components/icons/Sparkle'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
export function ActivitySubscriptionsNUX() {
|
||||
const t = useTheme()
|
||||
@@ -44,8 +44,8 @@ export function ActivitySubscriptionsNUX() {
|
||||
a.overflow_hidden,
|
||||
t.atoms.bg_contrast_25,
|
||||
{
|
||||
gap: isWeb ? 16 : 24,
|
||||
paddingTop: isWeb ? 24 : 48,
|
||||
gap: IS_WEB ? 16 : 24,
|
||||
paddingTop: IS_WEB ? 24 : 48,
|
||||
borderTopLeftRadius: a.rounded_md.borderRadius,
|
||||
borderTopRightRadius: a.rounded_md.borderRadius,
|
||||
},
|
||||
@@ -120,7 +120,7 @@ export function ActivitySubscriptionsNUX() {
|
||||
style={[
|
||||
a.align_center,
|
||||
a.px_xl,
|
||||
isWeb ? [a.pt_xl, a.gap_xl, a.pb_sm] : [a.pt_3xl, a.gap_3xl],
|
||||
IS_WEB ? [a.pt_xl, a.gap_xl, a.pb_sm] : [a.pt_3xl, a.gap_3xl],
|
||||
]}>
|
||||
<View style={[a.gap_md, a.align_center]}>
|
||||
<Text
|
||||
@@ -130,7 +130,7 @@ export function ActivitySubscriptionsNUX() {
|
||||
a.font_bold,
|
||||
a.text_center,
|
||||
{
|
||||
fontSize: isWeb ? 28 : 32,
|
||||
fontSize: IS_WEB ? 28 : 32,
|
||||
maxWidth: 300,
|
||||
},
|
||||
]}>
|
||||
@@ -153,7 +153,7 @@ export function ActivitySubscriptionsNUX() {
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{!isWeb && (
|
||||
{!IS_WEB && (
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
size="large"
|
||||
|
||||
@@ -5,7 +5,6 @@ import {LinearGradient} from 'expo-linear-gradient'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {transparentifyColor} from '#/alf/util/colorGeneration'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
@@ -13,6 +12,7 @@ import * as Dialog from '#/components/Dialog'
|
||||
import {useNuxDialogContext} from '#/components/dialogs/nuxs'
|
||||
import {Sparkle_Stroke2_Corner0_Rounded as SparkleIcon} from '#/components/icons/Sparkle'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
export function BookmarksAnnouncement() {
|
||||
const t = useTheme()
|
||||
@@ -49,7 +49,7 @@ export function BookmarksAnnouncement() {
|
||||
a.overflow_hidden,
|
||||
{
|
||||
gap: 16,
|
||||
paddingTop: isWeb ? 24 : 40,
|
||||
paddingTop: IS_WEB ? 24 : 40,
|
||||
borderTopLeftRadius: a.rounded_md.borderRadius,
|
||||
borderTopRightRadius: a.rounded_md.borderRadius,
|
||||
},
|
||||
@@ -90,7 +90,7 @@ export function BookmarksAnnouncement() {
|
||||
borderRadius: 24,
|
||||
aspectRatio: 333 / 104,
|
||||
},
|
||||
isWeb
|
||||
IS_WEB
|
||||
? [
|
||||
{
|
||||
boxShadow: `0px 10px 15px -3px ${transparentifyColor(t.palette.black, 0.2)}`,
|
||||
@@ -136,7 +136,7 @@ export function BookmarksAnnouncement() {
|
||||
a.font_bold,
|
||||
a.text_center,
|
||||
{
|
||||
fontSize: isWeb ? 28 : 32,
|
||||
fontSize: IS_WEB ? 28 : 32,
|
||||
maxWidth: 300,
|
||||
},
|
||||
]}>
|
||||
@@ -158,7 +158,7 @@ export function BookmarksAnnouncement() {
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{!isWeb && (
|
||||
{!IS_WEB && (
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
size="large"
|
||||
|
||||
@@ -6,7 +6,6 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
import {isFindContactsFeatureEnabled} from '#/components/contacts/country-allowlist'
|
||||
@@ -17,13 +16,14 @@ import {
|
||||
isExistingUserAsOf,
|
||||
} from '#/components/dialogs/nuxs/utils'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
import {IS_E2E} from '#/env'
|
||||
import {navigate} from '#/Navigation'
|
||||
|
||||
export const enabled = createIsEnabledCheck(props => {
|
||||
return (
|
||||
!IS_E2E &&
|
||||
isNative &&
|
||||
IS_NATIVE &&
|
||||
isExistingUserAsOf(
|
||||
'2025-12-16T00:00:00.000Z',
|
||||
props.currentProfile.createdAt,
|
||||
@@ -89,7 +89,7 @@ export function FindContactsAnnouncement() {
|
||||
a.font_bold,
|
||||
a.text_center,
|
||||
{
|
||||
fontSize: isWeb ? 28 : 32,
|
||||
fontSize: IS_WEB ? 28 : 32,
|
||||
maxWidth: 300,
|
||||
},
|
||||
]}>
|
||||
|
||||
@@ -6,7 +6,6 @@ import {useLingui} from '@lingui/react'
|
||||
|
||||
import {urls} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
@@ -15,6 +14,7 @@ import {Sparkle_Stroke2_Corner0_Rounded as SparkleIcon} from '#/components/icons
|
||||
import {VerifierCheck} from '#/components/icons/VerifierCheck'
|
||||
import {Link} from '#/components/Link'
|
||||
import {Span, Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export function InitialVerificationAnnouncement() {
|
||||
const t = useTheme()
|
||||
@@ -173,7 +173,7 @@ export function InitialVerificationAnnouncement() {
|
||||
<Trans>Read blog post</Trans>
|
||||
</ButtonText>
|
||||
</Link>
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
size="small"
|
||||
|
||||
@@ -5,7 +5,6 @@ import {LinearGradient} from 'expo-linear-gradient'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a, select, useTheme, utils, web} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
@@ -16,6 +15,7 @@ import {
|
||||
} from '#/components/dialogs/nuxs/utils'
|
||||
import {Beaker_Stroke2_Corner2_Rounded as BeakerIcon} from '#/components/icons/Beaker'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {IS_E2E} from '#/env'
|
||||
|
||||
export const enabled = createIsEnabledCheck(props => {
|
||||
@@ -72,7 +72,7 @@ export function LiveNowBetaDialog() {
|
||||
a.overflow_hidden,
|
||||
{
|
||||
gap: 16,
|
||||
paddingTop: isWeb ? 24 : 40,
|
||||
paddingTop: IS_WEB ? 24 : 40,
|
||||
borderTopLeftRadius: a.rounded_md.borderRadius,
|
||||
borderTopRightRadius: a.rounded_md.borderRadius,
|
||||
},
|
||||
@@ -116,7 +116,7 @@ export function LiveNowBetaDialog() {
|
||||
borderRadius: 24,
|
||||
aspectRatio: 652 / 211,
|
||||
},
|
||||
isWeb
|
||||
IS_WEB
|
||||
? [
|
||||
{
|
||||
boxShadow: `0px 10px 15px -3px ${shadowColor}`,
|
||||
@@ -163,7 +163,7 @@ export function LiveNowBetaDialog() {
|
||||
a.font_bold,
|
||||
a.text_center,
|
||||
{
|
||||
fontSize: isWeb ? 28 : 32,
|
||||
fontSize: IS_WEB ? 28 : 32,
|
||||
maxWidth: 360,
|
||||
},
|
||||
]}>
|
||||
@@ -186,7 +186,7 @@ export function LiveNowBetaDialog() {
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{!isWeb && (
|
||||
{!IS_WEB && (
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
size="large"
|
||||
|
||||
@@ -21,7 +21,7 @@ export function ActionsWrapper({
|
||||
<MessageContextMenu message={message}>
|
||||
{trigger =>
|
||||
// will always be true, since this file is platform split
|
||||
trigger.isNative && (
|
||||
trigger.IS_NATIVE && (
|
||||
<View style={[a.flex_1, a.relative]}>
|
||||
<View
|
||||
style={[
|
||||
|
||||
@@ -89,9 +89,9 @@ export function ActionsWrapper({
|
||||
: [a.ml_xs, {marginRight: 'auto'}],
|
||||
]}>
|
||||
<EmojiReactionPicker message={message} onEmojiSelect={onEmojiSelect}>
|
||||
{({props, state, isNative, control}) => {
|
||||
{({props, state, IS_NATIVE, control}) => {
|
||||
// always false, file is platform split
|
||||
if (isNative) return null
|
||||
if (IS_NATIVE) return null
|
||||
const showMenuTrigger = showActions || control.isOpen ? 1 : 0
|
||||
return (
|
||||
<Pressable
|
||||
@@ -111,9 +111,9 @@ export function ActionsWrapper({
|
||||
}}
|
||||
</EmojiReactionPicker>
|
||||
<MessageContextMenu message={message}>
|
||||
{({props, state, isNative, control}) => {
|
||||
{({props, state, IS_NATIVE, control}) => {
|
||||
// always false, file is platform split
|
||||
if (isNative) return null
|
||||
if (IS_NATIVE) return null
|
||||
const showMenuTrigger = showActions || control.isOpen ? 1 : 0
|
||||
return (
|
||||
<Pressable
|
||||
|
||||
@@ -7,7 +7,6 @@ import {StackActions, useNavigation} from '@react-navigation/native'
|
||||
import type React from 'react'
|
||||
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
|
||||
import {
|
||||
@@ -21,6 +20,7 @@ import * as Dialog from '#/components/Dialog'
|
||||
import * as Toggle from '#/components/forms/Toggle'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
type ReportDialogParams = {
|
||||
convoId: string
|
||||
@@ -130,7 +130,7 @@ function DoneStep({
|
||||
onMutate: () => {
|
||||
if (currentScreen === 'conversation') {
|
||||
navigation.dispatch(
|
||||
StackActions.replace('Messages', isNative ? {animation: 'pop'} : {}),
|
||||
StackActions.replace('Messages', IS_NATIVE ? {animation: 'pop'} : {}),
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -12,9 +12,9 @@ import {useLingui} from '@lingui/react'
|
||||
import {ScaleAndFadeIn} from '#/lib/custom-animations/ScaleAndFade'
|
||||
import {ShrinkAndPop} from '#/lib/custom-animations/ShrinkAndPop'
|
||||
import {useHaptics} from '#/lib/haptics'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
|
||||
|
||||
@@ -41,12 +41,12 @@ export function ChatEmptyPill() {
|
||||
}, [_])
|
||||
|
||||
const onPressIn = React.useCallback(() => {
|
||||
if (isWeb) return
|
||||
if (IS_WEB) return
|
||||
scale.set(() => withTiming(1.075, {duration: 100}))
|
||||
}, [scale])
|
||||
|
||||
const onPressOut = React.useCallback(() => {
|
||||
if (isWeb) return
|
||||
if (IS_WEB) return
|
||||
scale.set(() => withTiming(1, {duration: 100}))
|
||||
}, [scale])
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ import {useLingui} from '@lingui/react'
|
||||
import {StackActions, useNavigation} from '@react-navigation/native'
|
||||
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
|
||||
import * as Toast from '#/view/com/util/Toast'
|
||||
import {type DialogOuterProps} from '#/components/Dialog'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export function LeaveConvoPrompt({
|
||||
control,
|
||||
@@ -27,7 +27,7 @@ export function LeaveConvoPrompt({
|
||||
onMutate: () => {
|
||||
if (currentScreen === 'conversation') {
|
||||
navigation.dispatch(
|
||||
StackActions.replace('Messages', isNative ? {animation: 'pop'} : {}),
|
||||
StackActions.replace('Messages', IS_NATIVE ? {animation: 'pop'} : {}),
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8,7 +8,6 @@ import {useLingui} from '@lingui/react'
|
||||
import {useTranslate} from '#/lib/hooks/useTranslate'
|
||||
import {richTextToString} from '#/lib/strings/rich-text-helpers'
|
||||
import {logger} from '#/logger'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useConvoActive} from '#/state/messages/convo'
|
||||
import {useLanguagePrefs} from '#/state/preferences'
|
||||
import {useSession} from '#/state/session'
|
||||
@@ -23,6 +22,7 @@ import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/War
|
||||
import {ReportDialog} from '#/components/moderation/ReportDialog'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {usePromptControl} from '#/components/Prompt'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {EmojiReactionPicker} from './EmojiReactionPicker'
|
||||
import {hasReachedReactionLimit} from './util'
|
||||
|
||||
@@ -112,7 +112,7 @@ export let MessageContextMenu = ({
|
||||
return (
|
||||
<>
|
||||
<ContextMenu.Root>
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<ContextMenu.AuxiliaryView align={isFromSelf ? 'right' : 'left'}>
|
||||
<EmojiReactionPicker
|
||||
message={message}
|
||||
|
||||
@@ -21,7 +21,6 @@ import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useConvoActive} from '#/state/messages/convo'
|
||||
import {type ConvoItem} from '#/state/messages/convo/types'
|
||||
import {useSession} from '#/state/session'
|
||||
@@ -32,6 +31,7 @@ import {ActionsWrapper} from '#/components/dms/ActionsWrapper'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {DateDivider} from './DateDivider'
|
||||
import {MessageItemEmbed} from './MessageItemEmbed'
|
||||
import {localDateString} from './util'
|
||||
@@ -218,10 +218,10 @@ let MessageItem = ({
|
||||
</View>
|
||||
)}
|
||||
|
||||
{isNative && appliedReactions}
|
||||
{IS_NATIVE && appliedReactions}
|
||||
</ActionsWrapper>
|
||||
|
||||
{!isNative && appliedReactions}
|
||||
{!IS_NATIVE && appliedReactions}
|
||||
|
||||
{isLastInGroup && (
|
||||
<MessageItemMetadata
|
||||
|
||||
@@ -10,7 +10,6 @@ import {useLingui} from '@lingui/react'
|
||||
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {type Shadow} from '#/state/cache/profile-shadow'
|
||||
import {isConvoActive, useConvo} from '#/state/messages/convo'
|
||||
import {type ConvoItem} from '#/state/messages/convo/types'
|
||||
@@ -24,8 +23,9 @@ import {PostAlerts} from '#/components/moderation/PostAlerts'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useSimpleVerificationState} from '#/components/verification'
|
||||
import {VerificationCheck} from '#/components/verification/VerificationCheck'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
const PFP_SIZE = isWeb ? 40 : Layout.HEADER_SLOT_SIZE
|
||||
const PFP_SIZE = IS_WEB ? 40 : Layout.HEADER_SLOT_SIZE
|
||||
|
||||
export function MessagesListHeader({
|
||||
profile,
|
||||
|
||||
@@ -14,9 +14,9 @@ import {
|
||||
ScaleAndFadeOut,
|
||||
} from '#/lib/custom-animations/ScaleAndFade'
|
||||
import {useHaptics} from '#/lib/haptics'
|
||||
import {isAndroid, isIOS, isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_ANDROID, IS_IOS, IS_WEB} from '#/env'
|
||||
|
||||
const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
|
||||
|
||||
@@ -28,18 +28,18 @@ export function NewMessagesPill({
|
||||
const t = useTheme()
|
||||
const playHaptic = useHaptics()
|
||||
const {bottom: bottomInset} = useSafeAreaInsets()
|
||||
const bottomBarHeight = isIOS ? 42 : isAndroid ? 60 : 0
|
||||
const bottomOffset = isWeb ? 0 : bottomInset + bottomBarHeight
|
||||
const bottomBarHeight = IS_IOS ? 42 : IS_ANDROID ? 60 : 0
|
||||
const bottomOffset = IS_WEB ? 0 : bottomInset + bottomBarHeight
|
||||
|
||||
const scale = useSharedValue(1)
|
||||
|
||||
const onPressIn = React.useCallback(() => {
|
||||
if (isWeb) return
|
||||
if (IS_WEB) return
|
||||
scale.set(() => withTiming(1.075, {duration: 100}))
|
||||
}, [scale])
|
||||
|
||||
const onPressOut = React.useCallback(() => {
|
||||
if (isWeb) return
|
||||
if (IS_WEB) return
|
||||
scale.set(() => withTiming(1, {duration: 100}))
|
||||
}, [scale])
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@ import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {HITSLOP_10} from '#/lib/constants'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Button, ButtonIcon} from '#/components/Button'
|
||||
import * as TextField from '#/components/forms/TextField'
|
||||
import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlassIcon} from '#/components/icons/MagnifyingGlass'
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
type SearchInputProps = Omit<TextField.InputProps, 'label'> & {
|
||||
label?: TextField.InputProps['label']
|
||||
@@ -36,7 +36,7 @@ export const SearchInput = React.forwardRef<TextInput, SearchInputProps>(
|
||||
placeholder={_(msg`Search`)}
|
||||
returnKeyType="search"
|
||||
keyboardAppearance={t.scheme}
|
||||
selectTextOnFocus={isNative}
|
||||
selectTextOnFocus={IS_NATIVE}
|
||||
autoFocus={false}
|
||||
accessibilityRole="search"
|
||||
autoCorrect={false}
|
||||
|
||||
@@ -10,7 +10,6 @@ import Animated, {Easing, LinearTransition} from 'react-native-reanimated'
|
||||
|
||||
import {HITSLOP_10} from '#/lib/constants'
|
||||
import {useHaptics} from '#/lib/haptics'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {
|
||||
atoms as a,
|
||||
native,
|
||||
@@ -22,6 +21,7 @@ import {
|
||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||
import {CheckThick_Stroke2_Corner0_Rounded as Checkmark} from '#/components/icons/Check'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export * from './Panel'
|
||||
|
||||
@@ -562,4 +562,4 @@ export function BaseRadio({
|
||||
)
|
||||
}
|
||||
|
||||
export const Platform = isNative ? Switch : Checkbox
|
||||
export const Platform = IS_NATIVE ? Switch : Checkbox
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from 'react'
|
||||
|
||||
import {isFirefox, isSafari} from '#/lib/browser'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
function fullscreenSubscribe(onChange: () => void) {
|
||||
document.addEventListener('fullscreenchange', onChange)
|
||||
@@ -15,7 +15,7 @@ function fullscreenSubscribe(onChange: () => void) {
|
||||
}
|
||||
|
||||
export function useFullscreen(ref?: React.RefObject<HTMLElement | null>) {
|
||||
if (!isWeb) throw new Error("'useFullscreen' is a web-only hook")
|
||||
if (!IS_WEB) throw new Error("'useFullscreen' is a web-only hook")
|
||||
const isFullscreen = useSyncExternalStore(fullscreenSubscribe, () =>
|
||||
Boolean(document.fullscreenElement),
|
||||
)
|
||||
|
||||
@@ -4,9 +4,9 @@ import {
|
||||
createStarterPackLinkFromAndroidReferrer,
|
||||
httpStarterPackUriToAtUri,
|
||||
} from '#/lib/strings/starter-pack'
|
||||
import {isAndroid} from '#/platform/detection'
|
||||
import {useHasCheckedForStarterPack} from '#/state/preferences/used-starter-packs'
|
||||
import {useSetActiveStarterPack} from '#/state/shell/starter-pack'
|
||||
import {IS_ANDROID} from '#/env'
|
||||
import {Referrer, SharedPrefs} from '../../../modules/expo-bluesky-swiss-army'
|
||||
|
||||
export function useStarterPackEntry() {
|
||||
@@ -32,7 +32,7 @@ export function useStarterPackEntry() {
|
||||
;(async () => {
|
||||
let uri: string | null | undefined
|
||||
|
||||
if (isAndroid) {
|
||||
if (IS_ANDROID) {
|
||||
const res = await Referrer.getGooglePlayReferrerInfoAsync()
|
||||
|
||||
if (res && res.installReferrer) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {useEffect, useState} from 'react'
|
||||
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useSession} from '#/state/session'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
export function useWelcomeModal() {
|
||||
const {hasSession} = useSession()
|
||||
@@ -22,7 +22,7 @@ export function useWelcomeModal() {
|
||||
// 2. We're on the web (this is a web-only feature)
|
||||
// 3. We're on the homepage (path is '/' or '/home')
|
||||
// 4. User hasn't actively closed the modal in this session
|
||||
if (isWeb && !hasSession && typeof window !== 'undefined') {
|
||||
if (IS_WEB && !hasSession && typeof window !== 'undefined') {
|
||||
const currentPath = window.location.pathname
|
||||
const isHomePage = currentPath === '/'
|
||||
const hasUserClosedModal =
|
||||
|
||||
@@ -11,12 +11,12 @@ import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {type Dimensions} from '#/lib/media/types'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {ArrowsDiagonalOut_Stroke2_Corner0_Rounded as Fullscreen} from '#/components/icons/ArrowsDiagonal'
|
||||
import {MediaInsetBorder} from '#/components/MediaInsetBorder'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export function ConstrainedImage({
|
||||
aspectRatio,
|
||||
@@ -35,7 +35,7 @@ export function ConstrainedImage({
|
||||
* the height of the image.
|
||||
*/
|
||||
const outerAspectRatio = useMemo<DimensionValue>(() => {
|
||||
const ratio = isNative
|
||||
const ratio = IS_NATIVE
|
||||
? Math.min(1 / aspectRatio, minMobileAspectRatio ?? 16 / 9) // 9:16 bounding box
|
||||
: Math.min(1 / aspectRatio, 1) // 1:1 bounding box
|
||||
return `${ratio * 100}%`
|
||||
|
||||
@@ -3,7 +3,6 @@ import {View} from 'react-native'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
@@ -15,6 +14,7 @@ import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Resend} from '#/c
|
||||
import {useIntentDialogs} from '#/components/intents/IntentDialogs'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export function VerifyEmailIntentDialog() {
|
||||
const {verifyEmailDialogControl: control} = useIntentDialogs()
|
||||
@@ -68,7 +68,7 @@ function Inner({}: {control: DialogControlProps}) {
|
||||
<Loader size="xl" fill={t.atoms.text_contrast_low.color} />
|
||||
</View>
|
||||
) : status === 'success' ? (
|
||||
<View style={[a.gap_sm, isNative && a.pb_xl]}>
|
||||
<View style={[a.gap_sm, IS_NATIVE && a.pb_xl]}>
|
||||
<Text style={[a.font_bold, a.text_2xl]}>
|
||||
<Trans>Email Verified</Trans>
|
||||
</Text>
|
||||
@@ -93,7 +93,7 @@ function Inner({}: {control: DialogControlProps}) {
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
<View style={[a.gap_sm, isNative && a.pb_xl]}>
|
||||
<View style={[a.gap_sm, IS_NATIVE && a.pb_xl]}>
|
||||
<Text style={[a.font_bold, a.text_2xl]}>
|
||||
<Trans>Email Resent</Trans>
|
||||
</Text>
|
||||
|
||||
@@ -12,7 +12,6 @@ import {useLabelInfo} from '#/lib/moderation/useLabelInfo'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {logger} from '#/logger'
|
||||
import {isAndroid} from '#/platform/detection'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import * as Toast from '#/view/com/util/Toast'
|
||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||
@@ -20,6 +19,7 @@ import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_ANDROID} from '#/env'
|
||||
import {Admonition} from '../Admonition'
|
||||
import {Divider} from '../Divider'
|
||||
import {Loader} from '../Loader'
|
||||
@@ -344,7 +344,7 @@ function AppealForm({
|
||||
{isPending && <ButtonIcon icon={Loader} />}
|
||||
</Button>
|
||||
</View>
|
||||
{isAndroid && <View style={{height: 300}} />}
|
||||
{IS_ANDROID && <View style={{height: 300}} />}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,13 +7,13 @@ import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
||||
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {listUriToHref} from '#/lib/strings/url-helpers'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useSession} from '#/state/session'
|
||||
import {atoms as a, useGutters, useTheme} from '#/alf'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import {type AppModerationCause} from '#/components/Pills'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export {useDialogControl as useModerationDetailsDialogControl} from '#/components/Dialog'
|
||||
|
||||
@@ -158,7 +158,7 @@ function ModerationDetailsDialogInner({
|
||||
xGutters,
|
||||
a.py_md,
|
||||
a.border_t,
|
||||
!isNative && t.atoms.bg_contrast_25,
|
||||
!IS_NATIVE && t.atoms.bg_contrast_25,
|
||||
t.atoms.border_contrast_low,
|
||||
{
|
||||
borderBottomLeftRadius: a.rounded_md.borderRadius,
|
||||
@@ -219,7 +219,7 @@ function ModerationDetailsDialogInner({
|
||||
</View>
|
||||
)}
|
||||
|
||||
{isNative && <View style={{height: 40}} />}
|
||||
{IS_NATIVE && <View style={{height: 40}} />}
|
||||
|
||||
<Dialog.Close />
|
||||
</Dialog.ScrollableInner>
|
||||
|
||||
@@ -8,7 +8,6 @@ import {wait} from '#/lib/async/wait'
|
||||
import {getLabelingServiceTitle} from '#/lib/moderation'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {Logger} from '#/logger'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useMyLabelersQuery} from '#/state/queries/preferences'
|
||||
import {CharProgress} from '#/view/com/composer/char-progress/CharProgress'
|
||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||
@@ -29,6 +28,7 @@ import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
||||
import {createStaticClick, InlineLinkText, Link} from '#/components/Link'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {useSubmitReportMutation} from './action'
|
||||
import {
|
||||
BSKY_LABELER_ONLY_REPORT_REASONS,
|
||||
@@ -253,7 +253,7 @@ function Inner(props: ReportDialogProps) {
|
||||
label={_(msg`Report dialog`)}
|
||||
ref={ref}
|
||||
style={[a.w_full, {maxWidth: 500}]}>
|
||||
<View style={[a.gap_2xl, isNative && a.pt_md]}>
|
||||
<View style={[a.gap_2xl, IS_NATIVE && a.pt_md]}>
|
||||
<StepOuter>
|
||||
<StepTitle
|
||||
index={1}
|
||||
|
||||
Vendored
+11
@@ -1,3 +1,4 @@
|
||||
import {Platform} from 'react-native'
|
||||
import {nativeBuildVersion} from 'expo-application'
|
||||
|
||||
import {BUNDLE_IDENTIFIER, IS_TESTFLIGHT, RELEASE_VERSION} from '#/env/common'
|
||||
@@ -17,3 +18,13 @@ export const APP_VERSION = `${RELEASE_VERSION}.${nativeBuildVersion}`
|
||||
export const APP_METADATA = `${BUNDLE_IDENTIFIER.slice(0, 7)} (${
|
||||
__DEV__ ? 'dev' : IS_TESTFLIGHT ? 'tf' : 'prod'
|
||||
})`
|
||||
|
||||
/**
|
||||
* Platform detection
|
||||
*/
|
||||
export const IS_IOS: boolean = Platform.OS === 'ios'
|
||||
export const IS_ANDROID: boolean = Platform.OS === 'android'
|
||||
export const IS_NATIVE: boolean = true
|
||||
export const IS_WEB: boolean = false
|
||||
export const IS_WEB_MOBILE: boolean = false
|
||||
export const IS_WEB_MOBILE_IOS: boolean = false
|
||||
|
||||
Vendored
+13
@@ -13,3 +13,16 @@ export const APP_VERSION = RELEASE_VERSION
|
||||
* The short commit hash and environment of the current bundle.
|
||||
*/
|
||||
export const APP_METADATA = `${BUNDLE_IDENTIFIER.slice(0, 7)} (${__DEV__ ? 'dev' : 'prod'})`
|
||||
|
||||
/**
|
||||
* Platform detection
|
||||
*/
|
||||
export const IS_IOS: boolean = false
|
||||
export const IS_ANDROID: boolean = false
|
||||
export const IS_NATIVE: boolean = false
|
||||
export const IS_WEB: boolean = true
|
||||
// @ts-ignore we know window exists -prf
|
||||
export const IS_WEB_MOBILE: boolean = global.window.matchMedia(
|
||||
'only screen and (max-width: 1300px)',
|
||||
)?.matches
|
||||
export const IS_WEB_MOBILE_IOS: boolean = /iPhone/.test(navigator.userAgent)
|
||||
|
||||
@@ -3,7 +3,6 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {useCleanError} from '#/lib/hooks/useCleanError'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {atoms as a, web} from '#/alf'
|
||||
import {Admonition} from '#/components/Admonition'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
@@ -11,6 +10,7 @@ import * as Dialog from '#/components/Dialog'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Span, Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {useUpdateLiveEventPreferences} from '#/features/liveEvents/preferences'
|
||||
import {
|
||||
type LiveEventFeed,
|
||||
@@ -146,7 +146,7 @@ function Inner({
|
||||
</ButtonText>
|
||||
{isHidingAllFeeds && <ButtonIcon icon={Loader} />}
|
||||
</Button>
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<Button
|
||||
label={_(msg`Cancel`)}
|
||||
size="large"
|
||||
|
||||
@@ -3,12 +3,12 @@ import {type Agent, AppBskyActorDefs, asPredicate} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {
|
||||
preferencesQueryKey,
|
||||
usePreferencesQuery,
|
||||
} from '#/state/queries/preferences'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {IS_WEB} from '#/env'
|
||||
import * as env from '#/env'
|
||||
import {
|
||||
type LiveEventFeed,
|
||||
@@ -41,7 +41,7 @@ function useWebOnlyDebugLiveEventPreferences() {
|
||||
const agent = useAgent()
|
||||
|
||||
useEffect(() => {
|
||||
if (env.IS_DEV && isWeb && typeof window !== 'undefined') {
|
||||
if (env.IS_DEV && IS_WEB && typeof window !== 'undefined') {
|
||||
// @ts-ignore
|
||||
window.__updateLiveEventPreferences = async (
|
||||
action: LiveEventPreferencesAction,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {Platform} from 'react-native'
|
||||
import * as Location from 'expo-location'
|
||||
import {createPermissionHook} from 'expo-modules-core'
|
||||
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import * as debug from '#/geolocation/debug'
|
||||
import {logger} from '#/geolocation/logger'
|
||||
import {type Geolocation} from '#/geolocation/types'
|
||||
@@ -118,7 +118,7 @@ export function useSyncDeviceGeolocationOnStartup(
|
||||
const synced = useRef(false)
|
||||
const [status] = useForegroundPermissions()
|
||||
useEffect(() => {
|
||||
if (!isNative) return
|
||||
if (!IS_NATIVE) return
|
||||
|
||||
async function get() {
|
||||
// no need to set this more than once per session
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {type LocationGeocodedAddress} from 'expo-location'
|
||||
|
||||
import {isAndroid} from '#/platform/detection'
|
||||
import {IS_ANDROID} from '#/env'
|
||||
import {logger} from '#/geolocation/logger'
|
||||
import {type Geolocation} from '#/geolocation/types'
|
||||
|
||||
@@ -81,7 +81,7 @@ export function normalizeDeviceLocation(
|
||||
/*
|
||||
* Android doesn't give us ISO 3166-2 short codes. We need these for US
|
||||
*/
|
||||
if (isAndroid) {
|
||||
if (IS_ANDROID) {
|
||||
if (region && isoCountryCode === 'US') {
|
||||
/*
|
||||
* We need short codes for US states. If we can't remap it, just drop it
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user