Move /platform/detection vars into /env (#9707)
* Add platform vars to env * Replace /platform/detection with /env
This commit is contained in:
@@ -31,7 +31,7 @@ export const SplashScreen = ({
|
||||
}) => {
|
||||
const {_} = useLingui()
|
||||
const t = useTheme()
|
||||
const {isTabletOrMobile: isMobileWeb} = useWebMediaQueries()
|
||||
const {isTabletOrMobile: IS_WEB_MOBILE} = useWebMediaQueries()
|
||||
const [showClipOverlay, setShowClipOverlay] = React.useState(false)
|
||||
|
||||
React.useEffect(() => {
|
||||
@@ -78,7 +78,7 @@ export const SplashScreen = ({
|
||||
a.justify_center,
|
||||
// @ts-expect-error web only
|
||||
{paddingBottom: '20vh'},
|
||||
isMobileWeb && a.pb_5xl,
|
||||
IS_WEB_MOBILE && a.pb_5xl,
|
||||
t.atoms.border_contrast_medium,
|
||||
a.align_center,
|
||||
a.gap_5xl,
|
||||
|
||||
@@ -76,7 +76,6 @@ import {logEvent} from '#/lib/statsig/statsig'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {colors} from '#/lib/styles'
|
||||
import {logger} from '#/logger'
|
||||
import {isAndroid, isIOS, isNative, isWeb} from '#/platform/detection'
|
||||
import {useDialogStateControlContext} from '#/state/dialogs'
|
||||
import {emitPostCreated} from '#/state/events'
|
||||
import {
|
||||
@@ -130,6 +129,7 @@ import {LazyQuoteEmbed} from '#/components/Post/Embed/LazyQuoteEmbed'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text as NewText} from '#/components/Typography'
|
||||
import {IS_ANDROID, IS_IOS, IS_NATIVE, IS_WEB} from '#/env'
|
||||
import {BottomSheetPortalProvider} from '../../../../modules/bottom-sheet'
|
||||
import {PostLanguageSelect} from './select-language/PostLanguageSelect'
|
||||
import {
|
||||
@@ -329,14 +329,14 @@ export const ComposePost = ({
|
||||
const insets = useSafeAreaInsets()
|
||||
const viewStyles = useMemo(
|
||||
() => ({
|
||||
paddingTop: isAndroid ? insets.top : 0,
|
||||
paddingTop: IS_ANDROID ? insets.top : 0,
|
||||
paddingBottom:
|
||||
// iOS - when keyboard is closed, keep the bottom bar in the safe area
|
||||
(isIOS && !isKeyboardVisible) ||
|
||||
(IS_IOS && !isKeyboardVisible) ||
|
||||
// Android - Android >=35 KeyboardAvoidingView adds double padding when
|
||||
// keyboard is closed, so we subtract that in the offset and add it back
|
||||
// here when the keyboard is open
|
||||
(isAndroid && isKeyboardVisible)
|
||||
(IS_ANDROID && isKeyboardVisible)
|
||||
? insets.bottom
|
||||
: 0,
|
||||
}),
|
||||
@@ -366,7 +366,7 @@ export const ComposePost = ({
|
||||
|
||||
// On Android, pressing Back should ask confirmation.
|
||||
useEffect(() => {
|
||||
if (!isAndroid) {
|
||||
if (!IS_ANDROID) {
|
||||
return
|
||||
}
|
||||
const backHandler = BackHandler.addEventListener(
|
||||
@@ -671,7 +671,7 @@ export const ComposePost = ({
|
||||
composerState.mutableNeedsFocusActive = false
|
||||
// On Android, this risks getting the cursor stuck behind the keyboard.
|
||||
// Not worth it.
|
||||
if (!isAndroid) {
|
||||
if (!IS_ANDROID) {
|
||||
textInput.current?.focus()
|
||||
}
|
||||
}
|
||||
@@ -727,12 +727,12 @@ export const ComposePost = ({
|
||||
</>
|
||||
)
|
||||
|
||||
const isWebFooterSticky = !isNative && thread.posts.length > 1
|
||||
const IS_WEBFooterSticky = !IS_NATIVE && thread.posts.length > 1
|
||||
return (
|
||||
<BottomSheetPortalProvider>
|
||||
<KeyboardAvoidingView
|
||||
testID="composePostView"
|
||||
behavior={isIOS ? 'padding' : 'height'}
|
||||
behavior={IS_IOS ? 'padding' : 'height'}
|
||||
keyboardVerticalOffset={keyboardVerticalOffset}
|
||||
style={a.flex_1}>
|
||||
<View
|
||||
@@ -790,13 +790,13 @@ export const ComposePost = ({
|
||||
onPublish={onComposerPostPublish}
|
||||
onError={setError}
|
||||
/>
|
||||
{isWebFooterSticky && post.id === activePost.id && (
|
||||
{IS_WEBFooterSticky && post.id === activePost.id && (
|
||||
<View style={styles.stickyFooterWeb}>{footer}</View>
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</Animated.ScrollView>
|
||||
{!isWebFooterSticky && footer}
|
||||
{!IS_WEBFooterSticky && footer}
|
||||
</View>
|
||||
|
||||
<Prompt.Basic
|
||||
@@ -849,7 +849,7 @@ let ComposerPost = React.memo(function ComposerPost({
|
||||
const {data: currentProfile} = useProfileQuery({did: currentDid})
|
||||
const richtext = post.richtext
|
||||
const isTextOnly = !post.embed.link && !post.embed.quote && !post.embed.media
|
||||
const forceMinHeight = isWeb && isTextOnly && isActive
|
||||
const forceMinHeight = IS_WEB && isTextOnly && isActive
|
||||
const selectTextInputPlaceholder = isReply
|
||||
? isFirstPost
|
||||
? _(msg`Write your reply`)
|
||||
@@ -889,9 +889,9 @@ let ComposerPost = React.memo(function ComposerPost({
|
||||
async (uri: string) => {
|
||||
if (
|
||||
uri.startsWith('data:video/') ||
|
||||
(isWeb && uri.startsWith('data:image/gif'))
|
||||
(IS_WEB && uri.startsWith('data:image/gif'))
|
||||
) {
|
||||
if (isNative) return // web only
|
||||
if (IS_NATIVE) return // web only
|
||||
const [mimeType] = uri.slice('data:'.length).split(';')
|
||||
if (!SUPPORTED_MIME_TYPES.includes(mimeType as SupportedMimeTypes)) {
|
||||
Toast.show(_(msg`Unsupported video type: ${mimeType}`), {
|
||||
@@ -921,9 +921,9 @@ let ComposerPost = React.memo(function ComposerPost({
|
||||
a.mb_sm,
|
||||
!isActive && isLastPost && a.mb_lg,
|
||||
!isActive && styles.inactivePost,
|
||||
isTextOnly && isNative && a.flex_grow,
|
||||
isTextOnly && IS_NATIVE && a.flex_grow,
|
||||
]}>
|
||||
<View style={[a.flex_row, isNative && a.flex_1]}>
|
||||
<View style={[a.flex_row, IS_NATIVE && a.flex_1]}>
|
||||
<UserAvatar
|
||||
avatar={currentProfile?.avatar}
|
||||
size={42}
|
||||
@@ -1241,7 +1241,7 @@ function ComposerEmbeds({
|
||||
</LayoutAnimationConfig>
|
||||
{embed.quote?.uri ? (
|
||||
<View
|
||||
style={[a.pb_sm, video ? [a.pt_md] : [a.pt_xl], isWeb && [a.pb_md]]}>
|
||||
style={[a.pb_sm, video ? [a.pt_md] : [a.pt_xl], IS_WEB && [a.pb_md]]}>
|
||||
<View style={[a.relative]}>
|
||||
<View style={{pointerEvents: 'none'}}>
|
||||
<LazyQuoteEmbed uri={embed.quote.uri} />
|
||||
@@ -1652,7 +1652,7 @@ function useKeyboardVerticalOffset() {
|
||||
const {top, bottom} = useSafeAreaInsets()
|
||||
|
||||
// Android etc
|
||||
if (!isIOS) {
|
||||
if (!IS_IOS) {
|
||||
// need to account for the edge-to-edge nav bar
|
||||
return bottom * -1
|
||||
}
|
||||
@@ -1696,7 +1696,7 @@ function useHideKeyboardOnBackground() {
|
||||
const appState = useAppState()
|
||||
|
||||
useEffect(() => {
|
||||
if (isIOS) {
|
||||
if (IS_IOS) {
|
||||
if (appState === 'inactive') {
|
||||
Keyboard.dismiss()
|
||||
}
|
||||
@@ -1846,7 +1846,7 @@ function ToolbarWrapper({
|
||||
style: StyleProp<ViewStyle>
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
if (isWeb) return children
|
||||
if (IS_WEB) return children
|
||||
return (
|
||||
<Animated.View
|
||||
style={style}
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
type EmbedPlayerParams,
|
||||
parseEmbedPlayerFromUrl,
|
||||
} from '#/lib/strings/embed-player'
|
||||
import {isAndroid} from '#/platform/detection'
|
||||
import {useResolveGifQuery} from '#/state/queries/resolve-link'
|
||||
import {type Gif} from '#/state/queries/tenor'
|
||||
import {AltTextCounterWrapper} from '#/view/com/composer/AltTextCounterWrapper'
|
||||
@@ -23,6 +22,7 @@ import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/ico
|
||||
import {PlusSmall_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
|
||||
import {GifEmbed} from '#/components/Post/Embed/ExternalEmbed/Gif'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_ANDROID} from '#/env'
|
||||
import {AltTextReminder} from './photos/Gallery'
|
||||
|
||||
export function GifAltTextDialog({
|
||||
@@ -224,7 +224,7 @@ function AltTextInner({
|
||||
</View>
|
||||
<Dialog.Close />
|
||||
{/* Maybe fix this later -h */}
|
||||
{isAndroid ? <View style={{height: 300}} /> : null}
|
||||
{IS_ANDROID ? <View style={{height: 300}} /> : null}
|
||||
</Dialog.ScrollableInner>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ import {KeyboardStickyView} from 'react-native-keyboard-controller'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import type React from 'react'
|
||||
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
export function KeyboardAccessory({children}: {children: React.ReactNode}) {
|
||||
const t = useTheme()
|
||||
@@ -22,7 +22,7 @@ export function KeyboardAccessory({children}: {children: React.ReactNode}) {
|
||||
]
|
||||
|
||||
// todo: when iPad support is added, it should also not use the KeyboardStickyView
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
return <View style={style}>{children}</View>
|
||||
}
|
||||
|
||||
|
||||
@@ -11,13 +11,13 @@ import {
|
||||
} from '#/lib/hooks/usePermissions'
|
||||
import {openUnifiedPicker} from '#/lib/media/picker'
|
||||
import {extractDataUriMime} from '#/lib/media/util'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {MAX_IMAGES} from '#/view/com/composer/state/composer'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Button} from '#/components/Button'
|
||||
import {useSheetWrapper} from '#/components/Dialog/sheet-wrapper'
|
||||
import {Image_Stroke2_Corner0_Rounded as ImageIcon} from '#/components/icons/Image'
|
||||
import * as toast from '#/components/Toast'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
export type SelectMediaButtonProps = {
|
||||
disabled?: boolean
|
||||
@@ -91,7 +91,7 @@ const SUPPORTED_IMAGE_MIME_TYPES = (
|
||||
'image/svg+xml',
|
||||
'image/webp',
|
||||
'image/avif',
|
||||
isNative && 'image/heic',
|
||||
IS_NATIVE && 'image/heic',
|
||||
] as const
|
||||
).filter(Boolean)
|
||||
type SupportedImageMimeType = Exclude<
|
||||
@@ -261,7 +261,7 @@ async function processImagePickerAssets(
|
||||
* We don't care too much about mimeType at this point on native,
|
||||
* since the `processVideo` step later on will convert to `.mp4`.
|
||||
*/
|
||||
if (isWeb && !isSupportedVideoMimeType(mimeType)) {
|
||||
if (IS_WEB && !isSupportedVideoMimeType(mimeType)) {
|
||||
errors.add(SelectedAssetError.Unsupported)
|
||||
continue
|
||||
}
|
||||
@@ -271,7 +271,7 @@ async function processImagePickerAssets(
|
||||
* to filter out large files on web. On native, we compress these anyway,
|
||||
* so we only check on web.
|
||||
*/
|
||||
if (isWeb && asset.fileSize && asset.fileSize > VIDEO_MAX_SIZE) {
|
||||
if (IS_WEB && asset.fileSize && asset.fileSize > VIDEO_MAX_SIZE) {
|
||||
errors.add(SelectedAssetError.FileTooBig)
|
||||
continue
|
||||
}
|
||||
@@ -290,7 +290,7 @@ async function processImagePickerAssets(
|
||||
* to filter out large files on web. On native, we compress GIFs as
|
||||
* videos anyway, so we only check on web.
|
||||
*/
|
||||
if (isWeb && asset.fileSize && asset.fileSize > VIDEO_MAX_SIZE) {
|
||||
if (IS_WEB && asset.fileSize && asset.fileSize > VIDEO_MAX_SIZE) {
|
||||
errors.add(SelectedAssetError.FileTooBig)
|
||||
continue
|
||||
}
|
||||
@@ -308,7 +308,7 @@ async function processImagePickerAssets(
|
||||
* base64 data-uri, so we construct it here for web only.
|
||||
*/
|
||||
uri:
|
||||
isWeb && asset.base64
|
||||
IS_WEB && asset.base64
|
||||
? `data:${mimeType};base64,${asset.base64}`
|
||||
: asset.uri,
|
||||
})
|
||||
@@ -327,7 +327,7 @@ async function processImagePickerAssets(
|
||||
}
|
||||
|
||||
if (supportedAssets[0].duration) {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
/*
|
||||
* Web reports duration as seconds
|
||||
*/
|
||||
@@ -432,7 +432,7 @@ export function SelectMediaButton({
|
||||
)
|
||||
|
||||
const onPressSelectMedia = useCallback(async () => {
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
const [photoAccess, videoAccess] = await Promise.all([
|
||||
requestPhotoAccessIfNeeded(),
|
||||
requestVideoAccessIfNeeded(),
|
||||
@@ -446,7 +446,7 @@ export function SelectMediaButton({
|
||||
}
|
||||
}
|
||||
|
||||
if (isNative && Keyboard.isVisible()) {
|
||||
if (IS_NATIVE && Keyboard.isVisible()) {
|
||||
Keyboard.dismiss()
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
type OtherSelfLabel,
|
||||
type SelfLabel,
|
||||
} from '#/lib/moderation'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
@@ -18,6 +17,7 @@ import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
|
||||
import {TinyChevronBottom_Stroke2_Corner0_Rounded as TinyChevronIcon} from '#/components/icons/Chevron'
|
||||
import {Shield_Stroke2_Corner0_Rounded} from '#/components/icons/Shield'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
export function LabelsBtn({
|
||||
labels,
|
||||
@@ -218,7 +218,7 @@ function DialogInner({
|
||||
label={_(msg`Done`)}
|
||||
onPress={() => control.close()}
|
||||
color="primary"
|
||||
size={isWeb ? 'small' : 'large'}
|
||||
size={IS_WEB ? 'small' : 'large'}
|
||||
variant="solid"
|
||||
testID="confirmBtn">
|
||||
<ButtonText>
|
||||
|
||||
@@ -16,12 +16,12 @@ import {useLingui} from '@lingui/react'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {type Dimensions} from '#/lib/media/types'
|
||||
import {colors, s} from '#/lib/styles'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {type ComposerImage, cropImage} from '#/state/gallery'
|
||||
import {Text} from '#/view/com/util/text/Text'
|
||||
import {tokens, useTheme} from '#/alf'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import {MediaInsetBorder} from '#/components/MediaInsetBorder'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {type PostAction} from '../state/composer'
|
||||
import {EditImageDialog} from './EditImageDialog'
|
||||
import {ImageAltTextDialog} from './ImageAltTextDialog'
|
||||
@@ -145,7 +145,7 @@ const GalleryItem = ({
|
||||
const editControl = Dialog.useDialogControl()
|
||||
|
||||
const onImageEdit = () => {
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
cropImage(image).then(next => {
|
||||
onChange(next)
|
||||
})
|
||||
|
||||
@@ -6,7 +6,6 @@ import {useLingui} from '@lingui/react'
|
||||
|
||||
import {MAX_ALT_TEXT} from '#/lib/constants'
|
||||
import {enforceLen} from '#/lib/strings/helpers'
|
||||
import {isAndroid, isWeb} from '#/platform/detection'
|
||||
import {type ComposerImage} from '#/state/gallery'
|
||||
import {AltTextCounterWrapper} from '#/view/com/composer/AltTextCounterWrapper'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
@@ -16,6 +15,7 @@ import {type DialogControlProps} from '#/components/Dialog'
|
||||
import * as TextField from '#/components/forms/TextField'
|
||||
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_ANDROID, IS_WEB} from '#/env'
|
||||
|
||||
type Props = {
|
||||
control: Dialog.DialogOuterProps['control']
|
||||
@@ -66,7 +66,7 @@ const ImageAltTextInner = ({
|
||||
const windim = useWindowDimensions()
|
||||
|
||||
const imageStyle = React.useMemo<ImageStyle>(() => {
|
||||
const maxWidth = isWeb ? 450 : windim.width
|
||||
const maxWidth = IS_WEB ? 450 : windim.width
|
||||
const source = image.transformed ?? image.source
|
||||
|
||||
if (source.height > source.width) {
|
||||
@@ -165,7 +165,7 @@ const ImageAltTextInner = ({
|
||||
</AltTextCounterWrapper>
|
||||
</View>
|
||||
{/* Maybe fix this later -h */}
|
||||
{isAndroid ? <View style={{height: 300}} /> : null}
|
||||
{IS_ANDROID ? <View style={{height: 300}} /> : null}
|
||||
</Dialog.ScrollableInner>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ import {POST_IMG_MAX} from '#/lib/constants'
|
||||
import {useCameraPermission} from '#/lib/hooks/usePermissions'
|
||||
import {openCamera} from '#/lib/media/picker'
|
||||
import {logger} from '#/logger'
|
||||
import {isMobileWeb, isNative} from '#/platform/detection'
|
||||
import {type ComposerImage, createComposerImage} from '#/state/gallery'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Button} from '#/components/Button'
|
||||
import {Camera_Stroke2_Corner0_Rounded as Camera} from '#/components/icons/Camera'
|
||||
import {IS_NATIVE, IS_WEB_MOBILE} from '#/env'
|
||||
|
||||
type Props = {
|
||||
disabled?: boolean
|
||||
@@ -58,7 +58,7 @@ export function OpenCameraBtn({disabled, onAdd}: Props) {
|
||||
requestMediaPermission,
|
||||
])
|
||||
|
||||
const shouldShowCameraButton = isNative || isMobileWeb
|
||||
const shouldShowCameraButton = IS_NATIVE || IS_WEB_MOBILE
|
||||
if (!shouldShowCameraButton) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import {useLingui} from '@lingui/react'
|
||||
|
||||
import {languageName} from '#/locale/helpers'
|
||||
import {type Language, LANGUAGES, LANGUAGES_MAP_CODE2} from '#/locale/languages'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {
|
||||
toPostLanguages,
|
||||
useLanguagePrefs,
|
||||
@@ -21,6 +20,7 @@ import {SearchInput} from '#/components/forms/SearchInput'
|
||||
import * as Toggle from '#/components/forms/Toggle'
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
export function PostLanguageSelectDialog({
|
||||
control,
|
||||
@@ -168,7 +168,7 @@ export function DialogInner({
|
||||
|
||||
const listHeader = (
|
||||
<View
|
||||
style={[a.pb_xs, t.atoms.bg, isNative && a.pt_2xl]}
|
||||
style={[a.pb_xs, t.atoms.bg, IS_NATIVE && a.pt_2xl]}
|
||||
onLayout={evt => setHeaderHeight(evt.nativeEvent.layout.height)}>
|
||||
<View style={[a.flex_row, a.w_full, a.justify_between]}>
|
||||
<View>
|
||||
@@ -195,7 +195,7 @@ export function DialogInner({
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{isWeb && (
|
||||
{IS_WEB && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="small"
|
||||
@@ -252,7 +252,7 @@ export function DialogInner({
|
||||
ListHeaderComponent={listHeader}
|
||||
stickyHeaderIndices={[0]}
|
||||
contentContainerStyle={[a.gap_0]}
|
||||
style={[isNative && a.px_lg, web({paddingBottom: 120})]}
|
||||
style={[IS_NATIVE && a.px_lg, web({paddingBottom: 120})]}
|
||||
scrollIndicatorInsets={{top: headerHeight}}
|
||||
renderItem={({item, index}) => {
|
||||
if (item.type === 'header') {
|
||||
|
||||
@@ -25,13 +25,13 @@ import {isUriImage} from '#/lib/media/util'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {getMentionAt, insertMentionAt} from '#/lib/strings/mention-manip'
|
||||
import {useTheme} from '#/lib/ThemeContext'
|
||||
import {isAndroid, isNative} from '#/platform/detection'
|
||||
import {
|
||||
type LinkFacetMatch,
|
||||
suggestLinkCardUri,
|
||||
} from '#/view/com/composer/text-input/text-input-util'
|
||||
import {atoms as a, useAlf} from '#/alf'
|
||||
import {normalizeTextStyles} from '#/alf/typography'
|
||||
import {IS_ANDROID, IS_NATIVE} from '#/env'
|
||||
import {Autocomplete} from './mobile/Autocomplete'
|
||||
import {type TextInputProps} from './TextInput.types'
|
||||
|
||||
@@ -179,14 +179,14 @@ export function TextInput({
|
||||
/**
|
||||
* PasteInput doesn't like `lineHeight`, results in jumpiness
|
||||
*/
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
style.lineHeight = undefined
|
||||
}
|
||||
|
||||
/*
|
||||
* Android impl of `PasteInput` doesn't support the array syntax for `fontVariant`
|
||||
*/
|
||||
if (isAndroid) {
|
||||
if (IS_ANDROID) {
|
||||
// @ts-ignore
|
||||
style.fontVariant = style.fontVariant
|
||||
? style.fontVariant.join(' ')
|
||||
|
||||
@@ -8,7 +8,6 @@ import deepEqual from 'fast-deep-equal'
|
||||
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {logger} from '#/logger'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings'
|
||||
import {createPostgateRecord} from '#/state/queries/postgate/util'
|
||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||
@@ -25,6 +24,7 @@ import {Earth_Stroke2_Corner0_Rounded as EarthIcon} from '#/components/icons/Glo
|
||||
import {Group3_Stroke2_Corner0_Rounded as GroupIcon} from '#/components/icons/Group'
|
||||
import * as Tooltip from '#/components/Tooltip'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {useThreadgateNudged} from '#/storage/hooks/threadgate-nudged'
|
||||
|
||||
export function ThreadgateBtn({
|
||||
@@ -70,7 +70,7 @@ export function ThreadgateBtn({
|
||||
nudged: tooltipWasShown,
|
||||
})
|
||||
|
||||
if (isNative && Keyboard.isVisible()) {
|
||||
if (IS_NATIVE && Keyboard.isVisible()) {
|
||||
Keyboard.dismiss()
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import {useLingui} from '@lingui/react'
|
||||
import {MAX_ALT_TEXT} from '#/lib/constants'
|
||||
import {isOverMaxGraphemeCount} from '#/lib/strings/helpers'
|
||||
import {LANGUAGES} from '#/locale/languages'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useLanguagePrefs} from '#/state/preferences'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
@@ -17,6 +16,7 @@ import {PageText_Stroke2_Corner0_Rounded as PageTextIcon} from '#/components/ico
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
||||
import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {SubtitleFilePicker} from './SubtitleFilePicker'
|
||||
|
||||
const MAX_NUM_CAPTIONS = 1
|
||||
@@ -37,9 +37,9 @@ export function SubtitleDialogBtn(props: Props) {
|
||||
return (
|
||||
<View style={[a.flex_row, a.my_xs]}>
|
||||
<Button
|
||||
label={isWeb ? _(msg`Captions & alt text`) : _(msg`Alt text`)}
|
||||
label={IS_WEB ? _(msg`Captions & alt text`) : _(msg`Alt text`)}
|
||||
accessibilityHint={
|
||||
isWeb
|
||||
IS_WEB
|
||||
? _(msg`Opens captions and alt text dialog`)
|
||||
: _(msg`Opens alt text dialog`)
|
||||
}
|
||||
@@ -52,7 +52,11 @@ export function SubtitleDialogBtn(props: Props) {
|
||||
}}>
|
||||
<ButtonIcon icon={CCIcon} />
|
||||
<ButtonText>
|
||||
{isWeb ? <Trans>Captions & alt text</Trans> : <Trans>Alt text</Trans>}
|
||||
{IS_WEB ? (
|
||||
<Trans>Captions & alt text</Trans>
|
||||
) : (
|
||||
<Trans>Alt text</Trans>
|
||||
)}
|
||||
</ButtonText>
|
||||
</Button>
|
||||
<Dialog.Outer control={control}>
|
||||
@@ -134,7 +138,7 @@ function SubtitleDialogInner({
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{isWeb && (
|
||||
{IS_WEB && (
|
||||
<>
|
||||
<View
|
||||
style={[
|
||||
@@ -182,7 +186,7 @@ function SubtitleDialogInner({
|
||||
<View style={web([a.flex_row, a.justify_end])}>
|
||||
<Button
|
||||
label={_(msg`Done`)}
|
||||
size={isWeb ? 'small' : 'large'}
|
||||
size={IS_WEB ? 'small' : 'large'}
|
||||
color="primary"
|
||||
variant="solid"
|
||||
onPress={() => {
|
||||
|
||||
@@ -4,8 +4,8 @@ import ProgressPie from 'react-native-progress/Pie'
|
||||
import {type ImagePickerAsset} from 'expo-image-picker'
|
||||
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {ExternalEmbedRemoveBtn} from '../ExternalEmbedRemoveBtn'
|
||||
import {VideoTranscodeBackdrop} from './VideoTranscodeBackdrop'
|
||||
|
||||
@@ -20,7 +20,7 @@ export function VideoTranscodeProgress({
|
||||
}) {
|
||||
const t = useTheme()
|
||||
|
||||
if (isWeb) return null
|
||||
if (IS_WEB) return null
|
||||
|
||||
let aspectRatio = asset.width / asset.height
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
} from '#/lib/hooks/usePermissions'
|
||||
import {openCamera, openUnifiedPicker} from '#/lib/media/picker'
|
||||
import {logger} from '#/logger'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useCurrentAccountProfile} from '#/state/queries/useCurrentAccountProfile'
|
||||
import {MAX_IMAGES} from '#/view/com/composer/state/composer'
|
||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||
@@ -22,6 +21,7 @@ import {Camera_Stroke2_Corner0_Rounded as CameraIcon} from '#/components/icons/C
|
||||
import {Image_Stroke2_Corner0_Rounded as ImageIcon} from '#/components/icons/Image'
|
||||
import {SubtleHover} from '#/components/SubtleHover'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export function ComposerPrompt() {
|
||||
const {_} = useLingui()
|
||||
@@ -43,7 +43,7 @@ export function ComposerPrompt() {
|
||||
logger.metric('composerPrompt:gallery:press', {})
|
||||
|
||||
// On web, open the composer with the gallery picker auto-opening
|
||||
if (!isNative) {
|
||||
if (!IS_NATIVE) {
|
||||
openComposer({openGallery: true})
|
||||
return
|
||||
}
|
||||
@@ -105,7 +105,7 @@ export function ComposerPrompt() {
|
||||
return
|
||||
}
|
||||
|
||||
if (isNative && Keyboard.isVisible()) {
|
||||
if (IS_NATIVE && Keyboard.isVisible()) {
|
||||
Keyboard.dismiss()
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ export function ComposerPrompt() {
|
||||
]
|
||||
|
||||
openComposer({
|
||||
imageUris: isNative ? imageUris : undefined,
|
||||
imageUris: IS_NATIVE ? imageUris : undefined,
|
||||
})
|
||||
} catch (err: any) {
|
||||
if (!String(err).toLowerCase().includes('cancel')) {
|
||||
@@ -189,7 +189,7 @@ export function ComposerPrompt() {
|
||||
<Trans>What's up?</Trans>
|
||||
</Text>
|
||||
<View style={[a.flex_row, a.gap_md]}>
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<Button
|
||||
onPress={e => {
|
||||
e.stopPropagation()
|
||||
|
||||
@@ -20,7 +20,6 @@ import {getRootNavigation, getTabState, TabState} from '#/lib/routes/helpers'
|
||||
import {type AllNavigatorParams} from '#/lib/routes/types'
|
||||
import {logEvent} from '#/lib/statsig/statsig'
|
||||
import {s} from '#/lib/styles'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {listenSoftReset} from '#/state/events'
|
||||
import {FeedFeedbackProvider, useFeedFeedback} from '#/state/feed-feedback'
|
||||
import {useSetHomeBadge} from '#/state/home-badge'
|
||||
@@ -34,6 +33,7 @@ import {truncateAndInvalidate} from '#/state/queries/util'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useSetMinimalShellMode} from '#/state/shell'
|
||||
import {useHeaderOffset} from '#/components/hooks/useHeaderOffset'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {PostFeed} from '../posts/PostFeed'
|
||||
import {FAB} from '../util/fab/FAB'
|
||||
import {type ListMethods} from '../util/List'
|
||||
@@ -80,7 +80,7 @@ export function FeedPage({
|
||||
const feedIsVideoMode =
|
||||
feedInfo.contentMode === AppBskyFeedDefs.CONTENTMODEVIDEO
|
||||
const _isVideoFeed = isBskyVideoFeed || feedIsVideoMode
|
||||
return isNative && _isVideoFeed
|
||||
return IS_NATIVE && _isVideoFeed
|
||||
}, [feedInfo])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -91,7 +91,7 @@ export function FeedPage({
|
||||
|
||||
const scrollToTop = useCallback(() => {
|
||||
scrollElRef.current?.scrollToOffset({
|
||||
animated: isNative,
|
||||
animated: IS_NATIVE,
|
||||
offset: -headerOffset,
|
||||
})
|
||||
setMinimalShellMode(false)
|
||||
@@ -136,7 +136,7 @@ export function FeedPage({
|
||||
})
|
||||
}, [scrollToTop, feed, queryClient])
|
||||
|
||||
const shouldPrefetch = isNative && isPageAdjacent
|
||||
const shouldPrefetch = IS_NATIVE && isPageAdjacent
|
||||
const isDiscoverFeed = feedInfo.uri === DISCOVER_FEED_URI
|
||||
return (
|
||||
<View
|
||||
|
||||
@@ -4,7 +4,6 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {getFeedTypeFromUri} from '#/state/queries/feed'
|
||||
import {useProfileQuery} from '#/state/queries/profile'
|
||||
@@ -15,6 +14,7 @@ import {Divider} from '#/components/Divider'
|
||||
import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
|
||||
import * as ProfileCard from '#/components/ProfileCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
export function MissingFeed({
|
||||
style,
|
||||
@@ -83,7 +83,7 @@ export function MissingFeed({
|
||||
a.italic,
|
||||
]}
|
||||
numberOfLines={1}>
|
||||
{isWeb ? (
|
||||
{IS_WEB ? (
|
||||
<Trans>Click for information</Trans>
|
||||
) : (
|
||||
<Trans>Tap for information</Trans>
|
||||
@@ -205,7 +205,7 @@ function DialogInner({
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<Button
|
||||
label={_(msg`Close`)}
|
||||
onPress={() => control.close()}
|
||||
|
||||
@@ -20,7 +20,6 @@ import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS, isNative, isWeb} from '#/platform/detection'
|
||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||
import {RQKEY, useProfileFeedgensQuery} from '#/state/queries/profile-feedgens'
|
||||
import {useSession} from '#/state/session'
|
||||
@@ -33,6 +32,7 @@ import {atoms as a, ios, useTheme} from '#/alf'
|
||||
import * as FeedCard from '#/components/FeedCard'
|
||||
import {HashtagWide_Stroke1_Corner0_Rounded as HashtagWideIcon} from '#/components/icons/Hashtag'
|
||||
import {ListFooter} from '#/components/Lists'
|
||||
import {IS_IOS, IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
const LOADING = {_reactKey: '__loading__'}
|
||||
const EMPTY = {_reactKey: '__empty__'}
|
||||
@@ -111,7 +111,7 @@ export function ProfileFeedgens({
|
||||
|
||||
const onScrollToTop = useCallback(() => {
|
||||
scrollElRef.current?.scrollToOffset({
|
||||
animated: isNative,
|
||||
animated: IS_NATIVE,
|
||||
offset: -headerOffset,
|
||||
})
|
||||
queryClient.invalidateQueries({queryKey: RQKEY(did)})
|
||||
@@ -194,7 +194,7 @@ export function ProfileFeedgens({
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
(index !== 0 || isWeb) && a.border_t,
|
||||
(index !== 0 || IS_WEB) && a.border_t,
|
||||
t.atoms.border_contrast_low,
|
||||
a.px_lg,
|
||||
a.py_lg,
|
||||
@@ -218,7 +218,7 @@ export function ProfileFeedgens({
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (isIOS && enabled && scrollElRef.current) {
|
||||
if (IS_IOS && enabled && scrollElRef.current) {
|
||||
const nativeTag = findNodeHandle(scrollElRef.current)
|
||||
setScrollViewTag(nativeTag)
|
||||
}
|
||||
|
||||
@@ -41,13 +41,13 @@ import {Trans} from '@lingui/macro'
|
||||
|
||||
import {type Dimensions} from '#/lib/media/types'
|
||||
import {colors, s} from '#/lib/styles'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {type Lightbox} from '#/state/lightbox'
|
||||
import {Button} from '#/view/com/util/forms/Button'
|
||||
import {Text} from '#/view/com/util/text/Text'
|
||||
import {ScrollView} from '#/view/com/util/Views'
|
||||
import {useTheme} from '#/alf'
|
||||
import {setSystemUITheme} from '#/alf/util/systemUI'
|
||||
import {IS_IOS} from '#/env'
|
||||
import {PlatformInfo} from '../../../../../modules/expo-bluesky-swiss-army'
|
||||
import {type ImageSource, type Transform} from './@types'
|
||||
import ImageDefaultHeader from './components/ImageDefaultHeader'
|
||||
@@ -59,13 +59,13 @@ const PORTRAIT_UP = ScreenOrientation.OrientationLock.PORTRAIT_UP
|
||||
const PIXEL_RATIO = PixelRatio.get()
|
||||
|
||||
const SLOW_SPRING: WithSpringConfig = {
|
||||
mass: isIOS ? 1.25 : 0.75,
|
||||
mass: IS_IOS ? 1.25 : 0.75,
|
||||
damping: 300,
|
||||
stiffness: 800,
|
||||
restDisplacementThreshold: 0.01,
|
||||
}
|
||||
const FAST_SPRING: WithSpringConfig = {
|
||||
mass: isIOS ? 1.25 : 0.75,
|
||||
mass: IS_IOS ? 1.25 : 0.75,
|
||||
damping: 150,
|
||||
stiffness: 900,
|
||||
restDisplacementThreshold: 0.01,
|
||||
@@ -248,7 +248,7 @@ function ImageView({
|
||||
)
|
||||
opacity -= dragProgress
|
||||
}
|
||||
const factor = isIOS ? 100 : 50
|
||||
const factor = IS_IOS ? 100 : 50
|
||||
return {
|
||||
opacity: Math.round(opacity * factor) / factor,
|
||||
}
|
||||
@@ -686,7 +686,7 @@ const styles = StyleSheet.create({
|
||||
maxHeight: '100%',
|
||||
},
|
||||
footerText: {
|
||||
paddingBottom: isIOS ? 20 : 16,
|
||||
paddingBottom: IS_IOS ? 20 : 16,
|
||||
},
|
||||
footerBtns: {
|
||||
flexDirection: 'row',
|
||||
|
||||
@@ -20,7 +20,6 @@ import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS, isNative, isWeb} from '#/platform/detection'
|
||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||
import {RQKEY, useProfileListsQuery} from '#/state/queries/profile-lists'
|
||||
import {useSession} from '#/state/session'
|
||||
@@ -33,6 +32,7 @@ import {atoms as a, ios, useTheme} from '#/alf'
|
||||
import {BulletList_Stroke1_Corner0_Rounded as ListIcon} from '#/components/icons/BulletList'
|
||||
import * as ListCard from '#/components/ListCard'
|
||||
import {ListFooter} from '#/components/Lists'
|
||||
import {IS_IOS, IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
const LOADING = {_reactKey: '__loading__'}
|
||||
const EMPTY = {_reactKey: '__empty__'}
|
||||
@@ -111,7 +111,7 @@ export function ProfileLists({
|
||||
|
||||
const onScrollToTop = useCallback(() => {
|
||||
scrollElRef.current?.scrollToOffset({
|
||||
animated: isNative,
|
||||
animated: IS_NATIVE,
|
||||
offset: -headerOffset,
|
||||
})
|
||||
queryClient.invalidateQueries({queryKey: RQKEY(did)})
|
||||
@@ -193,7 +193,7 @@ export function ProfileLists({
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
(index !== 0 || isWeb) && a.border_t,
|
||||
(index !== 0 || IS_WEB) && a.border_t,
|
||||
t.atoms.border_contrast_low,
|
||||
a.px_lg,
|
||||
a.py_lg,
|
||||
@@ -217,7 +217,7 @@ export function ProfileLists({
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (isIOS && enabled && scrollElRef.current) {
|
||||
if (IS_IOS && enabled && scrollElRef.current) {
|
||||
const nativeTag = findNodeHandle(scrollElRef.current)
|
||||
setScrollViewTag(nativeTag)
|
||||
}
|
||||
|
||||
@@ -16,19 +16,19 @@ import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {colors, gradients, s} from '#/lib/styles'
|
||||
import {useTheme} from '#/lib/ThemeContext'
|
||||
import {isAndroid, isWeb} from '#/platform/detection'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {useAgent, useSession, useSessionApi} from '#/state/session'
|
||||
import {atoms as a, useTheme as useNewTheme} from '#/alf'
|
||||
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
||||
import {Text as NewText} from '#/components/Typography'
|
||||
import {IS_ANDROID, IS_WEB} from '#/env'
|
||||
import {resetToTab} from '../../../Navigation'
|
||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||
import {Text} from '../util/text/Text'
|
||||
import * as Toast from '../util/Toast'
|
||||
import {ScrollView, TextInput} from './util'
|
||||
|
||||
export const snapPoints = isAndroid ? ['90%'] : ['55%']
|
||||
export const snapPoints = IS_ANDROID ? ['90%'] : ['55%']
|
||||
|
||||
export function Component({}: {}) {
|
||||
const pal = usePalette('default')
|
||||
@@ -173,7 +173,7 @@ export function Component({}: {}) {
|
||||
</>
|
||||
)}
|
||||
|
||||
<View style={[!isWeb && a.px_xl]}>
|
||||
<View style={[!IS_WEB && a.px_xl]}>
|
||||
<View
|
||||
style={[
|
||||
a.w_full,
|
||||
|
||||
@@ -14,7 +14,6 @@ import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {s} from '#/lib/styles'
|
||||
import {isAndroid, isMobileWeb, isWeb} from '#/platform/detection'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {
|
||||
getMembership,
|
||||
@@ -24,6 +23,7 @@ import {
|
||||
useListMembershipRemoveMutation,
|
||||
} from '#/state/queries/list-memberships'
|
||||
import {useSession} from '#/state/session'
|
||||
import {IS_ANDROID, IS_WEB, IS_WEB_MOBILE} from '#/env'
|
||||
import {MyLists} from '../lists/MyLists'
|
||||
import {Button} from '../util/forms/Button'
|
||||
import {Text} from '../util/text/Text'
|
||||
@@ -56,9 +56,9 @@ export function Component({
|
||||
}, [closeModal])
|
||||
|
||||
const listStyle = React.useMemo(() => {
|
||||
if (isMobileWeb) {
|
||||
if (IS_WEB_MOBILE) {
|
||||
return [pal.border, {height: screenHeight / 2}]
|
||||
} else if (isWeb) {
|
||||
} else if (IS_WEB) {
|
||||
return [pal.border, {height: screenHeight / 1.5}]
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ function ListItem({
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
paddingHorizontal: isWeb ? 0 : 16,
|
||||
paddingHorizontal: IS_WEB ? 0 : 16,
|
||||
},
|
||||
btns: {
|
||||
position: 'relative',
|
||||
@@ -252,7 +252,7 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
gap: 10,
|
||||
paddingTop: 10,
|
||||
paddingBottom: isAndroid ? 10 : 0,
|
||||
paddingBottom: IS_ANDROID ? 10 : 0,
|
||||
borderTopWidth: StyleSheet.hairlineWidth,
|
||||
},
|
||||
footerBtn: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, {useContext} from 'react'
|
||||
import {type SharedValue} from 'react-native-reanimated'
|
||||
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
|
||||
export const PagerHeaderContext = React.createContext<{
|
||||
scrollY: SharedValue<number>
|
||||
@@ -37,7 +37,7 @@ export function PagerHeaderProvider({
|
||||
|
||||
export function usePagerHeaderContext() {
|
||||
const ctx = useContext(PagerHeaderContext)
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
if (!ctx) {
|
||||
throw new Error(
|
||||
'usePagerHeaderContext must be used within a HeaderProvider',
|
||||
|
||||
@@ -18,13 +18,13 @@ import Animated, {
|
||||
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {ScrollProvider} from '#/lib/ScrollContext'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {
|
||||
Pager,
|
||||
type PagerRef,
|
||||
type RenderTabBarFnProps,
|
||||
} from '#/view/com/pager/Pager'
|
||||
import {useTheme} from '#/alf'
|
||||
import {IS_IOS} from '#/env'
|
||||
import {type ListMethods} from '../util/List'
|
||||
import {PagerHeaderProvider} from './PagerHeaderContext'
|
||||
import {TabBar} from './TabBar'
|
||||
@@ -273,11 +273,11 @@ let PagerTabBar = ({
|
||||
const headerRef = useRef(null)
|
||||
return (
|
||||
<Animated.View
|
||||
pointerEvents={isIOS ? 'auto' : 'box-none'}
|
||||
pointerEvents={IS_IOS ? 'auto' : 'box-none'}
|
||||
style={[styles.tabBarMobile, headerTransform, t.atoms.bg]}>
|
||||
<View
|
||||
ref={headerRef}
|
||||
pointerEvents={isIOS ? 'auto' : 'box-none'}
|
||||
pointerEvents={IS_IOS ? 'auto' : 'box-none'}
|
||||
collapsable={false}>
|
||||
{renderHeader?.({setMinimumHeight: setMinimumHeaderHeight})}
|
||||
{
|
||||
|
||||
@@ -13,9 +13,9 @@ import {MagnifyingGlassIcon} from '#/lib/icons'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {s} from '#/lib/styles'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useFeedFeedbackContext} from '#/state/feed-feedback'
|
||||
import {useSession} from '#/state/session'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {Button} from '../util/forms/Button'
|
||||
import {Text} from '../util/text/Text'
|
||||
|
||||
@@ -44,7 +44,7 @@ export function CustomFeedEmptyState() {
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
|
||||
const onPressFindAccounts = React.useCallback(() => {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
navigation.navigate('Search', {})
|
||||
} else {
|
||||
navigation.navigate('SearchTab')
|
||||
|
||||
@@ -11,7 +11,7 @@ import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {MagnifyingGlassIcon} from '#/lib/icons'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {s} from '#/lib/styles'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {Button} from '../util/forms/Button'
|
||||
import {Text} from '../util/text/Text'
|
||||
|
||||
@@ -21,7 +21,7 @@ export function FollowingEmptyState() {
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
|
||||
const onPressFindAccounts = React.useCallback(() => {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
navigation.navigate('Search', {})
|
||||
} else {
|
||||
navigation.navigate('SearchTab')
|
||||
|
||||
@@ -10,7 +10,7 @@ import {useNavigation} from '@react-navigation/native'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {s} from '#/lib/styles'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {Button} from '../util/forms/Button'
|
||||
import {Text} from '../util/text/Text'
|
||||
|
||||
@@ -20,7 +20,7 @@ export function FollowingEndOfFeed() {
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
|
||||
const onPressFindAccounts = React.useCallback(() => {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
navigation.navigate('Search', {})
|
||||
} else {
|
||||
navigation.navigate('SearchTab')
|
||||
|
||||
@@ -34,7 +34,6 @@ import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {logEvent, useGate} from '#/lib/statsig/statsig'
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS, isNative, isWeb} from '#/platform/detection'
|
||||
import {usePostAuthorShadowFilter} from '#/state/cache/profile-shadow'
|
||||
import {listenPostCreated} from '#/state/events'
|
||||
import {useFeedFeedbackContext} from '#/state/feed-feedback'
|
||||
@@ -70,6 +69,7 @@ import {
|
||||
} from '#/components/feeds/PostFeedVideoGridRow'
|
||||
import {TrendingInterstitial} from '#/components/interstitials/Trending'
|
||||
import {TrendingVideos as TrendingVideosInterstitial} from '#/components/interstitials/TrendingVideos'
|
||||
import {IS_IOS, IS_NATIVE, IS_WEB} from '#/env'
|
||||
import {DiscoverFeedLiveEventFeedsAndTrendingBanner} from '#/features/liveEvents/components/DiscoverFeedLiveEventFeedsAndTrendingBanner'
|
||||
import {ComposerPrompt} from '../feeds/ComposerPrompt'
|
||||
import {DiscoverFallbackHeader} from './DiscoverFallbackHeader'
|
||||
@@ -243,7 +243,7 @@ let PostFeed = ({
|
||||
const [feedType, feedUriOrActorDid, feedTab] = feed.split('|')
|
||||
const {gtMobile} = useBreakpoints()
|
||||
const {rightNavVisible} = useLayoutBreakpoints()
|
||||
const areVideoFeedsEnabled = isNative
|
||||
const areVideoFeedsEnabled = IS_NATIVE
|
||||
|
||||
const [hasPressedShowLessUris, setHasPressedShowLessUris] = useState(
|
||||
() => new Set<string>(),
|
||||
@@ -873,7 +873,7 @@ let PostFeed = ({
|
||||
* reach the end, so that content isn't cut off by the bottom of the
|
||||
* screen.
|
||||
*/
|
||||
const offset = Math.max(headerOffset, 32) * (isWeb ? 1 : 2)
|
||||
const offset = Math.max(headerOffset, 32) * (IS_WEB ? 1 : 2)
|
||||
|
||||
return isFetchingNextPage ? (
|
||||
<View style={[styles.feedFooter]}>
|
||||
@@ -1024,7 +1024,7 @@ let PostFeed = ({
|
||||
}
|
||||
initialNumToRender={initialNumToRenderOverride ?? initialNumToRender}
|
||||
windowSize={9}
|
||||
maxToRenderPerBatch={isIOS ? 5 : 1}
|
||||
maxToRenderPerBatch={IS_IOS ? 5 : 1}
|
||||
updateCellsBatchingPeriod={40}
|
||||
onItemSeen={onItemSeen}
|
||||
/>
|
||||
|
||||
@@ -8,13 +8,13 @@ import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useProfileFollowsQuery} from '#/state/queries/profile-follows'
|
||||
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
|
||||
import {useSession} from '#/state/session'
|
||||
import {FindContactsBannerNUX} from '#/components/contacts/FindContactsBannerNUX'
|
||||
import {PeopleRemove2_Stroke1_Corner0_Rounded as PeopleRemoveIcon} from '#/components/icons/PeopleRemove2'
|
||||
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {List} from '../util/List'
|
||||
import {ProfileCardWithFollowBtn} from './ProfileCard'
|
||||
|
||||
@@ -49,7 +49,7 @@ export function ProfileFollows({name}: {name: string}) {
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
|
||||
const onPressFindAccounts = React.useCallback(() => {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
navigation.navigate('Search', {})
|
||||
} else {
|
||||
navigation.navigate('SearchTab')
|
||||
|
||||
@@ -12,7 +12,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 {type Shadow} from '#/state/cache/types'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {Nux, useNux, useSaveNux} from '#/state/queries/nuxs'
|
||||
@@ -61,6 +60,7 @@ import * as Prompt from '#/components/Prompt'
|
||||
import {useFullVerificationState} from '#/components/verification'
|
||||
import {VerificationCreatePrompt} from '#/components/verification/VerificationCreatePrompt'
|
||||
import {VerificationRemovePrompt} from '#/components/verification/VerificationRemovePrompt'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {Dot} from '#/features/nuxs/components/Dot'
|
||||
import {Gradient} from '#/features/nuxs/components/Gradient'
|
||||
import {useDevMode} from '#/storage/hooks/dev-mode'
|
||||
@@ -266,7 +266,7 @@ let ProfileMenu = ({
|
||||
<Menu.Item
|
||||
testID="profileHeaderDropdownShareBtn"
|
||||
label={
|
||||
isWeb ? _(msg`Copy link to profile`) : _(msg`Share via...`)
|
||||
IS_WEB ? _(msg`Copy link to profile`) : _(msg`Share via...`)
|
||||
}
|
||||
onPress={() => {
|
||||
if (showLoggedOutWarning) {
|
||||
@@ -276,13 +276,15 @@ let ProfileMenu = ({
|
||||
}
|
||||
}}>
|
||||
<Menu.ItemText>
|
||||
{isWeb ? (
|
||||
{IS_WEB ? (
|
||||
<Trans>Copy link to profile</Trans>
|
||||
) : (
|
||||
<Trans>Share via...</Trans>
|
||||
)}
|
||||
</Menu.ItemText>
|
||||
<Menu.ItemIcon icon={isWeb ? ChainLinkIcon : ArrowOutOfBoxIcon} />
|
||||
<Menu.ItemIcon
|
||||
icon={IS_WEB ? ChainLinkIcon : ArrowOutOfBoxIcon}
|
||||
/>
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
testID="profileHeaderDropdownSearchBtn"
|
||||
@@ -382,7 +384,7 @@ let ProfileMenu = ({
|
||||
a.flex_0,
|
||||
{
|
||||
color: t.palette.primary_500,
|
||||
right: isWeb ? -8 : -4,
|
||||
right: IS_WEB ? -8 : -4,
|
||||
},
|
||||
]}>
|
||||
<Trans>New</Trans>
|
||||
|
||||
@@ -25,12 +25,12 @@ import {
|
||||
linkRequiresWarning,
|
||||
} from '#/lib/strings/url-helpers'
|
||||
import {type TypographyVariant} from '#/lib/ThemeContext'
|
||||
import {isAndroid, isWeb} from '#/platform/detection'
|
||||
import {emitSoftReset} from '#/state/events'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {WebAuxClickWrapper} from '#/view/com/util/WebAuxClickWrapper'
|
||||
import {useTheme} from '#/alf'
|
||||
import {useGlobalDialogsControlContext} from '#/components/dialogs/Context'
|
||||
import {IS_ANDROID, IS_WEB} from '#/env'
|
||||
import {router} from '../../../routes'
|
||||
import {PressableWithHover} from './PressableWithHover'
|
||||
import {Text} from './text/Text'
|
||||
@@ -130,7 +130,7 @@ export const Link = memo(function Link({
|
||||
android_ripple={{
|
||||
color: t.atoms.bg_contrast_25.backgroundColor,
|
||||
}}
|
||||
unstable_pressDelay={isAndroid ? 90 : undefined}>
|
||||
unstable_pressDelay={IS_ANDROID ? 90 : undefined}>
|
||||
{/* @ts-ignore web only -prf */}
|
||||
<View style={style} href={anchorHref}>
|
||||
{children ? children : <Text>{title || 'link'}</Text>}
|
||||
@@ -219,7 +219,7 @@ export const TextLink = memo(function TextLink({
|
||||
})
|
||||
}
|
||||
if (
|
||||
isWeb &&
|
||||
IS_WEB &&
|
||||
href !== '#' &&
|
||||
e != null &&
|
||||
isModifiedEvent(e as React.MouseEvent)
|
||||
@@ -323,7 +323,7 @@ export const TextLinkOnWebOnly = memo(function DesktopWebTextLink({
|
||||
onBeforePress,
|
||||
...props
|
||||
}: TextLinkOnWebOnlyProps) {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
return (
|
||||
<TextLink
|
||||
testID={testID}
|
||||
|
||||
@@ -11,9 +11,9 @@ import {updateActiveVideoViewAsync} from '@haileyok/bluesky-video'
|
||||
import {useDedupe} from '#/lib/hooks/useDedupe'
|
||||
import {useScrollHandlers} from '#/lib/ScrollContext'
|
||||
import {addStyle} from '#/lib/styles'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
import {useLightbox} from '#/state/lightbox'
|
||||
import {useTheme} from '#/alf'
|
||||
import {IS_IOS} from '#/env'
|
||||
import {FlatList_INTERNAL} from './Views'
|
||||
|
||||
export type ListMethods = FlatList_INTERNAL
|
||||
@@ -94,7 +94,7 @@ let List = React.forwardRef<ListMethods, ListProps>(
|
||||
}
|
||||
}
|
||||
|
||||
if (isIOS) {
|
||||
if (IS_IOS) {
|
||||
runOnJS(dedupe)(updateActiveVideoViewAsync)
|
||||
}
|
||||
},
|
||||
@@ -184,7 +184,7 @@ export {List}
|
||||
|
||||
// We only want to use this context value on iOS because the `scrollsToTop` prop is iOS-only
|
||||
// removing it saves us a re-render on Android
|
||||
const useAllowScrollToTop = isIOS ? useAllowScrollToTopIOS : () => undefined
|
||||
const useAllowScrollToTop = IS_IOS ? useAllowScrollToTopIOS : () => undefined
|
||||
function useAllowScrollToTopIOS() {
|
||||
const {activeLightbox} = useLightbox()
|
||||
return !activeLightbox
|
||||
|
||||
@@ -9,9 +9,9 @@ import {
|
||||
import EventEmitter from 'eventemitter3'
|
||||
|
||||
import {ScrollProvider} from '#/lib/ScrollContext'
|
||||
import {isNative, isWeb} from '#/platform/detection'
|
||||
import {useMinimalShellMode} from '#/state/shell'
|
||||
import {useShellLayout} from '#/state/shell/shell-layout'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
|
||||
const WEB_HIDE_SHELL_THRESHOLD = 200
|
||||
|
||||
@@ -35,7 +35,7 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
return listenToForcedWindowScroll(() => {
|
||||
startDragOffset.set(null)
|
||||
startMode.set(null)
|
||||
@@ -48,7 +48,7 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
|
||||
(e: NativeScrollEvent) => {
|
||||
'worklet'
|
||||
const offsetY = Math.max(0, e.contentOffset.y)
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
const startDragOffsetValue = startDragOffset.get()
|
||||
if (startDragOffsetValue === null) {
|
||||
return
|
||||
@@ -75,7 +75,7 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
|
||||
(e: NativeScrollEvent) => {
|
||||
'worklet'
|
||||
const offsetY = Math.max(0, e.contentOffset.y)
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
startDragOffset.set(offsetY)
|
||||
startMode.set(headerMode.get())
|
||||
}
|
||||
@@ -86,7 +86,7 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
|
||||
const onEndDrag = useCallback(
|
||||
(e: NativeScrollEvent) => {
|
||||
'worklet'
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
if (e.velocity && e.velocity.y !== 0) {
|
||||
// If we detect a velocity, wait for onMomentumEnd to snap.
|
||||
return
|
||||
@@ -100,7 +100,7 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
|
||||
const onMomentumEnd = useCallback(
|
||||
(e: NativeScrollEvent) => {
|
||||
'worklet'
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
snapToClosestState(e)
|
||||
}
|
||||
},
|
||||
@@ -111,7 +111,7 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
|
||||
(e: NativeScrollEvent) => {
|
||||
'worklet'
|
||||
const offsetY = Math.max(0, e.contentOffset.y)
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
const startDragOffsetValue = startDragOffset.get()
|
||||
const startModeValue = startMode.get()
|
||||
if (startDragOffsetValue === null || startModeValue === null) {
|
||||
@@ -177,7 +177,7 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
|
||||
|
||||
const emitter = new EventEmitter()
|
||||
|
||||
if (isWeb) {
|
||||
if (IS_WEB) {
|
||||
const originalScroll = window.scroll
|
||||
window.scroll = function () {
|
||||
emitter.emit('forced-scroll')
|
||||
|
||||
@@ -12,7 +12,6 @@ import {NON_BREAKING_SPACE} from '#/lib/strings/constants'
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {niceDate} from '#/lib/strings/time'
|
||||
import {isAndroid} from '#/platform/detection'
|
||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {precacheProfile} from '#/state/queries/profile'
|
||||
import {atoms as a, platform, useTheme, web} from '#/alf'
|
||||
@@ -21,6 +20,7 @@ import {ProfileHoverCard} from '#/components/ProfileHoverCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useSimpleVerificationState} from '#/components/verification'
|
||||
import {VerificationCheck} from '#/components/verification/VerificationCheck'
|
||||
import {IS_ANDROID} from '#/env'
|
||||
import {TimeElapsed} from './TimeElapsed'
|
||||
import {PreviewableUserAvatar} from './UserAvatar'
|
||||
|
||||
@@ -152,14 +152,14 @@ let PostMeta = (opts: PostMetaOpts): React.ReactNode => {
|
||||
a.pl_xs,
|
||||
a.text_md,
|
||||
a.leading_tight,
|
||||
isAndroid && a.flex_grow,
|
||||
IS_ANDROID && a.flex_grow,
|
||||
a.text_right,
|
||||
t.atoms.text_contrast_medium,
|
||||
web({
|
||||
whiteSpace: 'nowrap',
|
||||
}),
|
||||
]}>
|
||||
{!isAndroid && (
|
||||
{!IS_ANDROID && (
|
||||
<Text
|
||||
style={[
|
||||
a.text_md,
|
||||
|
||||
@@ -30,7 +30,6 @@ import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {isCancelledError} from '#/lib/strings/errors'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {logger} from '#/logger'
|
||||
import {isAndroid, isNative, isWeb} from '#/platform/detection'
|
||||
import {
|
||||
type ComposerImage,
|
||||
compressImage,
|
||||
@@ -54,6 +53,7 @@ import {LiveStatusDialog} from '#/components/live/LiveStatusDialog'
|
||||
import {MediaInsetBorder} from '#/components/MediaInsetBorder'
|
||||
import * as Menu from '#/components/Menu'
|
||||
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
|
||||
import {IS_ANDROID, IS_NATIVE, IS_WEB} from '#/env'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
|
||||
export type UserAvatarType = 'user' | 'algo' | 'list' | 'labeler'
|
||||
@@ -88,7 +88,7 @@ interface PreviewableUserAvatarProps extends BaseUserAvatarProps {
|
||||
onBeforePress?: () => void
|
||||
}
|
||||
|
||||
const BLUR_AMOUNT = isWeb ? 5 : 100
|
||||
const BLUR_AMOUNT = IS_WEB ? 5 : 100
|
||||
|
||||
let DefaultAvatar = ({
|
||||
type,
|
||||
@@ -286,7 +286,7 @@ let UserAvatar = ({
|
||||
}, [size, style])
|
||||
|
||||
return avatar &&
|
||||
!((moderation?.blur && isAndroid) /* android crashes with blur */) ? (
|
||||
!((moderation?.blur && IS_ANDROID) /* android crashes with blur */) ? (
|
||||
<View style={containerStyle}>
|
||||
{usePlainRNImage ? (
|
||||
<RNImage
|
||||
@@ -394,7 +394,7 @@ let EditableUserAvatar = ({
|
||||
}
|
||||
|
||||
try {
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
onSelectNewAvatar(
|
||||
await compressIfNeeded(
|
||||
await openCropper({
|
||||
@@ -464,7 +464,7 @@ let EditableUserAvatar = ({
|
||||
</Menu.Trigger>
|
||||
<Menu.Outer showCancel>
|
||||
<Menu.Group>
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<Menu.Item
|
||||
testID="changeAvatarCameraBtn"
|
||||
label={_(msg`Upload from Camera`)}
|
||||
@@ -481,7 +481,7 @@ let EditableUserAvatar = ({
|
||||
label={_(msg`Upload from Library`)}
|
||||
onPress={onOpenLibrary}>
|
||||
<Menu.ItemText>
|
||||
{isNative ? (
|
||||
{IS_NATIVE ? (
|
||||
<Trans>Upload from Library</Trans>
|
||||
) : (
|
||||
<Trans>Upload from Files</Trans>
|
||||
@@ -571,7 +571,7 @@ let PreviewableUserAvatar = ({
|
||||
<ProfileHoverCard did={profile.did} disable={disableHoverCard}>
|
||||
{disableNavigation ? (
|
||||
avatarEl
|
||||
) : status.isActive && (isNative || isTouchDevice) ? (
|
||||
) : status.isActive && (IS_NATIVE || isTouchDevice) ? (
|
||||
<>
|
||||
<Button
|
||||
label={_(
|
||||
|
||||
@@ -14,7 +14,6 @@ import {openCamera, openCropper, openPicker} from '#/lib/media/picker'
|
||||
import {type PickerImage} from '#/lib/media/picker.shared'
|
||||
import {isCancelledError} from '#/lib/strings/errors'
|
||||
import {logger} from '#/logger'
|
||||
import {isAndroid, isNative} from '#/platform/detection'
|
||||
import {
|
||||
type ComposerImage,
|
||||
compressImage,
|
||||
@@ -32,6 +31,7 @@ import {
|
||||
import {StreamingLive_Stroke2_Corner0_Rounded as LibraryIcon} from '#/components/icons/StreamingLive'
|
||||
import {Trash_Stroke2_Corner0_Rounded as TrashIcon} from '#/components/icons/Trash'
|
||||
import * as Menu from '#/components/Menu'
|
||||
import {IS_ANDROID, IS_NATIVE} from '#/env'
|
||||
|
||||
export function UserBanner({
|
||||
type,
|
||||
@@ -75,7 +75,7 @@ export function UserBanner({
|
||||
}
|
||||
|
||||
try {
|
||||
if (isNative) {
|
||||
if (IS_NATIVE) {
|
||||
onSelectNewBanner?.(
|
||||
await compressIfNeeded(
|
||||
await openCropper({
|
||||
@@ -153,7 +153,7 @@ export function UserBanner({
|
||||
</Menu.Trigger>
|
||||
<Menu.Outer showCancel>
|
||||
<Menu.Group>
|
||||
{isNative && (
|
||||
{IS_NATIVE && (
|
||||
<Menu.Item
|
||||
testID="changeBannerCameraBtn"
|
||||
label={_(msg`Upload from Camera`)}
|
||||
@@ -170,7 +170,7 @@ export function UserBanner({
|
||||
label={_(msg`Upload from Library`)}
|
||||
onPress={onOpenLibrary}>
|
||||
<Menu.ItemText>
|
||||
{isNative ? (
|
||||
{IS_NATIVE ? (
|
||||
<Trans>Upload from Library</Trans>
|
||||
) : (
|
||||
<Trans>Upload from Files</Trans>
|
||||
@@ -207,7 +207,7 @@ export function UserBanner({
|
||||
/>
|
||||
</>
|
||||
) : banner &&
|
||||
!((moderation?.blur && isAndroid) /* android crashes with blur */) ? (
|
||||
!((moderation?.blur && IS_ANDROID) /* android crashes with blur */) ? (
|
||||
<Image
|
||||
testID="userBannerImage"
|
||||
style={[styles.bannerImage, t.atoms.bg_contrast_25]}
|
||||
|
||||
@@ -13,7 +13,7 @@ import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {colors, s} from '#/lib/styles'
|
||||
import {isAndroid} from '#/platform/detection'
|
||||
import {IS_ANDROID} from '#/env'
|
||||
import {Text} from './text/Text'
|
||||
import {FlatList_INTERNAL} from './Views'
|
||||
|
||||
@@ -120,7 +120,7 @@ export const ViewSelector = React.forwardRef<
|
||||
renderItem={renderItemInternal}
|
||||
ListFooterComponent={ListFooterComponent}
|
||||
// NOTE sticky header disabled on android due to major performance issues -prf
|
||||
stickyHeaderIndices={isAndroid ? undefined : STICKY_HEADER_INDICES}
|
||||
stickyHeaderIndices={IS_ANDROID ? undefined : STICKY_HEADER_INDICES}
|
||||
onScroll={onScroll}
|
||||
onEndReached={onEndReached}
|
||||
refreshControl={
|
||||
|
||||
@@ -12,9 +12,9 @@ import {PressableScale} from '#/lib/custom-animations/PressableScale'
|
||||
import {useHaptics} from '#/lib/haptics'
|
||||
import {useMinimalShellFabTransform} from '#/lib/hooks/useMinimalShellTransform'
|
||||
import {clamp} from '#/lib/numbers'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {ios, useBreakpoints, useTheme} from '#/alf'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
export interface FABProps extends ComponentProps<typeof Pressable> {
|
||||
testID?: string
|
||||
@@ -84,7 +84,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
outer: {
|
||||
// @ts-ignore web-only
|
||||
position: isWeb ? 'fixed' : 'absolute',
|
||||
position: IS_WEB ? 'fixed' : 'absolute',
|
||||
zIndex: 1,
|
||||
cursor: 'pointer',
|
||||
},
|
||||
|
||||
@@ -5,8 +5,8 @@ import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
|
||||
import {useIsKeyboardVisible} from '#/lib/hooks/useIsKeyboardVisible'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {Text} from '../text/Text'
|
||||
|
||||
export const LoggedOutLayout = ({
|
||||
@@ -79,7 +79,7 @@ export const LoggedOutLayout = ({
|
||||
contentContainerStyle={styles.scrollViewContentContainer}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
keyboardDismissMode="on-drag">
|
||||
<View style={[styles.contentWrapper, isWeb && a.my_auto]}>
|
||||
<View style={[styles.contentWrapper, IS_WEB && a.my_auto]}>
|
||||
{children}
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
@@ -5,13 +5,13 @@ import {UITextView} from 'react-native-uitextview'
|
||||
import {lh, s} from '#/lib/styles'
|
||||
import {type TypographyVariant, useTheme} from '#/lib/ThemeContext'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS, isWeb} from '#/platform/detection'
|
||||
import {applyFonts, useAlf} from '#/alf'
|
||||
import {
|
||||
childHasEmoji,
|
||||
renderChildrenWithEmoji,
|
||||
type StringChild,
|
||||
} from '#/alf/typography'
|
||||
import {IS_IOS, IS_WEB} from '#/env'
|
||||
|
||||
export type CustomTextProps = Omit<TextProps, 'children'> & {
|
||||
type?: TypographyVariant
|
||||
@@ -81,10 +81,10 @@ function Text_DEPRECATED({
|
||||
}
|
||||
|
||||
return {
|
||||
uiTextView: selectable && isIOS,
|
||||
uiTextView: selectable && IS_IOS,
|
||||
selectable,
|
||||
style: flattened,
|
||||
dataSet: isWeb
|
||||
dataSet: IS_WEB
|
||||
? Object.assign({tooltip: title}, dataSet || {})
|
||||
: undefined,
|
||||
...props,
|
||||
|
||||
Reference in New Issue
Block a user