[new arch] experiment - use animatedview/animatedref to measure rect for lightbox (#8298)
* more upgrades * use animatedview/animatedref for measurements in lightbox * rm usehandleref * downgrade dynamic app icon * more bumps that let the thing build on ios * bumps that let it build for ios * bump expo --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
import {useState} from 'react'
|
||||
import {AnimatedRef, measure, MeasuredDimensions} from 'react-native-reanimated'
|
||||
|
||||
export type HandleRef = {
|
||||
(node: any): void
|
||||
current: null | number
|
||||
}
|
||||
|
||||
// This is a lighterweight alternative to `useAnimatedRef()` for imperative UI thread actions.
|
||||
// Render it like <View ref={ref} />, then pass `ref.current` to `measureHandle()` and such.
|
||||
export function useHandleRef(): HandleRef {
|
||||
return useState(() => {
|
||||
const ref = (node: any) => {
|
||||
if (node) {
|
||||
ref.current =
|
||||
node._nativeTag ??
|
||||
node.__nativeTag ??
|
||||
node.canonical?.nativeTag ??
|
||||
null
|
||||
} else {
|
||||
ref.current = null
|
||||
}
|
||||
}
|
||||
ref.current = null
|
||||
return ref
|
||||
})[0] as HandleRef
|
||||
}
|
||||
|
||||
// When using this version, you need to read ref.current on the JS thread, and pass it to UI.
|
||||
export function measureHandle(
|
||||
current: number | null,
|
||||
): MeasuredDimensions | null {
|
||||
'worklet'
|
||||
if (current !== null) {
|
||||
return measure((() => current) as AnimatedRef<any>)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
import React, {memo, useEffect} from 'react'
|
||||
import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
|
||||
import {
|
||||
import Animated, {
|
||||
measure,
|
||||
type MeasuredDimensions,
|
||||
runOnJS,
|
||||
runOnUI,
|
||||
useAnimatedRef,
|
||||
} from 'react-native-reanimated'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {type AppBskyActorDefs, type ModerationDecision} from '@atproto/api'
|
||||
@@ -14,7 +16,6 @@ import {useNavigation} from '@react-navigation/native'
|
||||
import {useActorStatus} from '#/lib/actor-status'
|
||||
import {BACK_HITSLOP} from '#/lib/constants'
|
||||
import {useHaptics} from '#/lib/haptics'
|
||||
import {measureHandle, useHandleRef} from '#/lib/hooks/useHandleRef'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS} from '#/platform/detection'
|
||||
@@ -59,7 +60,7 @@ let ProfileHeaderShell = ({
|
||||
const playHaptic = useHaptics()
|
||||
const liveStatusControl = useDialogControl()
|
||||
|
||||
const aviRef = useHandleRef()
|
||||
const aviRef = useAnimatedRef()
|
||||
|
||||
const onPressBack = React.useCallback(() => {
|
||||
if (navigation.canGoBack()) {
|
||||
@@ -92,6 +93,18 @@ let ProfileHeaderShell = ({
|
||||
[openLightbox],
|
||||
)
|
||||
|
||||
const onPressAvi = React.useCallback(() => {
|
||||
const modui = moderation.ui('avatar')
|
||||
const avatar = profile.avatar
|
||||
if (avatar && !(modui.blur && modui.noOverride)) {
|
||||
runOnUI(() => {
|
||||
'worklet'
|
||||
const rect = measure(aviRef)
|
||||
runOnJS(_openLightbox)(avatar, rect)
|
||||
})()
|
||||
}
|
||||
}, [profile, moderation, _openLightbox, aviRef])
|
||||
|
||||
const isMe = React.useMemo(
|
||||
() => currentAccount?.did === profile.did,
|
||||
[currentAccount, profile],
|
||||
@@ -223,7 +236,7 @@ let ProfileHeaderShell = ({
|
||||
styles.avi,
|
||||
profile.associated?.labeler && styles.aviLabeler,
|
||||
]}>
|
||||
<View ref={aviRef} collapsable={false}>
|
||||
<Animated.View ref={aviRef} collapsable={false}>
|
||||
<UserAvatar
|
||||
type={profile.associated?.labeler ? 'labeler' : 'user'}
|
||||
size={live.isActive ? 88 : 90}
|
||||
@@ -231,7 +244,7 @@ let ProfileHeaderShell = ({
|
||||
moderation={moderation.ui('avatar')}
|
||||
/>
|
||||
{live.isActive && <LiveIndicator size="large" />}
|
||||
</View>
|
||||
</Animated.View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</GrowableAvatar>
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
import React from 'react'
|
||||
import {Pressable, View} from 'react-native'
|
||||
import {MeasuredDimensions, runOnJS, runOnUI} from 'react-native-reanimated'
|
||||
import {AppBskyGraphDefs} from '@atproto/api'
|
||||
import Animated, {
|
||||
measure,
|
||||
type MeasuredDimensions,
|
||||
runOnJS,
|
||||
runOnUI,
|
||||
useAnimatedRef,
|
||||
} from 'react-native-reanimated'
|
||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
|
||||
import {measureHandle, useHandleRef} from '#/lib/hooks/useHandleRef'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {NavigationProp} from '#/lib/routes/types'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {emitSoftReset} from '#/state/events'
|
||||
import {useLightboxControls} from '#/state/lightbox'
|
||||
import {TextLink} from '#/view/com/util/Link'
|
||||
import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
|
||||
import {Text} from '#/view/com/util/text/Text'
|
||||
import {UserAvatar, UserAvatarType} from '#/view/com/util/UserAvatar'
|
||||
import {UserAvatar, type UserAvatarType} from '#/view/com/util/UserAvatar'
|
||||
import {StarterPack} from '#/components/icons/StarterPack'
|
||||
import * as Layout from '#/components/Layout'
|
||||
|
||||
@@ -52,7 +57,7 @@ export function ProfileSubpageHeader({
|
||||
const {openLightbox} = useLightboxControls()
|
||||
const pal = usePalette('default')
|
||||
const canGoBack = navigation.canGoBack()
|
||||
const aviRef = useHandleRef()
|
||||
const aviRef = useAnimatedRef()
|
||||
|
||||
const _openLightbox = React.useCallback(
|
||||
(uri: string, thumbRect: MeasuredDimensions | null) => {
|
||||
@@ -81,10 +86,9 @@ export function ProfileSubpageHeader({
|
||||
if (
|
||||
avatar // TODO && !(view.moderation.avatar.blur && view.moderation.avatar.noOverride)
|
||||
) {
|
||||
const aviHandle = aviRef.current
|
||||
runOnUI(() => {
|
||||
'worklet'
|
||||
const rect = measureHandle(aviHandle)
|
||||
const rect = measure(aviRef)
|
||||
runOnJS(_openLightbox)(avatar, rect)
|
||||
})()
|
||||
}
|
||||
@@ -111,7 +115,7 @@ export function ProfileSubpageHeader({
|
||||
paddingBottom: 14,
|
||||
paddingHorizontal: isMobile ? 12 : 14,
|
||||
}}>
|
||||
<View ref={aviRef} collapsable={false}>
|
||||
<Animated.View ref={aviRef} collapsable={false}>
|
||||
<Pressable
|
||||
testID="headerAviButton"
|
||||
onPress={onPressAvi}
|
||||
@@ -125,7 +129,7 @@ export function ProfileSubpageHeader({
|
||||
<UserAvatar type={avatarType} size={58} avatar={avatar} />
|
||||
)}
|
||||
</Pressable>
|
||||
</View>
|
||||
</Animated.View>
|
||||
<View style={{flex: 1, gap: 4}}>
|
||||
{isLoading ? (
|
||||
<LoadingPlaceholder
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React, {useRef} from 'react'
|
||||
import {DimensionValue, Pressable, View} from 'react-native'
|
||||
import {type DimensionValue, Pressable, View} from 'react-native'
|
||||
import Animated, {type AnimatedRef, useAnimatedRef} from 'react-native-reanimated'
|
||||
import {Image} from 'expo-image'
|
||||
import {AppBskyEmbedImages} from '@atproto/api'
|
||||
import {type AppBskyEmbedImages} from '@atproto/api'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {HandleRef, useHandleRef} from '#/lib/hooks/useHandleRef'
|
||||
import type {Dimensions} from '#/lib/media/types'
|
||||
import {type Dimensions} from '#/lib/media/types'
|
||||
import {isNative} from '#/platform/detection'
|
||||
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
|
||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||
@@ -68,14 +68,17 @@ export function AutoSizedImage({
|
||||
image: AppBskyEmbedImages.ViewImage
|
||||
crop?: 'none' | 'square' | 'constrained'
|
||||
hideBadge?: boolean
|
||||
onPress?: (containerRef: HandleRef, fetchedDims: Dimensions | null) => void
|
||||
onPress?: (
|
||||
containerRef: AnimatedRef<any>,
|
||||
fetchedDims: Dimensions | null,
|
||||
) => void
|
||||
onLongPress?: () => void
|
||||
onPressIn?: () => void
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const largeAlt = useLargeAltBadgeEnabled()
|
||||
const containerRef = useHandleRef()
|
||||
const containerRef = useAnimatedRef()
|
||||
const fetchedDimsRef = useRef<{width: number; height: number} | null>(null)
|
||||
|
||||
let aspectRatio: number | undefined
|
||||
@@ -103,7 +106,7 @@ export function AutoSizedImage({
|
||||
const hasAlt = !!image.alt
|
||||
|
||||
const contents = (
|
||||
<View ref={containerRef} collapsable={false} style={{flex: 1}}>
|
||||
<Animated.View ref={containerRef} collapsable={false} style={{flex: 1}}>
|
||||
<Image
|
||||
contentFit={isContain ? 'contain' : 'cover'}
|
||||
style={[a.w_full, a.h_full]}
|
||||
@@ -185,7 +188,7 @@ export function AutoSizedImage({
|
||||
)}
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
</Animated.View>
|
||||
)
|
||||
|
||||
if (cropDisabled) {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React from 'react'
|
||||
import {Pressable, StyleProp, View, ViewStyle} from 'react-native'
|
||||
import {Image, ImageStyle} from 'expo-image'
|
||||
import {AppBskyEmbedImages} from '@atproto/api'
|
||||
import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native'
|
||||
import {type AnimatedRef} from 'react-native-reanimated'
|
||||
import {Image, type ImageStyle} from 'expo-image'
|
||||
import {type AppBskyEmbedImages} from '@atproto/api'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import type React from 'react'
|
||||
|
||||
import {HandleRef} from '#/lib/hooks/useHandleRef'
|
||||
import {Dimensions} from '#/lib/media/types'
|
||||
import {type Dimensions} from '#/lib/media/types'
|
||||
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
|
||||
import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
@@ -20,7 +20,7 @@ interface Props {
|
||||
index: number
|
||||
onPress?: (
|
||||
index: number,
|
||||
containerRefs: HandleRef[],
|
||||
containerRefs: AnimatedRef<any>[],
|
||||
fetchedDims: (Dimensions | null)[],
|
||||
) => void
|
||||
onLongPress?: EventFunction
|
||||
@@ -28,7 +28,7 @@ interface Props {
|
||||
imageStyle?: StyleProp<ImageStyle>
|
||||
viewContext?: PostEmbedViewContext
|
||||
insetBorderStyle?: StyleProp<ViewStyle>
|
||||
containerRefs: HandleRef[]
|
||||
containerRefs: AnimatedRef<any>[]
|
||||
thumbDimsRef: React.MutableRefObject<(Dimensions | null)[]>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import React from 'react'
|
||||
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
||||
import {AppBskyEmbedImages} from '@atproto/api'
|
||||
import {type StyleProp, StyleSheet, View, type ViewStyle} from 'react-native'
|
||||
import {type AnimatedRef, useAnimatedRef} from 'react-native-reanimated'
|
||||
import {type AppBskyEmbedImages} from '@atproto/api'
|
||||
|
||||
import {HandleRef, useHandleRef} from '#/lib/hooks/useHandleRef'
|
||||
import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types'
|
||||
import {atoms as a, useBreakpoints} from '#/alf'
|
||||
import {Dimensions} from '../../lightbox/ImageViewing/@types'
|
||||
import {type Dimensions} from '../../lightbox/ImageViewing/@types'
|
||||
import {GalleryItem} from './Gallery'
|
||||
|
||||
interface ImageLayoutGridProps {
|
||||
images: AppBskyEmbedImages.ViewImage[]
|
||||
onPress?: (
|
||||
index: number,
|
||||
containerRefs: HandleRef[],
|
||||
containerRefs: AnimatedRef<any>[],
|
||||
fetchedDims: (Dimensions | null)[],
|
||||
) => void
|
||||
onLongPress?: (index: number) => void
|
||||
@@ -43,7 +43,7 @@ interface ImageLayoutGridInnerProps {
|
||||
images: AppBskyEmbedImages.ViewImage[]
|
||||
onPress?: (
|
||||
index: number,
|
||||
containerRefs: HandleRef[],
|
||||
containerRefs: AnimatedRef<any>[],
|
||||
fetchedDims: (Dimensions | null)[],
|
||||
) => void
|
||||
onLongPress?: (index: number) => void
|
||||
@@ -56,10 +56,10 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
|
||||
const gap = props.gap
|
||||
const count = props.images.length
|
||||
|
||||
const containerRef1 = useHandleRef()
|
||||
const containerRef2 = useHandleRef()
|
||||
const containerRef3 = useHandleRef()
|
||||
const containerRef4 = useHandleRef()
|
||||
const containerRef1 = useAnimatedRef()
|
||||
const containerRef2 = useAnimatedRef()
|
||||
const containerRef3 = useAnimatedRef()
|
||||
const containerRef4 = useAnimatedRef()
|
||||
const thumbDimsRef = React.useRef<(Dimensions | null)[]>([])
|
||||
|
||||
switch (count) {
|
||||
|
||||
@@ -7,6 +7,8 @@ import {
|
||||
type ViewStyle,
|
||||
} from 'react-native'
|
||||
import {
|
||||
type AnimatedRef,
|
||||
measure,
|
||||
type MeasuredDimensions,
|
||||
runOnJS,
|
||||
runOnUI,
|
||||
@@ -25,7 +27,6 @@ import {
|
||||
type ModerationDecision,
|
||||
} from '@atproto/api'
|
||||
|
||||
import {type HandleRef, measureHandle} from '#/lib/hooks/useHandleRef'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {useLightboxControls} from '#/state/lightbox'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
@@ -162,13 +163,15 @@ export function PostEmbeds({
|
||||
}
|
||||
const onPress = (
|
||||
index: number,
|
||||
refs: HandleRef[],
|
||||
refs: AnimatedRef<any>[],
|
||||
fetchedDims: (Dimensions | null)[],
|
||||
) => {
|
||||
const handles = refs.map(r => r.current)
|
||||
runOnUI(() => {
|
||||
'worklet'
|
||||
const rects = handles.map(measureHandle)
|
||||
const rects: (MeasuredDimensions | null)[] = []
|
||||
for (const r of refs) {
|
||||
rects.push(measure(r))
|
||||
}
|
||||
runOnJS(_openLightbox)(index, rects, fetchedDims)
|
||||
})()
|
||||
}
|
||||
|
||||
@@ -3857,6 +3857,26 @@
|
||||
xcode "^3.0.1"
|
||||
xml2js "0.6.0"
|
||||
|
||||
"@expo/config-plugins@~10.0.0":
|
||||
version "10.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-10.0.0.tgz#5ea58f9c12d1d06b6c43c9fb9e7163bb4954d04f"
|
||||
integrity sha512-VAGMjQoBFKwyXGzVcAptqY68LGx1pZr8c+4e82h6E1elenjeVBt1CBaWHC/kiAw2Akr2nkdUVd85nIaC81m1ow==
|
||||
dependencies:
|
||||
"@expo/config-types" "^53.0.2"
|
||||
"@expo/json-file" "~9.1.3"
|
||||
"@expo/plist" "^0.3.3"
|
||||
"@expo/sdk-runtime-versions" "^1.0.0"
|
||||
chalk "^4.1.2"
|
||||
debug "^4.3.5"
|
||||
getenv "^1.0.0"
|
||||
glob "^10.4.2"
|
||||
resolve-from "^5.0.0"
|
||||
semver "^7.5.4"
|
||||
slash "^3.0.0"
|
||||
slugify "^1.6.6"
|
||||
xcode "^3.0.1"
|
||||
xml2js "0.6.0"
|
||||
|
||||
"@expo/config-plugins@~10.0.1", "@expo/config-plugins@~10.0.2":
|
||||
version "10.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-10.0.2.tgz#040867991e9c8c527b4f5c13a47bcf040a7479fe"
|
||||
@@ -3907,6 +3927,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-52.0.3.tgz#511f2f868172c93abeac7183beeb921dc72d6e1e"
|
||||
integrity sha512-muxvuARmbysH5OGaiBRlh1Y6vfdmL56JtpXxB+y2Hfhu0ezG1U4FjZYBIacthckZPvnDCcP3xIu1R+eTo7/QFA==
|
||||
|
||||
"@expo/config-types@^53.0.2":
|
||||
version "53.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-53.0.2.tgz#9251ddd56589e8f93703bfe7426d5daf120e4ec2"
|
||||
integrity sha512-W7bmDvCjAnsaNlu9bJmaGm95AEFVfqS+qEnlEwfAFi4BwDf+eFWL5TM87iw6esKpglVF8J3nQ1zHI4+CeS9xrg==
|
||||
|
||||
"@expo/config-types@^53.0.3":
|
||||
version "53.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-53.0.3.tgz#d083d9b095972e89eee96c41d085feb5b92d2749"
|
||||
@@ -3931,7 +3956,26 @@
|
||||
slugify "^1.3.4"
|
||||
sucrase "3.35.0"
|
||||
|
||||
"@expo/config@~11.0.6", "@expo/config@~11.0.7":
|
||||
"@expo/config@~11.0.6":
|
||||
version "11.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config/-/config-11.0.6.tgz#934efecf3393e0d47d00cadd511095b2255c3262"
|
||||
integrity sha512-lmBP4kbNFiDLZoxPNuaN/UanFzns0+PxJA1eimOAHa6aFSAHTl48AHozbJ6UARbvig/TVTzLfGpoxv2Ih03iYQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "~7.10.4"
|
||||
"@expo/config-plugins" "~10.0.0"
|
||||
"@expo/config-types" "^53.0.2"
|
||||
"@expo/json-file" "^9.1.3"
|
||||
deepmerge "^4.3.1"
|
||||
getenv "^1.0.0"
|
||||
glob "^10.4.2"
|
||||
require-from-string "^2.0.2"
|
||||
resolve-from "^5.0.0"
|
||||
resolve-workspace-root "^2.0.0"
|
||||
semver "^7.6.0"
|
||||
slugify "^1.3.4"
|
||||
sucrase "3.35.0"
|
||||
|
||||
"@expo/config@~11.0.7":
|
||||
version "11.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config/-/config-11.0.7.tgz#e6a6071942854269825e2450c3a115c963a4fd56"
|
||||
integrity sha512-pppH3Cy2IfituiYACMeW7cWYezcjmHKq7lDLfH1gMHT+zZ1QaYNs3EN6Kcc/QAXV//KFFhU0Qq4H/UrLuPp/yg==
|
||||
@@ -4037,7 +4081,7 @@
|
||||
json5 "^2.2.3"
|
||||
write-file-atomic "^2.3.0"
|
||||
|
||||
"@expo/json-file@^9.1.4", "@expo/json-file@~9.1.4":
|
||||
"@expo/json-file@^9.1.3", "@expo/json-file@^9.1.4", "@expo/json-file@~9.1.3", "@expo/json-file@~9.1.4":
|
||||
version "9.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-9.1.4.tgz#e719d092c08afb3234643f9285e57c6a24989327"
|
||||
integrity sha512-7Bv86X27fPERGhw8aJEZvRcH9sk+9BenDnEmrI3ZpywKodYSBgc8lX9Y32faNVQ/p0YbDK9zdJ0BfAKNAOyi0A==
|
||||
@@ -4117,7 +4161,7 @@
|
||||
base64-js "^1.2.3"
|
||||
xmlbuilder "^14.0.0"
|
||||
|
||||
"@expo/plist@^0.3.4":
|
||||
"@expo/plist@^0.3.3", "@expo/plist@^0.3.4":
|
||||
version "0.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.3.4.tgz#0c48eeff2158cf26c5c9ed4f681d24997ccfbeca"
|
||||
integrity sha512-MhBLaUJNe9FQDDU2xhSNS4SAolr6K2wuyi4+A79vYuXLkAoICsbTwcGEQJN5jPY6D9izO/jsXh5k0h+mIWQMdw==
|
||||
@@ -6140,7 +6184,7 @@
|
||||
"@babel/traverse" "^7.25.3"
|
||||
"@react-native/codegen" "0.79.2"
|
||||
|
||||
"@react-native/babel-preset@0.79.2":
|
||||
"@react-native/babel-preset@0.79.0-rc.4", "@react-native/babel-preset@0.79.2":
|
||||
version "0.79.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.79.2.tgz#5a683a6efeea357a326f70c84a881be2bafbeae3"
|
||||
integrity sha512-/HNu869oUq4FUXizpiNWrIhucsYZqu0/0spudJEzk9SEKar0EjVDP7zkg/sKK+KccNypDQGW7nFXT8onzvQ3og==
|
||||
|
||||
Reference in New Issue
Block a user