Expo 57 (#11334)
Co-authored-by: Tomek Zawadzki <tomekzawadzki98@gmail.com> Co-authored-by: vineyardbovines <spencerfpope@gmail.com>
This commit is contained in:
+5
-4
@@ -2,7 +2,6 @@ import {forwardRef, useCallback, useEffect, useState} from 'react'
|
||||
import {
|
||||
AccessibilityInfo,
|
||||
Image as RNImage,
|
||||
StyleSheet,
|
||||
useColorScheme,
|
||||
View,
|
||||
} from 'react-native'
|
||||
@@ -20,6 +19,7 @@ import {Image} from 'expo-image'
|
||||
import * as SplashScreen from 'expo-splash-screen'
|
||||
|
||||
import {Logotype} from '#/view/icons/Logotype'
|
||||
import {atoms as a} from '#/alf'
|
||||
// @ts-ignore
|
||||
import splashImagePointer from '../assets/splash/splash.png'
|
||||
// @ts-ignore
|
||||
@@ -170,12 +170,12 @@ export function Splash(props: React.PropsWithChildren<Props>) {
|
||||
return (
|
||||
<View style={{flex: 1}} onLayout={onLayout}>
|
||||
{!isAnimationComplete && (
|
||||
<View style={StyleSheet.absoluteFillObject}>
|
||||
<View style={[a.absolute, a.inset_0]}>
|
||||
<Image
|
||||
accessibilityIgnoresInvertColors
|
||||
onLoadEnd={onLoadEnd}
|
||||
source={{uri: isDarkMode ? darkSplashImageUri : splashImageUri}}
|
||||
style={StyleSheet.absoluteFillObject}
|
||||
style={[a.absolute, a.inset_0]}
|
||||
/>
|
||||
|
||||
<Animated.View
|
||||
@@ -205,7 +205,8 @@ export function Splash(props: React.PropsWithChildren<Props>) {
|
||||
{!isAnimationComplete && (
|
||||
<Animated.View
|
||||
style={[
|
||||
StyleSheet.absoluteFillObject,
|
||||
a.absolute,
|
||||
a.inset_0,
|
||||
logoAnimation,
|
||||
{
|
||||
flex: 1,
|
||||
|
||||
@@ -2,7 +2,7 @@ import {lazy, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
// @ts-expect-error missing types
|
||||
import QRCode from 'react-native-qrcode-styled'
|
||||
import type ViewShot from 'react-native-view-shot'
|
||||
import {type ViewShotRef} from 'react-native-view-shot'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
|
||||
import {Logo} from '#/view/icons/Logo'
|
||||
@@ -14,10 +14,7 @@ import {IS_WEB} from '#/env'
|
||||
import {app} from '#/lexicons'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
const LazyViewShot = lazy(
|
||||
// @ts-expect-error dynamic import
|
||||
() => import('react-native-view-shot/src/index'),
|
||||
)
|
||||
const LazyViewShot = lazy(() => import('react-native-view-shot'))
|
||||
|
||||
export function QrCode({
|
||||
starterPack,
|
||||
@@ -26,7 +23,7 @@ export function QrCode({
|
||||
}: {
|
||||
starterPack: app.bsky.graph.defs.StarterPackView
|
||||
link: string
|
||||
ref: React.Ref<ViewShot>
|
||||
ref: React.Ref<ViewShotRef>
|
||||
}) {
|
||||
const {record} = starterPack
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import {Suspense, useRef, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import type ViewShot from 'react-native-view-shot'
|
||||
import {requestPermissionsAsync, saveToLibraryAsync} from 'expo-media-library'
|
||||
import {type ViewShotRef} from 'react-native-view-shot'
|
||||
import {
|
||||
requestPermissionsAsync,
|
||||
saveToLibraryAsync,
|
||||
} from 'expo-media-library/legacy'
|
||||
import * as Sharing from 'expo-sharing'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
@@ -38,7 +41,7 @@ export function QrCodeDialog({
|
||||
const [isSaveProcessing, setIsSaveProcessing] = useState(false)
|
||||
const [isCopyProcessing, setIsCopyProcessing] = useState(false)
|
||||
|
||||
const ref = useRef<ViewShot>(null)
|
||||
const ref = useRef<ViewShotRef>(null)
|
||||
|
||||
const getCanvas = (base64: string): Promise<HTMLCanvasElement> => {
|
||||
return new Promise(resolve => {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import {Suspense, useRef} from 'react'
|
||||
import {Pressable, View} from 'react-native'
|
||||
import type ViewShot from 'react-native-view-shot'
|
||||
import {type ViewShotRef} from 'react-native-view-shot'
|
||||
import {setStringAsync} from 'expo-clipboard'
|
||||
import {requestPermissionsAsync, saveToLibraryAsync} from 'expo-media-library'
|
||||
import {
|
||||
requestPermissionsAsync,
|
||||
saveToLibraryAsync,
|
||||
} from 'expo-media-library/legacy'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
|
||||
@@ -41,7 +44,7 @@ export function InviteFriendsDialogInner({
|
||||
const {currentAccount} = useSession()
|
||||
const profileQuery = useProfileQuery({did: currentAccount?.did})
|
||||
const [themeKey, setThemeKey] = useInviteThemeKey()
|
||||
const captureRef = useRef<ViewShot>(null)
|
||||
const captureRef = useRef<ViewShotRef>(null)
|
||||
|
||||
const theme = getInviteTheme(themeKey)
|
||||
const variant = t.name === 'light' ? theme.light : theme.dark
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {useCallback, useState} from 'react'
|
||||
import {Pressable, StyleSheet, useWindowDimensions, View} from 'react-native'
|
||||
import {Pressable, useWindowDimensions, View} from 'react-native'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import Svg, {Path} from 'react-native-svg'
|
||||
import {
|
||||
@@ -125,7 +125,7 @@ export function InviteScannerScreen() {
|
||||
noInsetTop
|
||||
style={{backgroundColor: t.palette.black}}>
|
||||
<CameraView
|
||||
style={StyleSheet.absoluteFill}
|
||||
style={[a.absolute, a.inset_0]}
|
||||
facing="back"
|
||||
barcodeScannerSettings={{barcodeTypes: ['qr']}}
|
||||
onBarcodeScanned={scannerEnabled ? onBarcodeScanned : undefined}
|
||||
@@ -254,7 +254,7 @@ function ScannerScrim() {
|
||||
`V${y + r} A${r} ${r} 0 0 1 ${x + r} ${y} Z`
|
||||
return (
|
||||
<Svg
|
||||
style={StyleSheet.absoluteFill}
|
||||
style={[a.absolute, a.inset_0]}
|
||||
width={width}
|
||||
height={height}
|
||||
pointerEvents="none">
|
||||
|
||||
@@ -2,7 +2,7 @@ import {lazy} from 'react'
|
||||
import {View} from 'react-native'
|
||||
// @ts-expect-error missing types
|
||||
import QRCode from 'react-native-qrcode-styled'
|
||||
import type ViewShot from 'react-native-view-shot'
|
||||
import {type ViewShotRef} from 'react-native-view-shot'
|
||||
import {Image} from 'expo-image'
|
||||
import {LinearGradient} from 'expo-linear-gradient'
|
||||
|
||||
@@ -12,10 +12,7 @@ import {hexToRgb, rgbToHex} from '#/alf/util/colorGeneration'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type InviteThemeVariant} from '../themes'
|
||||
|
||||
const LazyViewShot = lazy(
|
||||
// @ts-expect-error dynamic import
|
||||
() => import('react-native-view-shot/src/index'),
|
||||
)
|
||||
const LazyViewShot = lazy(() => import('react-native-view-shot'))
|
||||
|
||||
const CARD_WIDTH = 278
|
||||
const CARD_GRADIENT_PADDING = 12
|
||||
@@ -37,7 +34,7 @@ export function ThemedQrCard({
|
||||
shareUrl: string
|
||||
handle: string
|
||||
avatarUri?: string
|
||||
captureRef: React.Ref<ViewShot>
|
||||
captureRef: React.Ref<ViewShotRef>
|
||||
}) {
|
||||
const t = useTheme()
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {useMemo, useState} from 'react'
|
||||
import {type ColorValue, Dimensions, StyleSheet, View} from 'react-native'
|
||||
import {type ColorValue, Dimensions, View} from 'react-native'
|
||||
import {Gesture, GestureDetector} from 'react-native-gesture-handler'
|
||||
import Animated, {
|
||||
clamp,
|
||||
@@ -16,6 +16,7 @@ import Animated, {
|
||||
import {scheduleOnRN} from 'react-native-worklets'
|
||||
|
||||
import {useHaptics} from '#/lib/haptics'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {type GestureActions} from './GestureActionView.shared'
|
||||
|
||||
const MAX_WIDTH = Dimensions.get('screen').width
|
||||
@@ -287,8 +288,7 @@ export function GestureActionView({
|
||||
return (
|
||||
<GestureDetector gesture={composedGesture}>
|
||||
<View>
|
||||
<Animated.View
|
||||
style={[StyleSheet.absoluteFill, animatedBackgroundStyle]}>
|
||||
<Animated.View style={[a.absolute, a.inset_0, animatedBackgroundStyle]}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {Linking} from 'react-native'
|
||||
import {useCameraPermissions as useExpoCameraPermissions} from 'expo-camera'
|
||||
import * as MediaLibrary from 'expo-media-library'
|
||||
import * as MediaLibrary from 'expo-media-library/legacy'
|
||||
|
||||
import {Alert} from '#/view/com/util/Alert'
|
||||
import {IS_WEB} from '#/env'
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
writeAsStringAsync,
|
||||
} from 'expo-file-system/legacy'
|
||||
import {manipulateAsync, SaveFormat} from 'expo-image-manipulator'
|
||||
import * as MediaLibrary from 'expo-media-library'
|
||||
import * as MediaLibrary from 'expo-media-library/legacy'
|
||||
import * as Sharing from 'expo-sharing'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {useCallback} from 'react'
|
||||
import * as MediaLibrary from 'expo-media-library'
|
||||
import * as MediaLibrary from 'expo-media-library/legacy'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
|
||||
Vendored
+40
-8
@@ -18,27 +18,42 @@ declare module '*.css'
|
||||
/*
|
||||
* expo-file-system's declarations build File/Directory on top of
|
||||
* `./ExpoFileSystem`, which remaps to a web shim whose classes are empty.
|
||||
* The fully-typed base classes live in ExpoFileSystem.types (no .web
|
||||
* sibling), so mirror the FileSystem.d.ts wrapper classes on top of those.
|
||||
* As of SDK 57 the fully-typed base classes live in
|
||||
* internal/NativeFileSystem.types (no .web sibling), so mirror the File.d.ts
|
||||
* and Directory.d.ts wrapper classes on top of those.
|
||||
*/
|
||||
declare module 'expo-file-system' {
|
||||
import {
|
||||
Directory as ExpoFileSystemDirectory,
|
||||
File as ExpoFileSystemFile,
|
||||
} from 'expo-file-system/build/ExpoFileSystem.types'
|
||||
NativeFileSystemDirectory as ExpoFileSystemDirectory,
|
||||
NativeFileSystemFile as ExpoFileSystemFile,
|
||||
} from 'expo-file-system/build/internal/NativeFileSystem.types'
|
||||
export {
|
||||
type DirectoryCreateOptions,
|
||||
type DirectoryInfo,
|
||||
type DownloadOptions,
|
||||
EncodingType,
|
||||
type FileCreateOptions,
|
||||
FileHandle,
|
||||
type FileHandle,
|
||||
type FileInfo,
|
||||
type FileWriteOptions,
|
||||
type InfoOptions,
|
||||
type PathInfo,
|
||||
} from 'expo-file-system/build/ExpoFileSystem.types'
|
||||
import {type PathInfo as ExpoPathInfo} from 'expo-file-system/build/ExpoFileSystem.types'
|
||||
} from 'expo-file-system/build/FileSystem.types'
|
||||
import {type PathInfo as ExpoPathInfo} from 'expo-file-system/build/FileSystem.types'
|
||||
import {
|
||||
type WatchEvent,
|
||||
type WatchOptions,
|
||||
type WatchSubscription,
|
||||
} from 'expo-file-system/build/FileSystemWatcher.types'
|
||||
import {
|
||||
type DownloadTask,
|
||||
type UploadTask,
|
||||
} from 'expo-file-system/build/NetworkTasks'
|
||||
import {
|
||||
type DownloadTaskOptions,
|
||||
type UploadOptions,
|
||||
type UploadResult,
|
||||
} from 'expo-file-system/build/NetworkTasks.types'
|
||||
import {PathUtilities} from 'expo-file-system/build/pathUtilities'
|
||||
|
||||
export class Paths extends PathUtilities {
|
||||
@@ -59,8 +74,21 @@ declare module 'expo-file-system' {
|
||||
readableStream(): ReadableStream<Uint8Array<ArrayBuffer>>
|
||||
writableStream(): WritableStream<Uint8Array<ArrayBufferLike>>
|
||||
arrayBuffer(): Promise<ArrayBuffer>
|
||||
json(): Promise<unknown>
|
||||
formData(): ReturnType<Response['formData']>
|
||||
stream(): ReadableStream<Uint8Array<ArrayBuffer>>
|
||||
slice(start?: number, end?: number, contentType?: string): Blob
|
||||
upload(url: string, options?: UploadOptions): Promise<UploadResult>
|
||||
createUploadTask(url: string, options?: UploadOptions): UploadTask
|
||||
static createDownloadTask(
|
||||
url: string,
|
||||
destination: File | Directory,
|
||||
options?: DownloadTaskOptions,
|
||||
): DownloadTask
|
||||
watch(
|
||||
callback: (event: WatchEvent<File>) => void,
|
||||
options?: WatchOptions,
|
||||
): WatchSubscription
|
||||
}
|
||||
|
||||
export class Directory extends ExpoFileSystemDirectory {
|
||||
@@ -70,6 +98,10 @@ declare module 'expo-file-system' {
|
||||
get name(): string
|
||||
createFile(name: string, mimeType: string | null): File
|
||||
createDirectory(name: string): Directory
|
||||
watch(
|
||||
callback: (event: WatchEvent<File | Directory>) => void,
|
||||
options?: WatchOptions,
|
||||
): WatchSubscription
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,15 +7,12 @@ import {
|
||||
useRef,
|
||||
} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import type ViewShot from 'react-native-view-shot'
|
||||
import {type ViewShotRef} from 'react-native-view-shot'
|
||||
|
||||
import {useAvatar} from '#/screens/Onboarding/StepProfile/index'
|
||||
import {atoms as a} from '#/alf'
|
||||
|
||||
const LazyViewShot = lazy(
|
||||
// @ts-expect-error dynamic import
|
||||
() => import('react-native-view-shot/src/index'),
|
||||
)
|
||||
const LazyViewShot = lazy(() => import('react-native-view-shot'))
|
||||
|
||||
const SIZE_MULTIPLIER = 5
|
||||
|
||||
@@ -28,7 +25,7 @@ export interface PlaceholderCanvasRef {
|
||||
export const PlaceholderCanvas = forwardRef<PlaceholderCanvasRef, {}>(
|
||||
function PlaceholderCanvas({}, ref) {
|
||||
const {avatar} = useAvatar()
|
||||
const viewshotRef = useRef<ViewShot>(null)
|
||||
const viewshotRef = useRef<ViewShotRef>(null)
|
||||
const Icon = avatar.placeholder.component
|
||||
|
||||
const styles = useMemo(
|
||||
|
||||
@@ -107,6 +107,7 @@ export function StepProfile() {
|
||||
const response = await sheetWrapper(
|
||||
launchImageLibraryAsync({
|
||||
exif: false,
|
||||
shouldDownloadFromNetwork: true,
|
||||
mediaTypes: ['images'],
|
||||
quality: 1,
|
||||
...opts,
|
||||
|
||||
@@ -95,8 +95,7 @@ export function StepInfo({
|
||||
tldtsRef.current = tldts
|
||||
})
|
||||
// This will get used in the avatar creator a few steps later, so lets preload it now
|
||||
// @ts-expect-error - valid path
|
||||
void import('react-native-view-shot/src/index')
|
||||
void import('react-native-view-shot')
|
||||
}, [])
|
||||
|
||||
const onNextPress = () => {
|
||||
|
||||
@@ -567,7 +567,7 @@ export const ComposePost = ({
|
||||
FileSystem.Paths.cache,
|
||||
tempFileName,
|
||||
)
|
||||
sourceFile.copy(tempFile)
|
||||
await sourceFile.copy(tempFile)
|
||||
logger.debug('restoreVideo: copied to temp file', {
|
||||
source: videoInfo.uri,
|
||||
temp: tempFile.uri,
|
||||
|
||||
@@ -50,7 +50,7 @@ export async function saveMediaToLocal(
|
||||
|
||||
try {
|
||||
const sourceFile = new File(normalizedSource)
|
||||
sourceFile.copy(destFile)
|
||||
await sourceFile.copy(destFile)
|
||||
// Update cache after successful save
|
||||
mediaExistsCache.set(localRefPath, true)
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {useCallback} from 'react'
|
||||
import * as MediaLibrary from 'expo-media-library'
|
||||
import * as MediaLibrary from 'expo-media-library/legacy'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
|
||||
@@ -369,7 +369,7 @@ export function TabBar({
|
||||
</Animated.View>
|
||||
</ScrollView>
|
||||
</BlockDrawerGesture>
|
||||
<View style={[t.atoms.border_contrast_low, styles.outerBottomBorder]} />
|
||||
<View style={[t.atoms.bg_contrast_100, styles.outerBottomBorder]} />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -470,6 +470,6 @@ const styles = StyleSheet.create({
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: '100%',
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
height: StyleSheet.hairlineWidth,
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user