[MOB-96] Haptics on tabs interaction and more (#2464)

Haptics on tabs interaction and more
This commit is contained in:
ameer2468 2024-05-08 20:41:34 +03:00 committed by GitHub
parent 893452d8c8
commit 853f0d4185
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 112 additions and 72 deletions

View file

@ -41,6 +41,7 @@
"expo-av": "^13.10.5",
"expo-blur": "^12.9.2",
"expo-build-properties": "~0.11.1",
"expo-haptics": "~12.8.1",
"expo-image": "^1.10.6",
"expo-linking": "~6.2.2",
"expo-media-library": "~15.9.1",

View file

@ -8,6 +8,7 @@ import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';
import { useExplorerStore } from '~/stores/explorerStore';
import { useActionsModalStore } from '~/stores/modalStore';
import * as Haptics from 'expo-haptics';
import { tw } from '~/lib/tailwind';
import ScreenContainer from '../layout/ScreenContainer';
import FileItem from './FileItem';
@ -39,6 +40,7 @@ const Explorer = (props: Props) => {
const { modalRef, setData } = useActionsModalStore();
function handlePress(data: ExplorerItem) {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
if (isPath(data) && data.item.is_dir && data.item.location_id !== null) {
navigation.push('Location', {
id: data.item.location_id,
@ -50,6 +52,12 @@ const Explorer = (props: Props) => {
}
}
function handleLongPress(data: ExplorerItem) {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
setData(data);
modalRef.current?.present();
}
return (
<ScreenContainer tabHeight={props.tabHeight} scrollview={false} style={'gap-0 py-0'}>
<Menu />
@ -71,7 +79,10 @@ const Explorer = (props: Props) => {
: item.item.id.toString()
}
renderItem={({ item }) => (
<Pressable onPress={() => handlePress(item)}>
<Pressable
onPress={() => handlePress(item)}
onLongPress={() => handleLongPress(item)}
>
{store.layoutMode === 'grid' ? (
<FileItem data={item} />
) : (

View file

@ -1,6 +1,6 @@
import { ExplorerItem, getItemFilePath } from '@sd/client';
import React from 'react';
import { Text, View } from 'react-native';
import { ExplorerItem, getItemFilePath } from '@sd/client';
import { tw, twStyle } from '~/lib/tailwind';
import { getExplorerStore } from '~/stores/explorerStore';
@ -20,7 +20,7 @@ const FileRow = ({ data }: FileRowProps) => {
})}
>
<FileThumb data={data} size={0.6} />
<View style={tw`ml-3`}>
<View style={tw`ml-3 max-w-[80%]`}>
<Text numberOfLines={1} style={tw`text-center text-xs font-medium text-ink-dull`}>
{filePath?.name}
{filePath?.extension && `.${filePath.extension}`}

View file

@ -1,8 +1,5 @@
import { DocumentDirectoryPath } from '@dr.pogodin/react-native-fs';
import { getIcon } from '@sd/assets/util';
import { Image } from 'expo-image';
import { useEffect, useLayoutEffect, useMemo, useState, type PropsWithChildren } from 'react';
import { View } from 'react-native';
import {
getExplorerItemData,
getItemFilePath,
@ -10,6 +7,9 @@ import {
isDarkTheme,
type ExplorerItem
} from '@sd/client';
import { Image } from 'expo-image';
import { useEffect, useLayoutEffect, useMemo, useState, type PropsWithChildren } from 'react';
import { View } from 'react-native';
import { flattenThumbnailKey, useExplorerStore } from '~/stores/explorerStore';
import { tw } from '../../lib/tailwind';

View file

@ -1,8 +1,8 @@
import { useQueryClient } from '@tanstack/react-query';
import { Object as SDObject, useLibraryMutation } from '@sd/client';
import * as Haptics from 'expo-haptics';
import { Heart } from 'phosphor-react-native';
import { useState } from 'react';
import { Pressable, PressableProps } from 'react-native';
import { Object as SDObject, useLibraryMutation } from '@sd/client';
type Props = {
data: SDObject;
@ -10,13 +10,13 @@ type Props = {
};
const FavoriteButton = (props: Props) => {
const queryClient = useQueryClient();
const [favorite, setFavorite] = useState(props.data.favorite);
const { mutate: toggleFavorite, isLoading } = useLibraryMutation('files.setFavorite', {
onSuccess: () => {
// TODO: Invalidate search queries
setFavorite(!favorite);
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
}
});

View file

@ -1,5 +1,3 @@
import React from 'react';
import { Alert, Pressable, View, ViewStyle } from 'react-native';
import {
ExplorerItem,
getExplorerItemData,
@ -8,6 +6,8 @@ import {
isPath,
useLibraryQuery
} from '@sd/client';
import React from 'react';
import { Alert, Pressable, View, ViewStyle } from 'react-native';
import { InfoPill, PlaceholderPill } from '~/components/primitive/InfoPill';
import { tw, twStyle } from '~/lib/tailwind';
@ -30,7 +30,7 @@ const InfoTagPills = ({ data, style }: Props) => {
return (
<View style={twStyle('mt-1 flex flex-row flex-wrap', style)}>
{/* Kind */}
<InfoPill containerStyle={tw`mr-1`} text={getExplorerItemData(data).kind} />
<InfoPill containerStyle={tw`mr-1`} text={isDir ? 'Folder' : getExplorerItemData(data).kind} />
{/* Extension */}
{filePath?.extension && (
<InfoPill text={filePath.extension} containerStyle={tw`mr-1`} />

View file

@ -2,6 +2,7 @@ import { Text, View } from 'react-native';
import { ClassInput } from 'twrnc';
import { twStyle } from '~/lib/tailwind';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Icon, IconName } from '../icons/Icon';
interface Props {
@ -10,14 +11,17 @@ interface Props {
style?: ClassInput; //Tailwind classes
iconSize?: number; //Size of the icon
textSize?: ClassInput; //Size of the text
includeHeaderHeight?: boolean; //Height of the header
}
const Empty = ({ description, icon, style, textSize = 'text-sm', iconSize = 38 }: Props) => {
const Empty = ({ description, icon, style, includeHeaderHeight = false, textSize = 'text-sm', iconSize = 38 }: Props) => {
const headerHeight = useSafeAreaInsets().top;
return (
<View
style={twStyle(
`relative mx-auto h-auto w-full flex-col items-center justify-center overflow-hidden
rounded-md border border-dashed border-sidebar-line p-4`,
{marginBottom: includeHeaderHeight ? headerHeight : 0},
style
)}
>

View file

@ -1,3 +1,10 @@
import {
byteSize,
getIndexedItemFilePath,
getItemObject,
useLibraryMutation,
useLibraryQuery
} from '@sd/client';
import dayjs from 'dayjs';
import {
Copy,
@ -13,13 +20,6 @@ import {
import { PropsWithChildren, useRef } from 'react';
import { Pressable, Text, View, ViewStyle } from 'react-native';
import FileViewer from 'react-native-file-viewer';
import {
byteSize,
getIndexedItemFilePath,
getItemObject,
useLibraryMutation,
useLibraryQuery
} from '@sd/client';
import FileThumb from '~/components/explorer/FileThumb';
import FavoriteButton from '~/components/explorer/sections/FavoriteButton';
import InfoTagPills from '~/components/explorer/sections/InfoTagPills';
@ -34,7 +34,7 @@ type ActionsContainerProps = PropsWithChildren<{
}>;
const ActionsContainer = ({ children, style }: ActionsContainerProps) => (
<View style={twStyle('rounded-lg bg-app-box py-3.5', style)}>{children}</View>
<View style={twStyle('rounded-lg border border-app-box bg-app py-3.5', style)}>{children}</View>
);
type ActionsItemProps = {
@ -61,7 +61,7 @@ const ActionsItem = ({ icon, onPress, title, isDanger = false }: ActionsItemProp
);
};
const ActionDivider = () => <View style={tw`my-3.5 h-[0.5px] bg-app-line/80`} />;
const ActionDivider = () => <View style={tw`my-3.5 h-[0.5px] bg-app-box`} />;
export const ActionsModal = () => {
const fileInfoRef = useRef<ModalRef>(null);

View file

@ -9,6 +9,7 @@ import Rive, { RiveRef } from 'rive-react-native';
import { Style } from 'twrnc/dist/esm/types';
import { tw } from '~/lib/tailwind';
import * as Haptics from 'expo-haptics';
import { RootStackParamList } from '.';
import BrowseStack, { BrowseStackParamList } from './tabs/BrowseStack';
import NetworkStack, { NetworkStackParamList } from './tabs/NetworkStack';
@ -145,6 +146,7 @@ export default function TabNavigator() {
})}
listeners={() => ({
focus: () => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
setActiveIndex(index);
},
})}

View file

@ -1,6 +1,8 @@
import { useEffect } from 'react';
import { useLibraryQuery, useObjectsExplorerQuery } from '@sd/client';
import { useEffect } from 'react';
import Explorer from '~/components/explorer/Explorer';
import Empty from '~/components/layout/Empty';
import { tw } from '~/lib/tailwind';
import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';
export default function TagScreen({ navigation, route }: BrowseStackScreenProps<'Tag'>) {
@ -21,5 +23,14 @@ export default function TagScreen({ navigation, route }: BrowseStackScreenProps<
});
}, [tagData?.name, navigation]);
return <Explorer {...objects} />;
return <Explorer
isEmpty={objects.count === 0}
emptyComponent={<Empty
includeHeaderHeight
icon={'Tags'}
style={tw`flex-1 items-center justify-center border-0`}
textSize="text-md"
iconSize={100}
description={'No items assigned to this tag'}
/>} {...objects} />;
}

View file

@ -116,10 +116,9 @@ const SearchScreen = ({ navigation }: SearchStackScreenProps<'Search'>) => {
isEmpty={noObjects}
emptyComponent={
<Empty
includeHeaderHeight
icon={noSearch ? 'Search' : 'FolderNoSpace'}
style={twStyle('flex-1 items-center justify-center border-0', {
marginBottom: headerHeight
})}
style={tw`flex-1 items-center justify-center border-0`}
textSize="text-md"
iconSize={100}
description={noSearch ? 'Add filters or type to search for files' : 'No files found'}

View file

@ -147,7 +147,7 @@ importers:
version: 2.16.0
'@tauri-apps/cli':
specifier: next
version: 2.0.0-beta.15
version: 2.0.0-beta.16
'@types/react':
specifier: ^18.2.67
version: 18.2.67
@ -404,6 +404,9 @@ importers:
expo-build-properties:
specifier: ~0.11.1
version: 0.11.1(expo@50.0.13(@babel/core@7.24.0)(@react-native/babel-preset@0.73.21(@babel/core@7.24.0)(@babel/preset-env@7.24.0(@babel/core@7.24.0))))
expo-haptics:
specifier: ~12.8.1
version: 12.8.1(expo@50.0.13(@babel/core@7.24.0)(@react-native/babel-preset@0.73.21(@babel/core@7.24.0)(@babel/preset-env@7.24.0(@babel/core@7.24.0))))
expo-image:
specifier: ^1.10.6
version: 1.10.6(expo@50.0.13(@babel/core@7.24.0)(@react-native/babel-preset@0.73.21(@babel/core@7.24.0)(@babel/preset-env@7.24.0(@babel/core@7.24.0))))
@ -5080,68 +5083,68 @@ packages:
resolution: {integrity: sha512-Nxtj28NYUo5iwYkpYslxmOPkdI2WkELU2e3UH9nbJm9Ydki2CQwJVGQxx4EANtdZcMNsEsUzRqaDTvEUYH1l6w==}
engines: {node: '>= 18', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
'@tauri-apps/cli-darwin-arm64@2.0.0-beta.15':
resolution: {integrity: sha512-M4owBLoRdJb2/IK48KOQDU3j5xrjqGxa539rDXMjvaKydBk8x+aLdk3xZNsk/owHTI1GnrQZsPCMQaOgetYHaw==}
'@tauri-apps/cli-darwin-arm64@2.0.0-beta.16':
resolution: {integrity: sha512-5Gif4AvpJmnyLj3HO3AEl1RVrr4ast6mDQiXoLwe75bfWq1pj9VwsS5SuSrUKtB8YBSnnclcJwkqwa6soY/xkg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@tauri-apps/cli-darwin-x64@2.0.0-beta.15':
resolution: {integrity: sha512-ECpatfJdT4xKyFoE7tNEtTUIRxjQ2XSXa0TQkP3g7Kn7H/jRse+7pYe69jASA7shixajatAwmD4bXNT8jYRyNA==}
'@tauri-apps/cli-darwin-x64@2.0.0-beta.16':
resolution: {integrity: sha512-6Cia8lGSroyoXKvfRI+Dv8Xinr27lptDzGZnd8mT9V0xPg73xcWxPKiTkuxPmLQTrQKVAurfsX3DwwgK8m9kSw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@tauri-apps/cli-linux-arm-gnueabihf@2.0.0-beta.15':
resolution: {integrity: sha512-GQz2nnPwIamzDbmmfGWvmmoLthOkOBs0RO5u72KYAa78ZRFTx7S6AovnxJv48Fq+zeGGdDKoD9+ZG2Ue+sCL4w==}
'@tauri-apps/cli-linux-arm-gnueabihf@2.0.0-beta.16':
resolution: {integrity: sha512-1mQ0flIt0wrX4QLPwd8f1QFsuFjLPQtWuiObK63K0/YZmDS2yzKT6jnGqNCJsSiyXE2/36gKSyWh6OVpX8U7xg==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
'@tauri-apps/cli-linux-arm64-gnu@2.0.0-beta.15':
resolution: {integrity: sha512-YBIfq0GbmIsWmRy6dVuDv3oMJN7a3R8HGVPMsa1W526AdCxoZDiPOQpSQN4VihJlbebUHxS/HyYF6maCY8uGzA==}
'@tauri-apps/cli-linux-arm64-gnu@2.0.0-beta.16':
resolution: {integrity: sha512-CjgwOvaslvy06m36faZ40noQaBu37gcXtD0HlCgAMofDZz7fUWQJn3xE7r8fegXmY0oMKZ9ah8dgwd5KSk+L+Q==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@tauri-apps/cli-linux-arm64-musl@2.0.0-beta.15':
resolution: {integrity: sha512-2ZBXoShz7UfqVGmc85mhwjI6ckdtrk15V69adxt/x+VS68yK6Ddbj+yqlffpeFNL90fZrsVhFoRIDqgkxtwksQ==}
'@tauri-apps/cli-linux-arm64-musl@2.0.0-beta.16':
resolution: {integrity: sha512-JMtryDJckutFzNpwFgh98o9Z4Vw1pwImYmJIDLpCPSqYIfd+mrBgPZFTaGl11ZsQnllqt4FNXlYR8T+ey7ZpfQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@tauri-apps/cli-linux-x64-gnu@2.0.0-beta.15':
resolution: {integrity: sha512-cwJqIIdc4Kq9sBl/vYc+Y95iMe+mlTYUj7ZnSn4YAbLKFz432bGg6uBn2qHXFN5jzwXtEOVZiB1zDZ2kveVoAQ==}
'@tauri-apps/cli-linux-x64-gnu@2.0.0-beta.16':
resolution: {integrity: sha512-3dQGCKsbjaIzk4UM7Jf5FzBJpBJ1OfwBOwkVv2M4O7EDLNZi9brDR+I41eqyFhTabEcHJoLhtURLbD25dJuiug==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@tauri-apps/cli-linux-x64-musl@2.0.0-beta.15':
resolution: {integrity: sha512-nNuxZ8/qs0vQbdLO2hovskZGxwGn2z4x1QFJuL4xwd6Tryy9vVcznvyZS+t/72dCLoIkY9pKZQq5nYtAHYfTEg==}
'@tauri-apps/cli-linux-x64-musl@2.0.0-beta.16':
resolution: {integrity: sha512-t+wdk/VCn8l9y1fhRQPfvZyz3Or7QEPTxXNobbUzbtckFsf/LqTxjaajOBmSGnZpoTDFvwVOmalDaylILxuM5g==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@tauri-apps/cli-win32-arm64-msvc@2.0.0-beta.15':
resolution: {integrity: sha512-DXiXMTE00INjBkTgq1CYduMWgUwQ0NvLw+uXfu8BUupA+aOlv9ODhsGu7bZSaxKx4/glwxNAGZum4kQ0E0AxUg==}
'@tauri-apps/cli-win32-arm64-msvc@2.0.0-beta.16':
resolution: {integrity: sha512-ouP0iiRMTNaKyz6c06LucMR5P585r2XJ3/GlzNWtUfP4EaP8mZAENB0ro9VZl10++7Z658MdWxSAf4+Qmkj0jQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@tauri-apps/cli-win32-ia32-msvc@2.0.0-beta.15':
resolution: {integrity: sha512-ajEQdW2jx2raPp7eDYryJkbBrgI8PIY1dz5ro8FweRrRmbotaUlclsro1kfNMQrfDah8+qfwnRvW3MahOBE5Wg==}
'@tauri-apps/cli-win32-ia32-msvc@2.0.0-beta.16':
resolution: {integrity: sha512-BiBkv3IesPNGXVaampxpB+ub0tz2sGu+6OLzxSm1QTp+2ZSw/qeXi/icvJl5azmOyee4ZWBBiuBzdVY88QH+Vw==}
engines: {node: '>= 10'}
cpu: [ia32]
os: [win32]
'@tauri-apps/cli-win32-x64-msvc@2.0.0-beta.15':
resolution: {integrity: sha512-yzsSgoiY0PmFiR5LvVOFr1b7h9l3aLPPQFlDG6+kRMrxCo7x7Pbyh4D5cqiMUuZO0QacwSP38EH6w0F88Y+4OA==}
'@tauri-apps/cli-win32-x64-msvc@2.0.0-beta.16':
resolution: {integrity: sha512-rrJeC7eAT6diQpnI3aaflhvtKyTryywbhHLG/c1QyPhdxA7Or6nflo5KzWLd6q3GQqKRbvz5dDtxwFn+XLo+rQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@tauri-apps/cli@2.0.0-beta.15':
resolution: {integrity: sha512-3pCvc54QfsRY+i9B7w3Q5jPAGtf8p+g7N/BamWPeiW6YqDqbHi9rNVI3SzrHkRRNOJnzMW8E5a8G0HziOluZGg==}
'@tauri-apps/cli@2.0.0-beta.16':
resolution: {integrity: sha512-ELaPqTekAVfTU4lFf7k/Z422DKXk/uDWi7ppI8TuQOqcXjrxlXMvv/Y1eC2tem9vMeuOIU0Jg53pOhOu0w8JIQ==}
engines: {node: '>= 10'}
hasBin: true
@ -5588,7 +5591,7 @@ packages:
resolution: {integrity: sha512-STEDMVQGww5lhCuNXVSQfbfuNII5E08QWkvAw5Qwf+bj2WT+JkG1uc+5/vXA3AOYMDHVOSpL+9rcbEUiHIm2dw==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
'@typescript-eslint/parser': ^7.0.0
'@typescript-eslint/parser': ^7.1.1
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
@ -7822,6 +7825,11 @@ packages:
peerDependencies:
expo: '*'
expo-haptics@12.8.1:
resolution: {integrity: sha512-ntLsHkfle8K8w9MW8pZEw92ZN3sguaGUSSIxv30fPKNeQFu7Cq/h47Qv3tONv2MO3wU48N9FbKnant6XlfptpA==}
peerDependencies:
expo: '*'
expo-image@1.10.6:
resolution: {integrity: sha512-vcnAIym1eU8vQgV1re1E7rVQZStJimBa4aPDhjFfzMzbddAF7heJuagyewiUkTzbZUwYzPaZAie6VJPyWx9Ueg==}
peerDependencies:
@ -18660,48 +18668,48 @@ snapshots:
'@tauri-apps/api@2.0.0-beta.4': {}
'@tauri-apps/cli-darwin-arm64@2.0.0-beta.15':
'@tauri-apps/cli-darwin-arm64@2.0.0-beta.16':
optional: true
'@tauri-apps/cli-darwin-x64@2.0.0-beta.15':
'@tauri-apps/cli-darwin-x64@2.0.0-beta.16':
optional: true
'@tauri-apps/cli-linux-arm-gnueabihf@2.0.0-beta.15':
'@tauri-apps/cli-linux-arm-gnueabihf@2.0.0-beta.16':
optional: true
'@tauri-apps/cli-linux-arm64-gnu@2.0.0-beta.15':
'@tauri-apps/cli-linux-arm64-gnu@2.0.0-beta.16':
optional: true
'@tauri-apps/cli-linux-arm64-musl@2.0.0-beta.15':
'@tauri-apps/cli-linux-arm64-musl@2.0.0-beta.16':
optional: true
'@tauri-apps/cli-linux-x64-gnu@2.0.0-beta.15':
'@tauri-apps/cli-linux-x64-gnu@2.0.0-beta.16':
optional: true
'@tauri-apps/cli-linux-x64-musl@2.0.0-beta.15':
'@tauri-apps/cli-linux-x64-musl@2.0.0-beta.16':
optional: true
'@tauri-apps/cli-win32-arm64-msvc@2.0.0-beta.15':
'@tauri-apps/cli-win32-arm64-msvc@2.0.0-beta.16':
optional: true
'@tauri-apps/cli-win32-ia32-msvc@2.0.0-beta.15':
'@tauri-apps/cli-win32-ia32-msvc@2.0.0-beta.16':
optional: true
'@tauri-apps/cli-win32-x64-msvc@2.0.0-beta.15':
'@tauri-apps/cli-win32-x64-msvc@2.0.0-beta.16':
optional: true
'@tauri-apps/cli@2.0.0-beta.15':
'@tauri-apps/cli@2.0.0-beta.16':
optionalDependencies:
'@tauri-apps/cli-darwin-arm64': 2.0.0-beta.15
'@tauri-apps/cli-darwin-x64': 2.0.0-beta.15
'@tauri-apps/cli-linux-arm-gnueabihf': 2.0.0-beta.15
'@tauri-apps/cli-linux-arm64-gnu': 2.0.0-beta.15
'@tauri-apps/cli-linux-arm64-musl': 2.0.0-beta.15
'@tauri-apps/cli-linux-x64-gnu': 2.0.0-beta.15
'@tauri-apps/cli-linux-x64-musl': 2.0.0-beta.15
'@tauri-apps/cli-win32-arm64-msvc': 2.0.0-beta.15
'@tauri-apps/cli-win32-ia32-msvc': 2.0.0-beta.15
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-beta.15
'@tauri-apps/cli-darwin-arm64': 2.0.0-beta.16
'@tauri-apps/cli-darwin-x64': 2.0.0-beta.16
'@tauri-apps/cli-linux-arm-gnueabihf': 2.0.0-beta.16
'@tauri-apps/cli-linux-arm64-gnu': 2.0.0-beta.16
'@tauri-apps/cli-linux-arm64-musl': 2.0.0-beta.16
'@tauri-apps/cli-linux-x64-gnu': 2.0.0-beta.16
'@tauri-apps/cli-linux-x64-musl': 2.0.0-beta.16
'@tauri-apps/cli-win32-arm64-msvc': 2.0.0-beta.16
'@tauri-apps/cli-win32-ia32-msvc': 2.0.0-beta.16
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-beta.16
'@tauri-apps/plugin-dialog@2.0.0-beta.2':
dependencies:
@ -22129,6 +22137,10 @@ snapshots:
expo: 50.0.13(@babel/core@7.24.0)(@react-native/babel-preset@0.73.21(@babel/core@7.24.0)(@babel/preset-env@7.24.0(@babel/core@7.24.0)))
fontfaceobserver: 2.3.0
expo-haptics@12.8.1(expo@50.0.13(@babel/core@7.24.0)(@react-native/babel-preset@0.73.21(@babel/core@7.24.0)(@babel/preset-env@7.24.0(@babel/core@7.24.0)))):
dependencies:
expo: 50.0.13(@babel/core@7.24.0)(@react-native/babel-preset@0.73.21(@babel/core@7.24.0)(@babel/preset-env@7.24.0(@babel/core@7.24.0)))
expo-image@1.10.6(expo@50.0.13(@babel/core@7.24.0)(@react-native/babel-preset@0.73.21(@babel/core@7.24.0)(@babel/preset-env@7.24.0(@babel/core@7.24.0)))):
dependencies:
'@react-native/assets-registry': 0.73.1