diff --git a/JoyboyCommunity/package.json b/JoyboyCommunity/package.json index 4c3481a3..d64e7926 100644 --- a/JoyboyCommunity/package.json +++ b/JoyboyCommunity/package.json @@ -23,8 +23,8 @@ "@noble/curves": "^1.4.0", "@nostr-dev-kit/ndk": "^2.8.2", "@react-native-async-storage/async-storage": "^1.23.1", - "@react-native-community/netinfo": "^11.3.2", - "@react-native-picker/picker": "^2.7.7", + "@react-native-community/netinfo": "11.3.1", + "@react-native-picker/picker": "2.7.5", "@react-navigation/bottom-tabs": "^6.5.20", "@react-navigation/native": "^6.1.17", "@react-navigation/native-stack": "^6.9.26", @@ -40,13 +40,13 @@ "buffer": "^6.0.3", "crypto-es": "^2.1.0", "events": "^3.3.0", - "expo": "~51.0.8", + "expo": "~51.0.17", "expo-application": "^5.9.1", "expo-clipboard": "~6.0.3", "expo-crypto": "~13.0.2", - "expo-image-picker": "~15.0.5", + "expo-image-picker": "~15.0.7", "expo-linking": "~6.3.1", - "expo-secure-store": "~13.0.1", + "expo-secure-store": "~13.0.2", "expo-splash-screen": "~0.27.4", "expo-status-bar": "~1.12.1", "fast-text-encoding": "^1.0.6", @@ -56,7 +56,7 @@ "pbkdf2": "^3.1.2", "react": "18.2.0", "react-dom": "18.2.0", - "react-native": "0.74.1", + "react-native": "0.74.3", "react-native-gesture-handler": "2.16.2", "react-native-get-random-values": "^1.11.0", "react-native-keychain": "^8.2.0", @@ -66,9 +66,9 @@ "react-native-qrcode-svg": "^6.3.1", "react-native-reanimated": "~3.10.1", "react-native-redash": "^18.1.3", - "react-native-safe-area-context": "^4.8.2", - "react-native-screens": "^3.29.0", - "react-native-svg": "^15.3.0", + "react-native-safe-area-context": "4.10.1", + "react-native-screens": "3.31.1", + "react-native-svg": "15.2.0", "react-native-tab-view": "^3.5.2", "react-native-web": "~0.19.6", "starknet": "6.9.0", diff --git a/JoyboyCommunity/src/app/App.tsx b/JoyboyCommunity/src/app/App.tsx index a39b4914..05fb2701 100644 --- a/JoyboyCommunity/src/app/App.tsx +++ b/JoyboyCommunity/src/app/App.tsx @@ -3,15 +3,20 @@ import '@walletconnect/react-native-compat'; import * as Font from 'expo-font'; import * as SplashScreen from 'expo-splash-screen'; import {useCallback, useEffect, useState} from 'react'; -import {StatusBar, View} from 'react-native'; +import {View} from 'react-native'; +import {useTips} from '../hooks'; +import {useToast} from '../hooks/modals'; import {Router} from './Router'; -// Keep the splash screen visible while we fetch resources SplashScreen.preventAutoHideAsync(); export default function App() { const [appIsReady, setAppIsReady] = useState(false); + const [sentTipNotification, setSentTipNotification] = useState(false); + + const tips = useTips(); + const {showToast} = useToast(); useEffect(() => { (async () => { @@ -27,31 +32,41 @@ export default function App() { } catch (e) { console.warn(e); } finally { - // Tell the application to render setAppIsReady(true); } })(); }, []); + useEffect(() => { + const interval = setInterval(() => tips.refetch(), 2 * 60 * 1_000); + return () => clearInterval(interval); + }, [tips]); + + useEffect(() => { + if (sentTipNotification) return; + + const hasUnclaimedTip = (tips.data ?? []).some((tip) => !tip.claimed && tip.depositId); + if (hasUnclaimedTip) { + setSentTipNotification(true); + showToast({ + type: 'info', + title: 'You have unclaimed tips', + }); + } + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [tips.data]); + const onLayoutRootView = useCallback(async () => { if (appIsReady) { - // This tells the splash screen to hide immediately! If we call this after - // `setAppIsReady`, then we may see a blank screen while the app is - // loading its initial state and rendering its first pixels. So instead, - // we hide the splash screen once we know the root view has already - // performed layout. await SplashScreen.hideAsync(); } }, [appIsReady]); - if (!appIsReady) { - return null; - } + if (!appIsReady) return null; return ( - - ); diff --git a/JoyboyCommunity/src/app/Router.tsx b/JoyboyCommunity/src/app/Router.tsx index cbb1bc66..e15b1117 100644 --- a/JoyboyCommunity/src/app/Router.tsx +++ b/JoyboyCommunity/src/app/Router.tsx @@ -1,10 +1,11 @@ import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import {NavigationContainer} from '@react-navigation/native'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; +import {useEffect, useState} from 'react'; import {StyleSheet, View} from 'react-native'; import {Icon} from '../components'; -import {useTheme} from '../hooks'; +import {useStyles} from '../hooks'; import {CreateAccount} from '../screens/Auth/CreateAccount'; import {Login} from '../screens/Auth/Login'; import {SaveKeys} from '../screens/Auth/SaveKeys'; @@ -15,7 +16,9 @@ import {PostDetail} from '../screens/PostDetail'; import {Profile} from '../screens/Profile'; import {Tips} from '../screens/Tips'; import {useAuth} from '../store/auth'; +import {ThemedStyleSheet} from '../styles'; import {AuthStackParams, HomeBottomStackParams, MainStackParams, RootStackParams} from '../types'; +import {retrievePublicKey} from '../utils/storage'; const RootStack = createNativeStackNavigator(); const AuthStack = createNativeStackNavigator(); @@ -23,22 +26,17 @@ const MainStack = createNativeStackNavigator(); const HomeBottomTabsStack = createBottomTabNavigator(); const HomeBottomTabNavigator: React.FC = () => { - const theme = useTheme(); + const styles = useStyles(stylesheet); + const {publicKey} = useAuth(); return ( { tabBarActiveTintColor: 'white', tabBarInactiveTintColor: '', tabBarIcon: ({focused}) => ( - + { }} /> - ( - - - {focused && } - - ), - }} - /> - { tabBarActiveTintColor: 'white', tabBarInactiveTintColor: 'grey', tabBarIcon: ({focused}) => ( - + { ( - + { }; const AuthNavigator: React.FC = () => { + const [publicKey, setPublicKey] = useState(undefined); + + useEffect(() => { + retrievePublicKey().then((key) => { + setPublicKey(key); + }); + }); + + if (publicKey === undefined) return null; + return ( - + {publicKey && } @@ -165,3 +153,21 @@ export const Router: React.FC = () => { ); }; + +const stylesheet = ThemedStyleSheet((theme) => ({ + sceneContainer: { + backgroundColor: theme.colors.background, + }, + + tabBar: { + backgroundColor: theme.colors.surface, + borderTopColor: theme.colors.divider, + borderTopWidth: StyleSheet.hairlineWidth, + }, + tabBarIcon: { + flex: 1, + gap: 2, + alignItems: 'center', + justifyContent: 'center', + }, +})); diff --git a/JoyboyCommunity/src/app/Wrapper.tsx b/JoyboyCommunity/src/app/Wrapper.tsx index f23b91d3..1968416b 100644 --- a/JoyboyCommunity/src/app/Wrapper.tsx +++ b/JoyboyCommunity/src/app/Wrapper.tsx @@ -37,17 +37,17 @@ export const Wrapper: React.FC = () => { - - - - - + + + + + - - - - - + + + + + diff --git a/JoyboyCommunity/src/assets/feed/feed-bg.png b/JoyboyCommunity/src/assets/feed-background.png similarity index 100% rename from JoyboyCommunity/src/assets/feed/feed-bg.png rename to JoyboyCommunity/src/assets/feed-background.png diff --git a/JoyboyCommunity/src/assets/feed/images/post.svg b/JoyboyCommunity/src/assets/feed/images/post.svg deleted file mode 100644 index e16ae4a4..00000000 --- a/JoyboyCommunity/src/assets/feed/images/post.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/JoyboyCommunity/src/assets/feed/images/story-1.png b/JoyboyCommunity/src/assets/feed/images/story-1.png deleted file mode 100644 index 6936d0af..00000000 Binary files a/JoyboyCommunity/src/assets/feed/images/story-1.png and /dev/null differ diff --git a/JoyboyCommunity/src/assets/feed/images/story-2.png b/JoyboyCommunity/src/assets/feed/images/story-2.png deleted file mode 100644 index 6d5f4a3d..00000000 Binary files a/JoyboyCommunity/src/assets/feed/images/story-2.png and /dev/null differ diff --git a/JoyboyCommunity/src/assets/feed/images/story-3.png b/JoyboyCommunity/src/assets/feed/images/story-3.png deleted file mode 100644 index 57a35e55..00000000 Binary files a/JoyboyCommunity/src/assets/feed/images/story-3.png and /dev/null differ diff --git a/JoyboyCommunity/src/assets/feed/images/story-4.png b/JoyboyCommunity/src/assets/feed/images/story-4.png deleted file mode 100644 index 4f8f95dd..00000000 Binary files a/JoyboyCommunity/src/assets/feed/images/story-4.png and /dev/null differ diff --git a/JoyboyCommunity/src/assets/feed/images/story-5.png b/JoyboyCommunity/src/assets/feed/images/story-5.png deleted file mode 100644 index 87decf5a..00000000 Binary files a/JoyboyCommunity/src/assets/feed/images/story-5.png and /dev/null differ diff --git a/JoyboyCommunity/src/assets/feed/images/story-bg.png b/JoyboyCommunity/src/assets/feed/images/story-bg.png deleted file mode 100644 index 378b880d..00000000 Binary files a/JoyboyCommunity/src/assets/feed/images/story-bg.png and /dev/null differ diff --git a/JoyboyCommunity/src/assets/icons.tsx b/JoyboyCommunity/src/assets/icons.tsx index 0881e91f..1f344a23 100644 --- a/JoyboyCommunity/src/assets/icons.tsx +++ b/JoyboyCommunity/src/assets/icons.tsx @@ -510,3 +510,20 @@ export const FlagIcon: React.FC = (props) => ( /> ); + +export const CloseIcon: React.FC = (props) => ( + + + + +); diff --git a/JoyboyCommunity/src/components/Button/index.tsx b/JoyboyCommunity/src/components/Button/index.tsx index 9f263f74..c581ce03 100644 --- a/JoyboyCommunity/src/components/Button/index.tsx +++ b/JoyboyCommunity/src/components/Button/index.tsx @@ -26,7 +26,7 @@ export const Button: React.FC = ({ style: styleProp, ...pressableProps }) => { - const styles = useStyles(stylesheet, variant, block, disabled, small); + const styles = useStyles(stylesheet, variant, !!block, !!disabled, !!small); return ( ({ @@ -11,6 +13,8 @@ export default ThemedStyleSheet((theme) => ({ alignItems: 'center', paddingVertical: Spacing.xxsmall, paddingHorizontal: Spacing.medium, + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: theme.colors.divider, }, logoContainer: { diff --git a/JoyboyCommunity/src/components/IconButton/index.tsx b/JoyboyCommunity/src/components/IconButton/index.tsx index feb36a53..f4924514 100644 --- a/JoyboyCommunity/src/components/IconButton/index.tsx +++ b/JoyboyCommunity/src/components/IconButton/index.tsx @@ -26,7 +26,7 @@ export const IconButton: React.FC = ({ const color = useColor(colorProp); const backgroundColor = useColor(backgroundColorProp); - const styles = useStyles(stylesheet, disabled, backgroundColor); + const styles = useStyles(stylesheet, !!disabled, backgroundColor); return ( & MenuSubComponents = ({handle, open, onClose, c }, [animation, open]); const animatedMenuStyles = useAnimatedStyle(() => { - const menuWidth = Math.min(width / 1.6, 320); + const menuWidth = Math.min(width / 1.5, 320); const menuStyle = { ...styles.menu, diff --git a/JoyboyCommunity/src/components/Menu/styles.ts b/JoyboyCommunity/src/components/Menu/styles.ts index 7657eccd..d2d2fdc8 100644 --- a/JoyboyCommunity/src/components/Menu/styles.ts +++ b/JoyboyCommunity/src/components/Menu/styles.ts @@ -31,6 +31,10 @@ export default ThemedStyleSheet((theme) => ({ backgroundColor: theme.colors.background, borderRadius: 16, overflow: 'hidden', + shadowColor: theme.colors.shadow, + shadowOffset: {width: 0, height: 2}, + shadowRadius: 4, + elevation: 2, }, menuItem: { diff --git a/JoyboyCommunity/src/components/PickerContainer/index.tsx b/JoyboyCommunity/src/components/PickerContainer/index.tsx index 41b50a11..dbd6a102 100644 --- a/JoyboyCommunity/src/components/PickerContainer/index.tsx +++ b/JoyboyCommunity/src/components/PickerContainer/index.tsx @@ -6,7 +6,7 @@ import {Modalize} from '../Modalize'; import {Text, TextProps} from '../Text'; export type PickerContainerProps = { - selectedValue: string; + selectedValue?: string; modalizeTitle: string; style?: StyleProp; diff --git a/JoyboyCommunity/src/components/Skeleton/RootScreenContainer.tsx b/JoyboyCommunity/src/components/Skeleton/RootScreenContainer.tsx index 81aa2499..dd3846b3 100644 --- a/JoyboyCommunity/src/components/Skeleton/RootScreenContainer.tsx +++ b/JoyboyCommunity/src/components/Skeleton/RootScreenContainer.tsx @@ -1,9 +1,29 @@ -import {View, ViewProps} from 'react-native'; +import {Platform, View, ViewProps} from 'react-native'; -import {useTheme} from '../../hooks'; +import {WEB_MAX_WIDTH} from '../../constants/misc'; +import {useStyles} from '../../hooks'; +import {ThemedStyleSheet} from '../../styles'; -export const RootScreenContainer: React.FC = ({style, ...props}) => { - const theme = useTheme(); +export const RootScreenContainer: React.FC = ({style, children, ...props}) => { + const styles = useStyles(stylesheet); - return ; + return ( + + {children} + + ); }; + +const stylesheet = ThemedStyleSheet((theme) => ({ + container: { + flex: 1, + alignItems: 'center', + backgroundColor: theme.colors.background, + }, + + content: { + flex: 1, + width: '100%', + maxWidth: Platform.OS === 'web' ? WEB_MAX_WIDTH : '100%', + }, +})); diff --git a/JoyboyCommunity/src/components/Story/index.tsx b/JoyboyCommunity/src/components/Story/index.tsx deleted file mode 100644 index 2067601f..00000000 --- a/JoyboyCommunity/src/components/Story/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import {Image, ImageSourcePropType, View} from 'react-native'; - -import {Text} from '../Text'; -import styles from './styles'; - -export type StoryProps = { - image: ImageSourcePropType; - name: string; -}; - -export const Story: React.FC = ({image, name}) => { - return ( - - - - - - - - {name} - - - ); -}; diff --git a/JoyboyCommunity/src/components/Story/styles.ts b/JoyboyCommunity/src/components/Story/styles.ts deleted file mode 100644 index 1e0364e9..00000000 --- a/JoyboyCommunity/src/components/Story/styles.ts +++ /dev/null @@ -1,23 +0,0 @@ -import {StyleSheet} from 'react-native'; - -import {Spacing} from '../../styles'; - -export default StyleSheet.create({ - container: { - alignItems: 'center', - }, - - imageContainer: { - position: 'relative', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - }, - image: { - position: 'absolute', - }, - - name: { - paddingTop: Spacing.xxsmall, - }, -}); diff --git a/JoyboyCommunity/src/components/Toast/index.tsx b/JoyboyCommunity/src/components/Toast/index.tsx index 06b1a23c..50316c13 100644 --- a/JoyboyCommunity/src/components/Toast/index.tsx +++ b/JoyboyCommunity/src/components/Toast/index.tsx @@ -2,6 +2,7 @@ import {View} from 'react-native'; import {ErrorIcon, InfoIcon, SuccessIcon} from '../../assets/icons'; import {useStyles, useTheme} from '../../hooks'; +import {IconButton} from '../IconButton'; import {Text} from '../Text'; import stylesheet from './styles'; @@ -10,7 +11,11 @@ export type ToastProps = { title: string; }; -export const Toast: React.FC = ({type, title}) => { +export const Toast: React.FC void}> = ({ + type, + title, + onDismiss, +}) => { const theme = useTheme(); const styles = useStyles(stylesheet, type); @@ -37,6 +42,14 @@ export const Toast: React.FC = ({type, title}) => { {title} + + ); }; diff --git a/JoyboyCommunity/src/components/Toast/styles.ts b/JoyboyCommunity/src/components/Toast/styles.ts index 6aa99eb1..fe41a77c 100644 --- a/JoyboyCommunity/src/components/Toast/styles.ts +++ b/JoyboyCommunity/src/components/Toast/styles.ts @@ -22,7 +22,13 @@ export default ThemedStyleSheet((theme, type: 'success' | 'info' | 'error') => ( backgroundColor: theme.colors.errorLight, }), }, + text: { flex: 1, }, + + closeIcon: { + backgroundColor: theme.colors.transparent, + padding: Spacing.none, + }, })); diff --git a/JoyboyCommunity/src/components/index.ts b/JoyboyCommunity/src/components/index.ts index fc607ea1..5cbae276 100644 --- a/JoyboyCommunity/src/components/index.ts +++ b/JoyboyCommunity/src/components/index.ts @@ -15,7 +15,6 @@ export {InputAccessoryView} from './Skeleton/InputAccessoryView'; export {KeyboardFixedView} from './Skeleton/KeyboardFixedView'; export {RootScreenContainer} from './Skeleton/RootScreenContainer'; export {SquareInput} from './SquareInput'; -export {Story} from './Story'; export {Text} from './Text'; export {TextButton} from './TextButton'; export {Toast} from './Toast'; diff --git a/JoyboyCommunity/src/constants/env.ts b/JoyboyCommunity/src/constants/env.ts index 672e7b39..a701baca 100644 --- a/JoyboyCommunity/src/constants/env.ts +++ b/JoyboyCommunity/src/constants/env.ts @@ -1,11 +1,14 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ + import {constants} from 'starknet'; export const NETWORK_NAME = process.env.EXPO_PUBLIC_NETWORK as constants.NetworkName; -export const PROVIDER_URL = process.env.EXPO_PUBLIC_PROVIDER_URL; +export const CHAIN_ID = constants.StarknetChainId[NETWORK_NAME]; +export const PROVIDER_URL = process.env.EXPO_PUBLIC_PROVIDER_URL!; -export const BACKEND_URL = process.env.EXPO_PUBLIC_BACKEND_URL; +export const BACKEND_URL = process.env.EXPO_PUBLIC_BACKEND_URL!; -export const WALLET_CONNECT_ID = process.env.EXPO_PUBLIC_WC_ID; +export const WALLET_CONNECT_ID = process.env.EXPO_PUBLIC_WC_ID!; if (!Object.keys(constants.NetworkName).includes(NETWORK_NAME)) { throw new Error(`Invalid network name: ${NETWORK_NAME}`); diff --git a/JoyboyCommunity/src/constants/misc.ts b/JoyboyCommunity/src/constants/misc.ts index f666ca60..c2e94e3d 100644 --- a/JoyboyCommunity/src/constants/misc.ts +++ b/JoyboyCommunity/src/constants/misc.ts @@ -14,6 +14,9 @@ export enum Entrypoint { export enum EventKey { DepositEvent = '0xa1db419bdf20c7726cf74c30394c4300e5645db4e3cacaf897da05faabae03', TransferEvent = '0x15884c9d44b49803fec52bec32166b4a87f9683725e9c83e8b0bc12306fc10', + ClaimEvent = '0x1338111cc170c56fecb176d35cca4c04823f0b8d9c64cfb956c97b236ea6fc6', } export const DEFAULT_TIMELOCK = 7 * 24 * 60 * 60 * 1_000; // 7 days + +export const WEB_MAX_WIDTH = 520; diff --git a/JoyboyCommunity/src/context/TipModal.tsx b/JoyboyCommunity/src/context/TipModal.tsx index f006b95f..7d47c973 100644 --- a/JoyboyCommunity/src/context/TipModal.tsx +++ b/JoyboyCommunity/src/context/TipModal.tsx @@ -47,7 +47,14 @@ export const TipModalProvider: React.FC = ({children}) {children} - + {successModal && } diff --git a/JoyboyCommunity/src/context/Toast/AnimatedToast.tsx b/JoyboyCommunity/src/context/Toast/AnimatedToast.tsx index 18a28ad5..86eab963 100644 --- a/JoyboyCommunity/src/context/Toast/AnimatedToast.tsx +++ b/JoyboyCommunity/src/context/Toast/AnimatedToast.tsx @@ -1,3 +1,4 @@ +import {useEffect} from 'react'; import {Gesture, GestureDetector} from 'react-native-gesture-handler'; import Animated, { measure, @@ -10,17 +11,20 @@ import Animated, { import {clamp, snapPoint} from 'react-native-redash'; import {Toast} from '../../components'; -import {useToast} from '../../hooks'; -import {ToastConfig} from './ToastContext'; - -export const AnimatedToast: React.FC<{toast: ToastConfig}> = ({toast}) => { - const {hideToast} = useToast(); +import type {ToastConfig} from './ToastContext'; +export const AnimatedToast: React.FC<{toast: ToastConfig; hide: () => void}> = ({toast, hide}) => { const containerRef = useAnimatedRef(); const top = useSharedValue(0); const translateY = useSharedValue(0); + useEffect(() => { + setTimeout(onDismiss, toast.timeout ?? 10_000); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const pan = Gesture.Pan() .onChange(({translationY}) => { translateY.value = clamp(translationY, -999, 0); @@ -33,7 +37,7 @@ export const AnimatedToast: React.FC<{toast: ToastConfig}> = ({toast}) => { if (snapTo < 0) { top.value = withTiming(1, {duration: 200}, () => { - runOnJS(hideToast)(toast.key); + runOnJS(hide)(); }); } @@ -45,10 +49,16 @@ export const AnimatedToast: React.FC<{toast: ToastConfig}> = ({toast}) => { transform: [{translateY: translateY.value}], })); + const onDismiss = () => { + top.value = withTiming(1, {duration: 200}, () => { + runOnJS(hide)(); + }); + }; + return ( - + ); diff --git a/JoyboyCommunity/src/context/Toast/ToastContext.tsx b/JoyboyCommunity/src/context/Toast/ToastContext.tsx index d9753dcf..67e4e7b4 100644 --- a/JoyboyCommunity/src/context/Toast/ToastContext.tsx +++ b/JoyboyCommunity/src/context/Toast/ToastContext.tsx @@ -9,10 +9,11 @@ import styles from './styles'; export type ToastConfig = ToastProps & { key: string; + timeout?: number; }; export type ToastContextType = { - showToast: (toast: ToastProps) => () => void; + showToast: (toast: Omit) => () => void; hideToast: (key: string) => void; }; @@ -26,7 +27,7 @@ export const ToastProvider: React.FC<{children: React.ReactNode}> = ({children}) }, []); const showToast = useCallback( - (toast: ToastProps) => { + (toast: Omit) => { const key = randomUUID(); setToasts((prev) => [...prev, {...toast, key}]); @@ -46,7 +47,7 @@ export const ToastProvider: React.FC<{children: React.ReactNode}> = ({children}) {toasts.map((toast) => ( - + hideToast(toast.key)} /> ))} diff --git a/JoyboyCommunity/src/hooks/api/useApiMutation.ts b/JoyboyCommunity/src/hooks/api/useApiMutation.ts index 28c8104b..d827438d 100644 --- a/JoyboyCommunity/src/hooks/api/useApiMutation.ts +++ b/JoyboyCommunity/src/hooks/api/useApiMutation.ts @@ -26,7 +26,7 @@ export const useApiMutation = < useEffect(() => { if (showErrorToast && mutation.error) { const {response} = mutation.error; - if (!response || typeof response.data !== 'object' || !('code' in response.data)) { + if (!response?.data || typeof response.data !== 'object' || !('code' in response.data)) { showToast({ type: 'error', title: 'Request failed with no response, please try again later.', diff --git a/JoyboyCommunity/src/hooks/index.ts b/JoyboyCommunity/src/hooks/index.ts index e35c3279..db500bff 100644 --- a/JoyboyCommunity/src/hooks/index.ts +++ b/JoyboyCommunity/src/hooks/index.ts @@ -1,10 +1,7 @@ -export * from './api'; -export * from './modals'; export * from './nostr'; -export {useChainId} from './useChainId'; export {useColor} from './useColor'; export {useStyles} from './useStyles'; export {useTheme} from './useTheme'; export {useTips} from './useTips'; -export {useTransaction} from './useTransaction'; export {useWaitConnection} from './useWaitConnection'; +export {useWindowDimensions} from './useWindowDimensions'; diff --git a/JoyboyCommunity/src/hooks/modals/index.ts b/JoyboyCommunity/src/hooks/modals/index.ts index 71468a67..cff72690 100644 --- a/JoyboyCommunity/src/hooks/modals/index.ts +++ b/JoyboyCommunity/src/hooks/modals/index.ts @@ -1,5 +1,6 @@ export {useDialog} from './useDialog'; export {useTipModal} from './useTipModal'; export {useToast} from './useToast'; +export {useTransaction} from './useTransaction'; export {useTransactionModal} from './useTransactionModal'; export {useWalletModal} from './useWalletModal'; diff --git a/JoyboyCommunity/src/hooks/useTransaction.ts b/JoyboyCommunity/src/hooks/modals/useTransaction.ts similarity index 92% rename from JoyboyCommunity/src/hooks/useTransaction.ts rename to JoyboyCommunity/src/hooks/modals/useTransaction.ts index 99b3ccb5..c7f9938d 100644 --- a/JoyboyCommunity/src/hooks/useTransaction.ts +++ b/JoyboyCommunity/src/hooks/modals/useTransaction.ts @@ -1,7 +1,7 @@ import {ContractWriteVariables, useContractWrite} from '@starknet-react/core'; import {GetTransactionReceiptResponse} from 'starknet'; -import {useTransactionModal} from './modals/useTransactionModal'; +import {useTransactionModal} from './useTransactionModal'; export const useTransaction = () => { const {show: showTransactionModal, hide: hideTransactionModal, shown} = useTransactionModal(); diff --git a/JoyboyCommunity/src/hooks/nostr/useContacts.ts b/JoyboyCommunity/src/hooks/nostr/useContacts.ts index 23f59984..4c0e47cd 100644 --- a/JoyboyCommunity/src/hooks/nostr/useContacts.ts +++ b/JoyboyCommunity/src/hooks/nostr/useContacts.ts @@ -20,7 +20,7 @@ export const useContacts = (options?: UseContactsOptions) => { search: options?.search, }); - return contacts.tags.filter((tag) => tag[0] === 'p').map((tag) => tag[1]); + return contacts?.tags.filter((tag) => tag[0] === 'p').map((tag) => tag[1]) ?? []; }, placeholderData: [], }); diff --git a/JoyboyCommunity/src/hooks/nostr/useEditProfile.ts b/JoyboyCommunity/src/hooks/nostr/useEditProfile.ts index 3c8cfb03..b6f04ee8 100644 --- a/JoyboyCommunity/src/hooks/nostr/useEditProfile.ts +++ b/JoyboyCommunity/src/hooks/nostr/useEditProfile.ts @@ -6,16 +6,12 @@ import {useAuth} from '../../store/auth'; export const useEditProfile = () => { const {ndk} = useNostrContext(); - const {publicKey, privateKey} = useAuth(); + const {publicKey} = useAuth(); return useMutation({ mutationKey: ['editProfile'], mutationFn: async (data: NDKUserProfile) => { try { - if (!privateKey) { - throw new Error('Private key is required'); - } - const user = ndk.getUser({pubkey: publicKey}); await user.fetchProfile(); diff --git a/JoyboyCommunity/src/hooks/nostr/useNote.ts b/JoyboyCommunity/src/hooks/nostr/useNote.ts index ded45527..0261d604 100644 --- a/JoyboyCommunity/src/hooks/nostr/useNote.ts +++ b/JoyboyCommunity/src/hooks/nostr/useNote.ts @@ -18,7 +18,7 @@ export const useNote = (options: UseNoteOptions) => { ids: [options.noteId], }); - return note; + return note ?? undefined; }, }); }; diff --git a/JoyboyCommunity/src/hooks/nostr/useProfile.ts b/JoyboyCommunity/src/hooks/nostr/useProfile.ts index 96b68aef..8bd9849a 100644 --- a/JoyboyCommunity/src/hooks/nostr/useProfile.ts +++ b/JoyboyCommunity/src/hooks/nostr/useProfile.ts @@ -3,7 +3,7 @@ import {useQuery} from '@tanstack/react-query'; import {useNostrContext} from '../../context/NostrContext'; export type UseProfileOptions = { - publicKey: string; + publicKey?: string; }; export const useProfile = (options: UseProfileOptions) => { diff --git a/JoyboyCommunity/src/hooks/nostr/useReact.ts b/JoyboyCommunity/src/hooks/nostr/useReact.ts index 9ec58ef5..e86cf080 100644 --- a/JoyboyCommunity/src/hooks/nostr/useReact.ts +++ b/JoyboyCommunity/src/hooks/nostr/useReact.ts @@ -15,7 +15,7 @@ export const useReact = () => { event.tags = [ ['e', data.event.id], ['p', data.event.pubkey], - ['k', data.event.kind.toString()], + ['k', (data.event.kind ?? 1).toString()], ]; return event.publish(); diff --git a/JoyboyCommunity/src/hooks/nostr/useReactions.ts b/JoyboyCommunity/src/hooks/nostr/useReactions.ts index 233e4a87..29aff5c2 100644 --- a/JoyboyCommunity/src/hooks/nostr/useReactions.ts +++ b/JoyboyCommunity/src/hooks/nostr/useReactions.ts @@ -13,7 +13,7 @@ export const useReactions = (options?: UseReactionsOptions) => { const {ndk} = useNostrContext(); return useQuery({ - queryKey: ['reactions', options?.authors, options?.search, options?.noteId], + queryKey: ['reactions', options?.noteId, options?.authors, options?.search], queryFn: async () => { const notes = await ndk.fetchEvents({ kinds: [NDKKind.Reaction], diff --git a/JoyboyCommunity/src/hooks/nostr/useReplyNotes.ts b/JoyboyCommunity/src/hooks/nostr/useReplyNotes.ts index 2d3f2820..8538a96f 100644 --- a/JoyboyCommunity/src/hooks/nostr/useReplyNotes.ts +++ b/JoyboyCommunity/src/hooks/nostr/useReplyNotes.ts @@ -18,7 +18,7 @@ export const useReplyNotes = (options?: UseReplyNotesOptions) => { getNextPageParam: (lastPage: any, allPages, lastPageParam) => { if (!lastPage?.length) return undefined; - const pageParam = lastPage[lastPage.length - 1].created_at; + const pageParam = lastPage[lastPage.length - 1].created_at - 1; if (!pageParam || pageParam === lastPageParam) return undefined; return pageParam; diff --git a/JoyboyCommunity/src/hooks/nostr/useReposts.ts b/JoyboyCommunity/src/hooks/nostr/useReposts.ts index 249058d7..9b912f2c 100644 --- a/JoyboyCommunity/src/hooks/nostr/useReposts.ts +++ b/JoyboyCommunity/src/hooks/nostr/useReposts.ts @@ -17,7 +17,7 @@ export const useReposts = (options?: UseRepostsOptions) => { getNextPageParam: (lastPage: any, allPages, lastPageParam) => { if (!lastPage?.length) return undefined; - const pageParam = lastPage[lastPage.length - 1].created_at; + const pageParam = lastPage[lastPage.length - 1].created_at - 1; if (!pageParam || pageParam === lastPageParam) return undefined; return pageParam; diff --git a/JoyboyCommunity/src/hooks/nostr/useRootNotes.ts b/JoyboyCommunity/src/hooks/nostr/useRootNotes.ts index 42cc9fe0..b88f29c7 100644 --- a/JoyboyCommunity/src/hooks/nostr/useRootNotes.ts +++ b/JoyboyCommunity/src/hooks/nostr/useRootNotes.ts @@ -17,25 +17,21 @@ export const useRootNotes = (options?: UseRootNotesOptions) => { getNextPageParam: (lastPage: any, allPages, lastPageParam) => { if (!lastPage?.length) return undefined; - const pageParam = lastPage[lastPage.length - 1].created_at; + const pageParam = lastPage[lastPage.length - 1].created_at - 1; if (!pageParam || pageParam === lastPageParam) return undefined; return pageParam; }, queryFn: async ({pageParam}) => { - try { - const notes = await ndk.fetchEvents({ - kinds: [NDKKind.Text], - authors: options?.authors, - search: options?.search, - until: pageParam || Math.round(Date.now() / 1000), - limit: 20, - }); + const notes = await ndk.fetchEvents({ + kinds: [NDKKind.Text], + authors: options?.authors, + search: options?.search, + until: pageParam || Math.round(Date.now() / 1000), + limit: 20, + }); - return [...notes].filter((note) => note.tags.every((tag) => tag[0] !== 'e')); - } catch (error) { - console.log('error', error); - } + return [...notes].filter((note) => note.tags.every((tag) => tag[0] !== 'e')); }, placeholderData: {pages: [], pageParams: []}, }); diff --git a/JoyboyCommunity/src/hooks/useChainId.ts b/JoyboyCommunity/src/hooks/useChainId.ts deleted file mode 100644 index 509652f7..00000000 --- a/JoyboyCommunity/src/hooks/useChainId.ts +++ /dev/null @@ -1,8 +0,0 @@ -import {starknetChainId, useNetwork} from '@starknet-react/core'; -import {useMemo} from 'react'; - -export const useChainId = () => { - const {chain} = useNetwork(); - - return useMemo(() => (chain.id ? starknetChainId(chain.id) : undefined), [chain.id]); -}; diff --git a/JoyboyCommunity/src/hooks/useColor.ts b/JoyboyCommunity/src/hooks/useColor.ts index 12a627b4..168393d1 100644 --- a/JoyboyCommunity/src/hooks/useColor.ts +++ b/JoyboyCommunity/src/hooks/useColor.ts @@ -1,11 +1,13 @@ -import {ColorProp} from '../styles'; +import {ColorProp, ThemeColorNames} from '../styles'; import {useTheme} from './useTheme'; -export const useColor = (color: ColorProp) => { +type Color = `#${string}` | `rgb${string}` | 'transparent'; + +export const useColor = (color: ColorProp): Color => { const theme = useTheme(); if (color === 'transparent') return 'transparent'; - if (color.startsWith('#') || color.startsWith('rgb')) return color; + if (color.startsWith('#') || color.startsWith('rgb')) return color as Color; - return theme.colors[color] ?? theme.colors.text; + return (theme.colors[color as ThemeColorNames] ?? theme.colors.text) as Color; }; diff --git a/JoyboyCommunity/src/hooks/useTips.ts b/JoyboyCommunity/src/hooks/useTips.ts index 4e640655..11bb320c 100644 --- a/JoyboyCommunity/src/hooks/useTips.ts +++ b/JoyboyCommunity/src/hooks/useTips.ts @@ -1,49 +1,80 @@ -import {useInfiniteQuery} from '@tanstack/react-query'; +import {useQuery} from '@tanstack/react-query'; import {uint256} from 'starknet'; import {ESCROW_ADDRESSES} from '../constants/contracts'; +import {CHAIN_ID} from '../constants/env'; import {EventKey} from '../constants/misc'; import {useAuth} from '../store/auth'; -import {useChainId} from './useChainId'; +import {parseClaimEvent, parseDepositEvent} from '../utils/events'; import {useRpcProvider} from './useRpcProvider'; export const useTips = () => { - const chainId = useChainId(); const provider = useRpcProvider(); const {publicKey} = useAuth(); - return useInfiniteQuery({ - initialPageParam: undefined as string | undefined, - queryKey: ['tips', chainId, publicKey], - getNextPageParam: ( - lastPage: Awaited>, - allPages, - lastPageParam, - ) => { - if (!lastPage?.continuation_token) return undefined; + return useQuery({ + queryKey: ['tips', CHAIN_ID, publicKey], + queryFn: async () => { + if (!publicKey) return []; - const pageParam = lastPage.continuation_token; - - if (!pageParam || pageParam === lastPageParam) return undefined; - return pageParam; - }, - queryFn: async ({pageParam}) => { const {low, high} = uint256.bnToUint256(`0x${publicKey}`); - const tips = await provider.getEvents({ - address: ESCROW_ADDRESSES[chainId], - keys: [ - [EventKey.DepositEvent, EventKey.TransferEvent], - [], - [], - [low.toString(), high.toString()], - ], - chunk_size: 1000, - continuation_token: pageParam, - }); - - return tips; + const getTipEvents = async ( + continuationToken?: string, + ): Promise>['events']> => { + const tips = await provider.getEvents({ + address: ESCROW_ADDRESSES[CHAIN_ID], + keys: [ + [EventKey.DepositEvent, EventKey.TransferEvent], + [], + [], + [low.toString(), high.toString()], + ], + to_block: 'pending', + chunk_size: 1000, + continuation_token: continuationToken, + }); + + if (tips.continuation_token) { + const next = await getTipEvents(tips.continuation_token); + return [...tips.events, ...next]; + } + + return tips.events; + }; + + const tipEvents = (await getTipEvents()) + .map((event) => parseDepositEvent(event)) + .filter((event): event is NonNullable> => !!event); + + const getClaimEvents = async ( + continuationToken?: string, + ): Promise>['events']> => { + const tips = await provider.getEvents({ + address: ESCROW_ADDRESSES[CHAIN_ID], + keys: [[EventKey.ClaimEvent], [], [], [low.toString()], [high.toString()]], + to_block: 'pending', + chunk_size: 1000, + continuation_token: continuationToken, + }); + + if (tips.continuation_token) { + const next = await getClaimEvents(tips.continuation_token); + return [...tips.events, ...next]; + } + + return tips.events; + }; + + const claimEvents = (await getClaimEvents()) + .map((event) => parseClaimEvent(event)) + .filter((event): event is NonNullable> => !!event); + + return tipEvents.map((tip) => ({ + ...tip, + claimed: claimEvents.findIndex((claim) => claim.depositId === tip.depositId) !== -1, + })); }, - placeholderData: {pages: [], pageParams: []}, + placeholderData: [], }); }; diff --git a/JoyboyCommunity/src/hooks/useWaitConnection.ts b/JoyboyCommunity/src/hooks/useWaitConnection.ts index 6bd93088..f662b859 100644 --- a/JoyboyCommunity/src/hooks/useWaitConnection.ts +++ b/JoyboyCommunity/src/hooks/useWaitConnection.ts @@ -9,7 +9,7 @@ export const useWaitConnection = () => { useEffect(() => { if (account.address && promise.current) { - promiseResolve.current(account); + promiseResolve.current?.(account); promise.current = undefined; promiseResolve.current = undefined; @@ -23,7 +23,7 @@ export const useWaitConnection = () => { if (promise.current) { // If a promise is already in progress, resolve it with false - promiseResolve.current(false); + promiseResolve.current?.(false); promise.current = undefined; promiseResolve.current = undefined; diff --git a/JoyboyCommunity/src/hooks/useWindowDimensions.ts b/JoyboyCommunity/src/hooks/useWindowDimensions.ts new file mode 100644 index 00000000..dc72a67f --- /dev/null +++ b/JoyboyCommunity/src/hooks/useWindowDimensions.ts @@ -0,0 +1,11 @@ +import {Platform, useWindowDimensions as useRNWindowDimensions} from 'react-native'; + +import {WEB_MAX_WIDTH} from '../constants/misc'; + +export const useWindowDimensions = () => { + const dimensions = useRNWindowDimensions(); + + if (Platform.OS === 'web') dimensions.width = WEB_MAX_WIDTH; + + return dimensions; +}; diff --git a/JoyboyCommunity/src/modules/Post/index.tsx b/JoyboyCommunity/src/modules/Post/index.tsx index 6a56ad2a..6f133c2f 100644 --- a/JoyboyCommunity/src/modules/Post/index.tsx +++ b/JoyboyCommunity/src/modules/Post/index.tsx @@ -1,5 +1,6 @@ import {NDKEvent} from '@nostr-dev-kit/ndk'; import {useNavigation} from '@react-navigation/native'; +import {useQueryClient} from '@tanstack/react-query'; import {useMemo, useState} from 'react'; import {Image, Pressable, View} from 'react-native'; import Animated, { @@ -13,15 +14,8 @@ import Animated, { import {CommentIcon, LikeFillIcon, LikeIcon, RepostIcon} from '../../assets/icons'; import {Avatar, IconButton, Menu, Text} from '../../components'; -import { - useProfile, - useReact, - useReactions, - useReplyNotes, - useStyles, - useTheme, - useTipModal, -} from '../../hooks'; +import {useProfile, useReact, useReactions, useReplyNotes, useStyles, useTheme} from '../../hooks'; +import {useTipModal} from '../../hooks/modals'; import {useAuth} from '../../store/auth'; import {MainStackNavigationProps} from '../../types'; import {getElapsedTimeStringFull} from '../../utils/timestamp'; @@ -48,6 +42,7 @@ export const Post: React.FC = ({asComment, event}) => { const userReaction = useReactions({authors: [publicKey], noteId: event?.id}); const comments = useReplyNotes({noteId: event?.id}); const react = useReact(); + const queryClient = useQueryClient(); const [menuOpen, setMenuOpen] = useState(false); @@ -81,17 +76,19 @@ export const Post: React.FC = ({asComment, event}) => { }; const handleNavigateToPostDetails = () => { + if (!event?.id) return; navigation.navigate('PostDetail', {postId: event?.id, post: event}); }; /** @TODO comment in Nostr */ const toggleLike = async () => { + if (!event?.id) return; + await react.mutateAsync( {event, type: isLiked ? 'dislike' : 'like'}, { onSuccess: () => { - reactions.refetch(); - userReaction.refetch(); + queryClient.invalidateQueries({queryKey: ['reactions', event?.id]}); scale.value = withSequence( withTiming(1.5, {duration: 100, easing: Easing.out(Easing.ease)}), // Scale up @@ -111,8 +108,6 @@ export const Post: React.FC = ({asComment, event}) => { )} - {/* TODO: different rendering base on kind =1,6,7 and tags for kind = 1 */} - handleProfilePress(event?.pubkey)}> @@ -143,7 +138,7 @@ export const Post: React.FC = ({asComment, event}) => { )} - {getElapsedTimeStringFull(event.created_at * 1000)} + {getElapsedTimeStringFull((event?.created_at ?? Date.now()) * 1000)} @@ -171,7 +166,7 @@ export const Post: React.FC = ({asComment, event}) => { - {repostedEvent?.content ?? event?.content} + {event?.content} {postSource && ( @@ -206,6 +201,8 @@ export const Post: React.FC = ({asComment, event}) => { label={profile?.username ? `Tip @${profile.username}` : 'Tip'} icon="CoinIcon" onPress={() => { + if (!event) return; + showTipModal(event); setMenuOpen(false); }} diff --git a/JoyboyCommunity/src/modules/TipModal/index.tsx b/JoyboyCommunity/src/modules/TipModal/index.tsx index b47501c0..002698ba 100644 --- a/JoyboyCommunity/src/modules/TipModal/index.tsx +++ b/JoyboyCommunity/src/modules/TipModal/index.tsx @@ -8,224 +8,225 @@ import {CallData, uint256} from 'starknet'; import {Avatar, Button, Input, Modalize, Picker, Text} from '../../components'; import {ESCROW_ADDRESSES} from '../../constants/contracts'; +import {CHAIN_ID} from '../../constants/env'; import {DEFAULT_TIMELOCK, Entrypoint} from '../../constants/misc'; import {TOKENS, TokenSymbol} from '../../constants/tokens'; -import { - useChainId, - useDialog, - useProfile, - useStyles, - useTipModal, - useTransaction, - useWaitConnection, - useWalletModal, -} from '../../hooks'; +import {useProfile, useStyles, useWaitConnection} from '../../hooks'; +import {useDialog} from '../../hooks/modals/useDialog'; +import {useTransaction} from '../../hooks/modals/useTransaction'; +import {useWalletModal} from '../../hooks/modals/useWalletModal'; import {decimalsScale} from '../../utils/helpers'; +import {TipSuccessModalProps} from '../TipSuccessModal'; import stylesheet from './styles'; export type TipModal = Modalize; export type TipModalProps = { event?: NDKEvent; -}; -export const TipModal = forwardRef(({event}, ref) => { - const styles = useStyles(stylesheet); + show: (event: NDKEvent) => void; + hide: () => void; + showSuccess: (props: TipSuccessModalProps) => void; + hideSuccess: () => void; +}; - const [token, setToken] = useState(TokenSymbol.ETH); - const [amount, setAmount] = useState(''); +export const TipModal = forwardRef( + ({event, hide: hideTipModal, showSuccess, hideSuccess}, ref) => { + const styles = useStyles(stylesheet); - const {data: profile} = useProfile({publicKey: event?.pubkey}); + const [token, setToken] = useState(TokenSymbol.ETH); + const [amount, setAmount] = useState(''); - const chainId = useChainId(); - const account = useAccount(); - const walletModal = useWalletModal(); - const sendTransaction = useTransaction(); - const waitConnection = useWaitConnection(); + const {data: profile} = useProfile({publicKey: event?.pubkey}); - const {hide: hideTipModal, showSuccess, hideSuccess} = useTipModal(); - const {showDialog, hideDialog} = useDialog(); + const account = useAccount(); + const walletModal = useWalletModal(); + const sendTransaction = useTransaction(); + const waitConnection = useWaitConnection(); - const isActive = !!amount && !!token; + const {showDialog, hideDialog} = useDialog(); - const onTipPress = async () => { - if (!account.address) { - walletModal.show(); + const isActive = !!amount && !!token; - const result = await waitConnection(); - if (!result) return; - } + const onTipPress = async () => { + if (!account.address) { + walletModal.show(); - const amountUint256 = uint256.bnToUint256( - new Fraction(1, Math.ceil(1 / Number(amount))) - .multiply(decimalsScale(TOKENS[token][chainId].decimals)) - .toFixed(0), - ); - - const approveCallData = CallData.compile([ - ESCROW_ADDRESSES[chainId], // Contract address - amountUint256, // Amount - ]); - - const depositCallData = CallData.compile([ - amountUint256, // Amount - TOKENS[token][chainId].address, // Token address - uint256.bnToUint256(`0x${event.pubkey}`), // Recipient nostr pubkey - DEFAULT_TIMELOCK, // timelock - ]); - - const receipt = await sendTransaction({ - calls: [ - { - contractAddress: TOKENS[token][chainId].address, - entrypoint: Entrypoint.APPROVE, - calldata: approveCallData, - }, - { - contractAddress: ESCROW_ADDRESSES[chainId], - entrypoint: Entrypoint.DEPOSIT, - calldata: depositCallData, - }, - ], - }); - - if (receipt?.isSuccess()) { - hideTipModal(); - showSuccess({ - amount: Number(amount), - symbol: token, - user: - (profile?.nip05 && `@${profile.nip05}`) ?? - profile?.displayName ?? - profile?.name ?? - event?.pubkey, - hide: hideSuccess, - }); - } else { - let description = 'Please Try Again Later.'; - if (receipt.isRejected()) { - description = receipt.transaction_failure_reason.error_message; + const result = await waitConnection(); + if (!result) return; } - showDialog({ - title: 'Failed to send the tip', - description, - buttons: [{type: 'secondary', label: 'Close', onPress: () => hideDialog()}], + const amountUint256 = uint256.bnToUint256( + new Fraction(1, Math.ceil(1 / Number(amount))) + .multiply(decimalsScale(TOKENS[token][CHAIN_ID].decimals)) + .toFixed(0), + ); + + const approveCallData = CallData.compile([ + ESCROW_ADDRESSES[CHAIN_ID], // Contract address + amountUint256, // Amount + ]); + + const depositCallData = CallData.compile([ + amountUint256, // Amount + TOKENS[token][CHAIN_ID].address, // Token address + uint256.bnToUint256(`0x${event?.pubkey}`), // Recipient nostr pubkey + DEFAULT_TIMELOCK, // timelock + ]); + + const receipt = await sendTransaction({ + calls: [ + { + contractAddress: TOKENS[token][CHAIN_ID].address, + entrypoint: Entrypoint.APPROVE, + calldata: approveCallData, + }, + { + contractAddress: ESCROW_ADDRESSES[CHAIN_ID], + entrypoint: Entrypoint.DEPOSIT, + calldata: depositCallData, + }, + ], }); - } - }; - - return ( - - - - - - - - - - {profile?.displayName ?? profile?.name ?? event?.pubkey} - - {profile?.nip05 && ( - - @{profile?.nip05} + if (receipt?.isSuccess()) { + hideTipModal(); + showSuccess({ + amount: Number(amount), + symbol: token, + user: + (profile?.nip05 && `@${profile.nip05}`) ?? + profile?.displayName ?? + profile?.name ?? + event?.pubkey, + hide: hideSuccess, + }); + } else { + let description = 'Please Try Again Later.'; + if (receipt?.isRejected()) { + description = receipt.transaction_failure_reason.error_message; + } + + showDialog({ + title: 'Failed to send the tip', + description, + buttons: [{type: 'secondary', label: 'Close', onPress: () => hideDialog()}], + }); + } + }; + + return ( + + + + + + + + + + {profile?.displayName ?? profile?.name ?? event?.pubkey} - )} + + {profile?.nip05 && ( + + @{profile?.nip05} + + )} + - - - 16 likes + + 16 likes + - - - {event?.content} - - - - - - setToken(itemValue as TokenSymbol)} + - {Object.values(TOKENS).map((tkn) => ( - - ))} - + {event?.content} + + + + + + setToken(itemValue as TokenSymbol)} + > + {Object.values(TOKENS).map((tkn) => ( + + ))} + + + + - - + + + + Sending + - - - - Sending - + {amount.length > 0 && token.length > 0 ? ( + + {amount} {token} + + ) : ( + + ... + + )} + - {amount.length > 0 && token.length > 0 ? ( - - {amount} {token} + + + to - ) : ( - - ... + + {(profile?.nip05 && `@${profile.nip05}`) ?? + profile?.displayName ?? + profile?.name ?? + event?.pubkey} - )} + - - - to - - - {(profile?.nip05 && `@${profile.nip05}`) ?? - profile?.displayName ?? - profile?.name ?? - event?.pubkey} - + + - - - - - - - - Tip friends and support creators with your favorite tokens. - - - - ); -}); + + + Tip friends and support creators with your favorite tokens. + + + + ); + }, +); TipModal.displayName = 'TipModal'; diff --git a/JoyboyCommunity/src/modules/TipSuccessModal/index.tsx b/JoyboyCommunity/src/modules/TipSuccessModal/index.tsx index 9de529d9..4dccb016 100644 --- a/JoyboyCommunity/src/modules/TipSuccessModal/index.tsx +++ b/JoyboyCommunity/src/modules/TipSuccessModal/index.tsx @@ -6,7 +6,7 @@ import {useStyles} from '../../hooks'; import stylesheet from './styles'; export type TipSuccessModalProps = { - user: string; + user?: string; symbol: string; amount: number; hide: () => void; diff --git a/JoyboyCommunity/src/modules/WalletModal/index.tsx b/JoyboyCommunity/src/modules/WalletModal/index.tsx index 87e012ba..952f1f5d 100644 --- a/JoyboyCommunity/src/modules/WalletModal/index.tsx +++ b/JoyboyCommunity/src/modules/WalletModal/index.tsx @@ -5,7 +5,8 @@ import {SvgXml} from 'react-native-svg'; import {Button, Modal, Text} from '../../components'; import {ARGENT_X_INSTALL_URL, BRAAVOS_INSTALL_URL} from '../../constants/urls'; -import {useDialog, useStyles, useTheme} from '../../hooks'; +import {useStyles, useTheme} from '../../hooks'; +import {useDialog} from '../../hooks/modals/useDialog'; import stylesheet from './styles'; export type WalletModalProps = { @@ -26,49 +27,51 @@ export const WalletModal: React.FC = ({hide}) => { - {connectors.map((connector) => ( - { - if ( - (connector.id === 'argentX' || connector.id === 'braavos') && - !globalThis[`starknet_${connector.id}`] - ) { - showDialog({ - title: 'Wallet is not available', - description: `${connector.name} is not available to use. Please install the wallet and try again.`, - buttons: [ - { - type: 'secondary', - label: `Install ${connector.name}`, - onPress: () => { - if (connector.id === 'argentX') Linking.openURL(ARGENT_X_INSTALL_URL); - if (connector.id === 'braavos') Linking.openURL(BRAAVOS_INSTALL_URL); - hideDialog(); + {connectors.map((connector) => { + const icon = connector.icon[theme.dark ? 'dark' : 'light']; + + return ( + { + if ( + (connector.id === 'argentX' || connector.id === 'braavos') && + !(globalThis as any)[`starknet_${connector.id}`] + ) { + showDialog({ + title: 'Wallet is not available', + description: `${connector.name} is not available to use. Please install the wallet and try again.`, + buttons: [ + { + type: 'secondary', + label: `Install ${connector.name}`, + onPress: () => { + if (connector.id === 'argentX') Linking.openURL(ARGENT_X_INSTALL_URL); + if (connector.id === 'braavos') Linking.openURL(BRAAVOS_INSTALL_URL); + hideDialog(); + }, + }, + { + type: 'default', + label: 'Close', + onPress: hideDialog, }, - }, - { - type: 'default', - label: 'Close', - onPress: hideDialog, - }, - ], - }); + ], + }); + hide(); + return; + } + connect({connector}); hide(); - return; - } - connect({connector}); - hide(); - }} - style={styles.connector} - > - {Platform.OS !== 'web' && ( - - )} + }} + style={styles.connector} + > + {Platform.OS !== 'web' && icon ? : null} - {connector.name} - - ))} + {connector.name} + + ); + })} - - navigation.navigate('Login')}>Login ); }; diff --git a/JoyboyCommunity/src/screens/Auth/Login.tsx b/JoyboyCommunity/src/screens/Auth/Login.tsx index ae40bad0..055882d3 100644 --- a/JoyboyCommunity/src/screens/Auth/Login.tsx +++ b/JoyboyCommunity/src/screens/Auth/Login.tsx @@ -4,7 +4,8 @@ import {Platform} from 'react-native'; import {LockIcon} from '../../assets/icons'; import {Button, Input, TextButton} from '../../components'; -import {useTheme, useToast} from '../../hooks'; +import {useTheme} from '../../hooks'; +import {useDialog, useToast} from '../../hooks/modals'; import {Auth} from '../../modules/Auth'; import {useAuth} from '../../store/auth'; import {AuthLoginScreenProps} from '../../types'; @@ -19,8 +20,10 @@ export const Login: React.FC = ({navigation}) => { const theme = useTheme(); const setAuth = useAuth((state) => state.setAuth); - const [password, setPassword] = useState(null); + const [password, setPassword] = useState(''); + const {showToast} = useToast(); + const {showDialog, hideDialog} = useDialog(); useEffect(() => { (async () => { @@ -34,7 +37,7 @@ export const Login: React.FC = ({navigation}) => { }, []); const handleLogin = async () => { - if (password?.length == 0 || !password) { + if (!password) { showToast({type: 'error', title: 'Password is required'}); return; } @@ -57,6 +60,25 @@ export const Login: React.FC = ({navigation}) => { setAuth(publicKey, privateKeyHex); }; + const handleCreateAccount = () => { + showDialog({ + title: 'WARNING', + description: + 'Creating a new account will delete your current account. Are you sure you want to continue?', + buttons: [ + {type: 'default', label: 'Cancel', onPress: hideDialog}, + { + type: 'primary', + label: 'Continue', + onPress: () => { + navigation.navigate('CreateAccount'); + hideDialog(); + }, + }, + ], + }); + }; + return ( = ({navigation}) => { Login - navigation.navigate('CreateAccount')}>Create Account + Create Account ); }; diff --git a/JoyboyCommunity/src/screens/Auth/SaveKeys.tsx b/JoyboyCommunity/src/screens/Auth/SaveKeys.tsx index 77de378b..4f9f6337 100644 --- a/JoyboyCommunity/src/screens/Auth/SaveKeys.tsx +++ b/JoyboyCommunity/src/screens/Auth/SaveKeys.tsx @@ -4,7 +4,8 @@ import {TouchableOpacity, View} from 'react-native'; import {CopyIconStack} from '../../assets/icons'; import {InfoIcon} from '../../assets/icons'; import {Button, Input, Text} from '../../components'; -import {useStyles, useTheme, useToast} from '../../hooks'; +import {useStyles, useTheme} from '../../hooks'; +import {useToast} from '../../hooks/modals'; import {Auth} from '../../modules/Auth'; import {useAuth} from '../../store/auth'; import {AuthSaveKeysScreenProps} from '../../types'; diff --git a/JoyboyCommunity/src/screens/CreatePost/index.tsx b/JoyboyCommunity/src/screens/CreatePost/index.tsx index 4f9a88ee..d68d40b2 100644 --- a/JoyboyCommunity/src/screens/CreatePost/index.tsx +++ b/JoyboyCommunity/src/screens/CreatePost/index.tsx @@ -1,21 +1,23 @@ -import {useNavigation} from '@react-navigation/native'; +import {useQueryClient} from '@tanstack/react-query'; import {useState} from 'react'; import {KeyboardAvoidingView, Pressable, TextInput, View} from 'react-native'; import {SafeAreaView} from 'react-native-safe-area-context'; import {CopyIcon, GalleryIcon, GifIcon, SendIconContained} from '../../assets/icons'; import {TextButton} from '../../components'; -import {useSendNote, useStyles, useTheme, useToast} from '../../hooks'; +import {useSendNote, useStyles, useTheme} from '../../hooks'; +import {useToast} from '../../hooks/modals'; +import {CreatePostScreenProps} from '../../types'; import stylesheet from './styles'; -export const CreatePost: React.FC = () => { - const navigation = useNavigation(); - +export const CreatePost: React.FC = ({navigation}) => { const theme = useTheme(); const styles = useStyles(stylesheet); const [note, setNote] = useState(); + const sendNote = useSendNote(); + const queryClient = useQueryClient(); const {showToast} = useToast(); const handleSendNote = () => { @@ -29,6 +31,8 @@ export const CreatePost: React.FC = () => { { onSuccess() { showToast({type: 'success', title: 'Note sent successfully'}); + queryClient.invalidateQueries({queryKey: ['rootNotes']}); + navigation.goBack(); }, onError() { showToast({ diff --git a/JoyboyCommunity/src/screens/EditProfile/index.tsx b/JoyboyCommunity/src/screens/EditProfile/index.tsx index 64233456..d005e768 100644 --- a/JoyboyCommunity/src/screens/EditProfile/index.tsx +++ b/JoyboyCommunity/src/screens/EditProfile/index.tsx @@ -7,7 +7,8 @@ import {ScrollView, TouchableOpacity, View} from 'react-native'; import {CopyIconStack} from '../../assets/icons'; import {Button, SquareInput, Text} from '../../components'; -import {useEditProfile, useProfile, useStyles, useTheme, useToast} from '../../hooks'; +import {useEditProfile, useProfile, useStyles, useTheme} from '../../hooks'; +import {useToast} from '../../hooks/modals'; import {useAuth} from '../../store/auth'; import {EditProfileScreenProps} from '../../types'; import {ProfileHead} from '../Profile/Head'; @@ -80,12 +81,12 @@ export const EditProfile: React.FC = () => { }; const initialFormValues: FormValues = { - username: profile.data?.nip05, - displayName: profile.data?.displayName ?? profile.data?.name, - bio: profile.data?.about, - telegram: profile.data?.telegram?.toString(), - github: profile.data?.github?.toString(), - twitter: profile.data?.twitter?.toString(), + username: profile.data?.nip05 ?? '', + displayName: profile.data?.displayName ?? profile.data?.name ?? '', + bio: profile.data?.about ?? '', + telegram: profile.data?.telegram?.toString() ?? '', + github: profile.data?.github?.toString() ?? '', + twitter: profile.data?.twitter?.toString() ?? '', }; const onSubmitPress = () => { @@ -121,12 +122,12 @@ export const EditProfile: React.FC = () => { onProfilePhotoUpload={onProfilePhotoUpload} onCoverPhotoUpload={onCoverPhotoUpload} profilePhoto={ - (profilePhoto?.uri && {uri: profilePhoto.uri}) || - (profile.data?.image && {uri: profile.data?.image}) + (profilePhoto?.uri ? {uri: profilePhoto.uri} : undefined) || + (profile.data?.image ? {uri: profile.data?.image} : undefined) } coverPhoto={ - (coverPhoto?.uri && {uri: coverPhoto.uri}) || - (profile.data?.banner && {uri: profile.data?.banner}) + (coverPhoto?.uri ? {uri: coverPhoto.uri} : undefined) || + (profile.data?.banner ? {uri: profile.data?.banner} : undefined) } buttons={ + {item.depositId ? ( + <> + {item.claimed ? ( + + ) : ( + + )} + ) : null} @@ -119,7 +119,7 @@ export const Tips: React.FC = () => { - {event.sender} + {item.sender} diff --git a/JoyboyCommunity/src/services/provider.ts b/JoyboyCommunity/src/services/provider.ts index a4fe741c..ecee2864 100644 --- a/JoyboyCommunity/src/services/provider.ts +++ b/JoyboyCommunity/src/services/provider.ts @@ -1,11 +1,11 @@ import {Chain} from '@starknet-react/chains'; -import {constants, RpcProvider} from 'starknet'; +import {RpcProvider} from 'starknet'; -import {NETWORK_NAME, PROVIDER_URL} from '../constants/env'; +import {CHAIN_ID, PROVIDER_URL} from '../constants/env'; export const provider = new RpcProvider({ nodeUrl: PROVIDER_URL, - chainId: constants.StarknetChainId[NETWORK_NAME], + chainId: CHAIN_ID, }); export const providers = (_chain: Chain) => provider; diff --git a/JoyboyCommunity/src/store/auth.ts b/JoyboyCommunity/src/store/auth.ts index 1dffae51..16f5e2a4 100644 --- a/JoyboyCommunity/src/store/auth.ts +++ b/JoyboyCommunity/src/store/auth.ts @@ -3,8 +3,8 @@ import {createStore} from 'zustand'; import createBoundedUseStore from './createBoundedUseStore'; type State = { - publicKey: string | null; - privateKey: string | null; + publicKey: string; + privateKey: string; }; type Action = { @@ -12,8 +12,10 @@ type Action = { }; export const authStore = createStore((set, get) => ({ - publicKey: null, - privateKey: null, + // publicKey and privateKey are set to undefined but we know they are strings + // so we can cast them as strings without hassle in the app + publicKey: undefined as unknown as string, + privateKey: undefined as unknown as string, setAuth: (publicKey, privateKey) => { set({publicKey, privateKey}); diff --git a/JoyboyCommunity/src/styles/Colors.tsx b/JoyboyCommunity/src/styles/Colors.tsx index 6b9bd739..81181fda 100644 --- a/JoyboyCommunity/src/styles/Colors.tsx +++ b/JoyboyCommunity/src/styles/Colors.tsx @@ -27,6 +27,7 @@ export const LightTheme = { surface: '#FFFFFF', elevated: '#FFFFFF', overlay: 'rgba(0, 0, 0, 0.5)', + shadow: 'rgba(13, 13, 29, 0.2)', text: '#14142C', textSecondary: '#6B6B8C', @@ -74,6 +75,7 @@ export const DarkTheme = { surface: '#FFFFFF', elevated: '#FFFFFF', overlay: 'rgba(0, 0, 0, 0.5)', + shadow: 'rgba(13, 13, 29, 0.2)', text: '#14142C', textSecondary: '#6B6B8C', diff --git a/JoyboyCommunity/src/utils/events.ts b/JoyboyCommunity/src/utils/events.ts index 56d8555b..90501005 100644 --- a/JoyboyCommunity/src/utils/events.ts +++ b/JoyboyCommunity/src/utils/events.ts @@ -1,5 +1,6 @@ -import {constants, getChecksumAddress} from 'starknet'; +import {getChecksumAddress} from 'starknet'; +import {CHAIN_ID} from '../constants/env'; import {EventKey} from '../constants/misc'; import {TOKEN_ADDRESSES} from '../constants/tokens'; @@ -12,11 +13,12 @@ export type ContractEvent = { transaction_hash: string; }; -export const parseDepositEvents = (event: ContractEvent, chainId: constants.StarknetChainId) => { +export const parseDepositEvent = (event: ContractEvent) => { if (event.keys[0] === EventKey.DepositEvent) { return { + event, sender: event.keys[2], - token: TOKEN_ADDRESSES[chainId][getChecksumAddress(event.data[2])], + token: TOKEN_ADDRESSES[CHAIN_ID][getChecksumAddress(event.data[2])], amount: event.data[0], depositId: Number(event.keys[1]), }; @@ -24,11 +26,27 @@ export const parseDepositEvents = (event: ContractEvent, chainId: constants.Star if (event.keys[0] === EventKey.TransferEvent) { return { + event, sender: event.keys[1], - token: TOKEN_ADDRESSES[chainId][getChecksumAddress(event.data[2])], + token: TOKEN_ADDRESSES[CHAIN_ID][getChecksumAddress(event.data[2])], amount: event.data[0], }; } return undefined; }; + +export const parseClaimEvent = (event: ContractEvent) => { + if (event.keys[0] === EventKey.ClaimEvent) { + return { + event, + sender: event.keys[2], + token: TOKEN_ADDRESSES[CHAIN_ID][getChecksumAddress(event.data[1])], + amount: event.data[0], + starknetRecipient: event.keys[5], + depositId: Number(event.keys[1]), + }; + } + + return undefined; +}; diff --git a/JoyboyCommunity/src/utils/format.ts b/JoyboyCommunity/src/utils/format.ts deleted file mode 100644 index fc37dd7d..00000000 --- a/JoyboyCommunity/src/utils/format.ts +++ /dev/null @@ -1,63 +0,0 @@ -// Convert Uint8Array to Base64 string -export const uint8ArrayToBase64 = (uint8Array: Uint8Array) => { - return btoa(String.fromCharCode.apply(null, Array.from(uint8Array))); -}; - -export const uint8ArrayToString = (uint8Array: Uint8Array): string => { - try { - let utf8String = ''; - for (let i = 0; i < uint8Array.length; i++) { - utf8String += String.fromCharCode(uint8Array[i]); - } - return decodeURIComponent(escape(utf8String)); - } catch (e) { - console.log('Error uint8ArrayToString', e); - return undefined; - } -}; - -// Convert Base64 string to Uint8Array -export const base64ToUint8Array = (base64: string) => { - try { - return new Uint8Array( - atob(base64) - .split('') - .map((char) => char.charCodeAt(0)), - ); - } catch (e) { - console.log('Error base64ToUint8Array', e); - } -}; -// Convert UTF-8 string to Uint8Array - -export const utf8StringToUint8Array = (utf8String: string, length = 32): Uint8Array => { - try { - const encoder = new TextEncoder(); - let encodedArray = encoder.encode(utf8String); - - if (encodedArray.length > length) { - // Truncate the array if it's longer than the desired length - encodedArray = encodedArray.slice(0, length); - } else { - // Pad the array with zeros if it's shorter than the desired length - const padding = new Uint8Array(length - encodedArray.length); - encodedArray = new Uint8Array([...encodedArray, ...padding]); - } - - const keypair = encodedArray; - return keypair; - } catch (e) { - console.log('Error utf8StringToUint8Array', e); - return undefined; - } -}; - -export const uint8ArrayToHex = (uint8Array: Uint8Array): string | undefined => { - try { - return Array.from(uint8Array) - .map((byte) => byte.toString(16).padStart(2, '0')) - .join(''); - } catch (e) { - return undefined; - } -}; diff --git a/JoyboyCommunity/tsconfig.json b/JoyboyCommunity/tsconfig.json index 12f15398..e30ce24e 100644 --- a/JoyboyCommunity/tsconfig.json +++ b/JoyboyCommunity/tsconfig.json @@ -1,5 +1,30 @@ -{ - "extends": "expo/tsconfig.base", - "compilerOptions": {}, - "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"] -} +{ + "extends": "expo/tsconfig.base", + "compilerOptions": { + "target": "ESNext", + "lib": ["dom", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "strict": true, + "alwaysStrict": true, + "strictNullChecks": true, + "noUnusedLocals": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitThis": true, + "noImplicitReturns": true, + "useUnknownInCatchVariables": false, + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "jsx": "react-native", + "module": "ES6" + }, + "exclude": ["node_modules", "dist", "babel.config.js", "metro.config.js", "jest.config.js"], + "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"] +} diff --git a/JoyboyCommunity/yarn.lock b/JoyboyCommunity/yarn.lock index 3cd5d096..208bfb02 100644 --- a/JoyboyCommunity/yarn.lock +++ b/JoyboyCommunity/yarn.lock @@ -56,6 +56,17 @@ json5 "^2.2.3" semver "^6.3.1" +"@babel/generator@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.0.tgz#eaf3821fa0301d9d4aef88e63d4bcc19b73ba16c" + integrity sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg== + dependencies: + "@babel/types" "^7.2.0" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + "@babel/generator@^7.20.0", "@babel/generator@^7.20.5", "@babel/generator@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.7.tgz#1654d01de20ad66b4b4d99c135471bc654c55e6d" @@ -808,7 +819,7 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.20.0", "@babel/types@^7.24.7": +"@babel/types@^7.19.0", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.7.tgz#6027fe12bc1aa724cd32ab113fb7f1988f1f66f2" integrity sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q== @@ -930,10 +941,10 @@ mv "~2" safe-json-stringify "~1" -"@expo/cli@0.18.19": - version "0.18.19" - resolved "https://registry.yarnpkg.com/@expo/cli/-/cli-0.18.19.tgz#ae342bae82cd2c78b24986522aa7d1e1b4c51154" - integrity sha512-8Rj18cTofpLl+7D++auMVS71KungldHbrArR44fpE8loMVAvYZA+U932lmd0K2lOYBASPhm7SVP9wzls//ESFQ== +"@expo/cli@0.18.21": + version "0.18.21" + resolved "https://registry.yarnpkg.com/@expo/cli/-/cli-0.18.21.tgz#a44fb04bbac42141bc101b6acb91eb7b237e5722" + integrity sha512-t8sFUGXRM/vafILp98H/MvIgJ5c7OG+d780Zastpzn0zfakaVDvXyw9tXskwAYi9YHJpG8/cfvght1c5fBDBoA== dependencies: "@babel/runtime" "^7.20.0" "@expo/code-signing-certificates" "0.0.5" @@ -1021,7 +1032,28 @@ node-forge "^1.2.1" nullthrows "^1.1.1" -"@expo/config-plugins@8.0.5", "@expo/config-plugins@~8.0.0", "@expo/config-plugins@~8.0.0-beta.0": +"@expo/config-plugins@8.0.6": + version "8.0.6" + resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-8.0.6.tgz#ab87eb4d2a6d1b40e95f74ed9ff3d849561f3f88" + integrity sha512-Vmn/BSg/hBmliU/Bl+G4sExDoWd4iHXQG7ITUNR5Uar7uLko1A5vdVV+EOEUFA0f8jEZMHG3uZJUoXmr4LPaxA== + dependencies: + "@expo/config-types" "^51.0.0-unreleased" + "@expo/json-file" "~8.3.0" + "@expo/plist" "^0.1.0" + "@expo/sdk-runtime-versions" "^1.0.0" + chalk "^4.1.2" + debug "^4.3.1" + find-up "~5.0.0" + getenv "^1.0.0" + glob "7.1.6" + 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@~8.0.0", "@expo/config-plugins@~8.0.0-beta.0": version "8.0.5" resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-8.0.5.tgz#fc165e59786e399dd4694aae2a7cd716ab8a496c" integrity sha512-VGseKX1dYvaf2qHUDGzIQwSOJrO5fomH0gE5cKSQyi6wn+Q6rcV2Dj2E5aga+9aKNPL6FxZ0dqRFC3t2sbhaSA== @@ -1136,7 +1168,31 @@ json5 "^2.2.2" write-file-atomic "^2.3.0" -"@expo/metro-config@0.18.7", "@expo/metro-config@~0.18.6": +"@expo/metro-config@0.18.8": + version "0.18.8" + resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.18.8.tgz#2902bfdb864876da3cf5b1822a554bbb011e4a77" + integrity sha512-YGpTlVc1/6EPzPbt0LZt92Bwrpjngulup6uHSTRbwn/heMPfFaVv1Y4VE3GAUkx7/Qwu+dTVIV0Kys4pLOAIiw== + dependencies: + "@babel/core" "^7.20.0" + "@babel/generator" "^7.20.5" + "@babel/parser" "^7.20.0" + "@babel/types" "^7.20.0" + "@expo/config" "~9.0.0-beta.0" + "@expo/env" "~0.3.0" + "@expo/json-file" "~8.3.0" + "@expo/spawn-async" "^1.7.2" + chalk "^4.1.0" + debug "^4.3.2" + find-yarn-workspace-root "~2.0.0" + fs-extra "^9.1.0" + getenv "^1.0.0" + glob "^7.2.3" + jsc-safe-url "^0.2.4" + lightningcss "~1.19.0" + postcss "~8.4.32" + resolve-from "^5.0.0" + +"@expo/metro-config@~0.18.6": version "0.18.7" resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.18.7.tgz#f64a0299761a2f90bf2686b59306847620f91e92" integrity sha512-MzAyFP0fvoyj9IUc6SPnpy6/HLT23j/p5J+yWjGug2ddOpSuKNDHOOqlwWZbJp5KfZCEIVWNHeUoE+TaC/yhaQ== @@ -1348,6 +1404,15 @@ dependencies: "@sinclair/typebox" "^0.27.8" +"@jest/types@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" + integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^13.0.0" + "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -1624,45 +1689,45 @@ dependencies: merge-options "^3.0.4" -"@react-native-community/cli-clean@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-13.6.6.tgz#87c7ad8746c38dab0fe7b3c6ff89d44351d5d943" - integrity sha512-cBwJTwl0NyeA4nyMxbhkWZhxtILYkbU3TW3k8AXLg+iGphe0zikYMGB3T+haTvTc6alTyEFwPbimk9bGIqkjAQ== +"@react-native-community/cli-clean@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-13.6.9.tgz#b6754f39c2b877c9d730feb848945150e1d52209" + integrity sha512-7Dj5+4p9JggxuVNOjPbduZBAP1SUgNhLKVw5noBUzT/3ZpUZkDM+RCSwyoyg8xKWoE4OrdUAXwAFlMcFDPKykA== dependencies: - "@react-native-community/cli-tools" "13.6.6" + "@react-native-community/cli-tools" "13.6.9" chalk "^4.1.2" execa "^5.0.0" fast-glob "^3.3.2" -"@react-native-community/cli-config@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-13.6.6.tgz#69f590694b3a079c74f781baab3b762db74f5dbd" - integrity sha512-mbG425zCKr8JZhv/j11382arezwS/70juWMsn8j2lmrGTrP1cUdW0MF15CCIFtJsqyK3Qs+FTmqttRpq81QfSg== +"@react-native-community/cli-config@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-13.6.9.tgz#d609a64d40a173c89bd7d24e31807bb7dcba69f9" + integrity sha512-rFfVBcNojcMm+KKHE/xqpqXg8HoKl4EC7bFHUrahMJ+y/tZll55+oX/PGG37rzB8QzP2UbMQ19DYQKC1G7kXeg== dependencies: - "@react-native-community/cli-tools" "13.6.6" + "@react-native-community/cli-tools" "13.6.9" chalk "^4.1.2" cosmiconfig "^5.1.0" deepmerge "^4.3.0" fast-glob "^3.3.2" joi "^17.2.1" -"@react-native-community/cli-debugger-ui@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-13.6.6.tgz#ac021ebd795b0fd66fb52a8987d1d41c5a4b8cb3" - integrity sha512-Vv9u6eS4vKSDAvdhA0OiQHoA7y39fiPIgJ6biT32tN4avHDtxlc6TWZGiqv7g98SBvDWvoVAmdPLcRf3kU+c8g== +"@react-native-community/cli-debugger-ui@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-13.6.9.tgz#bc5727c51964206a00d417e5148b46331a81d5a5" + integrity sha512-TkN7IdFmGPPvTpAo3nCAH9uwGCPxWBEAwpqEZDrq0NWllI7Tdie8vDpGdrcuCcKalmhq6OYnkXzeBah7O1Ztpw== dependencies: serve-static "^1.13.1" -"@react-native-community/cli-doctor@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-13.6.6.tgz#ac0febff05601d9b86af3e03460e1a6b0a1d33a5" - integrity sha512-TWZb5g6EmQe2Ua2TEWNmyaEayvlWH4GmdD9ZC+p8EpKFpB1NpDGMK6sXbpb42TDvwZg5s4TDRplK0PBEA/SVDg== +"@react-native-community/cli-doctor@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-13.6.9.tgz#f1d4eeff427ddc8a9d19851042621c10939c35cb" + integrity sha512-5quFaLdWFQB+677GXh5dGU9I5eg2z6Vg4jOX9vKnc9IffwyIFAyJfCZHrxLSRPDGNXD7biDQUdoezXYGwb6P/A== dependencies: - "@react-native-community/cli-config" "13.6.6" - "@react-native-community/cli-platform-android" "13.6.6" - "@react-native-community/cli-platform-apple" "13.6.6" - "@react-native-community/cli-platform-ios" "13.6.6" - "@react-native-community/cli-tools" "13.6.6" + "@react-native-community/cli-config" "13.6.9" + "@react-native-community/cli-platform-android" "13.6.9" + "@react-native-community/cli-platform-apple" "13.6.9" + "@react-native-community/cli-platform-ios" "13.6.9" + "@react-native-community/cli-tools" "13.6.9" chalk "^4.1.2" command-exists "^1.2.8" deepmerge "^4.3.0" @@ -1676,54 +1741,54 @@ wcwidth "^1.0.1" yaml "^2.2.1" -"@react-native-community/cli-hermes@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-13.6.6.tgz#590f55f151fec23b55498228f92d100a0e71d474" - integrity sha512-La5Ie+NGaRl3klei6WxKoOxmCUSGGxpOk6vU5pEGf0/O7ky+Ay0io+zXYUZqlNMi/cGpO7ZUijakBYOB/uyuFg== +"@react-native-community/cli-hermes@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-13.6.9.tgz#88c8dfe936a0d4272efc54429eda9ccc3fca3ad8" + integrity sha512-GvwiwgvFw4Ws+krg2+gYj8sR3g05evmNjAHkKIKMkDTJjZ8EdyxbkifRUs1ZCq3TMZy2oeblZBXCJVOH4W7ZbA== dependencies: - "@react-native-community/cli-platform-android" "13.6.6" - "@react-native-community/cli-tools" "13.6.6" + "@react-native-community/cli-platform-android" "13.6.9" + "@react-native-community/cli-tools" "13.6.9" chalk "^4.1.2" hermes-profile-transformer "^0.0.6" -"@react-native-community/cli-platform-android@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-13.6.6.tgz#9e3863cb092709021f11848890bff0fc16fc1609" - integrity sha512-/tMwkBeNxh84syiSwNlYtmUz/Ppc+HfKtdopL/5RB+fd3SV1/5/NPNjMlyLNgFKnpxvKCInQ7dnl6jGHJjeHjg== +"@react-native-community/cli-platform-android@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-13.6.9.tgz#b175b9b11334fc90da3f395432678bd53c30fae4" + integrity sha512-9KsYGdr08QhdvT3Ht7e8phQB3gDX9Fs427NJe0xnoBh+PDPTI2BD5ks5ttsH8CzEw8/P6H8tJCHq6hf2nxd9cw== dependencies: - "@react-native-community/cli-tools" "13.6.6" + "@react-native-community/cli-tools" "13.6.9" chalk "^4.1.2" execa "^5.0.0" fast-glob "^3.3.2" fast-xml-parser "^4.2.4" logkitty "^0.7.1" -"@react-native-community/cli-platform-apple@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-apple/-/cli-platform-apple-13.6.6.tgz#d445fd6ed02c5ae2f43f9c45501e04fee53a2790" - integrity sha512-bOmSSwoqNNT3AmCRZXEMYKz1Jf1l2F86Nhs7qBcXdY/sGiJ+Flng564LOqvdAlVLTbkgz47KjNKCS2pP4Jg0Mg== +"@react-native-community/cli-platform-apple@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-apple/-/cli-platform-apple-13.6.9.tgz#02fb5dc47d62acd85f4d7a852e93216927a772fa" + integrity sha512-KoeIHfhxMhKXZPXmhQdl6EE+jGKWwoO9jUVWgBvibpVmsNjo7woaG/tfJMEWfWF3najX1EkQAoJWpCDBMYWtlA== dependencies: - "@react-native-community/cli-tools" "13.6.6" + "@react-native-community/cli-tools" "13.6.9" chalk "^4.1.2" execa "^5.0.0" fast-glob "^3.3.2" fast-xml-parser "^4.0.12" ora "^5.4.1" -"@react-native-community/cli-platform-ios@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-13.6.6.tgz#0cd700f36483ca37dda7ec044377f8a926b1df1f" - integrity sha512-vjDnRwhlSN5ryqKTas6/DPkxuouuyFBAqAROH4FR1cspTbn6v78JTZKDmtQy9JMMo7N5vZj1kASU5vbFep9IOQ== +"@react-native-community/cli-platform-ios@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-13.6.9.tgz#f37ceab41c2302e8f0d4bcbd3bf58b3353db4306" + integrity sha512-CiUcHlGs8vE0CAB4oi1f+dzniqfGuhWPNrDvae2nm8dewlahTBwIcK5CawyGezjcJoeQhjBflh9vloska+nlnw== dependencies: - "@react-native-community/cli-platform-apple" "13.6.6" + "@react-native-community/cli-platform-apple" "13.6.9" -"@react-native-community/cli-server-api@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-13.6.6.tgz#467993006ef82361cdf7a9817999d5a09e85ca6a" - integrity sha512-ZtCXxoFlM7oDv3iZ3wsrT3SamhtUJuIkX2WePLPlN5bcbq7zimbPm2lHyicNJtpcGQ5ymsgpUWPCNZsWQhXBqQ== +"@react-native-community/cli-server-api@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-13.6.9.tgz#269e666bc26e9d0b2f42c7f6099559b5f9259e9d" + integrity sha512-W8FSlCPWymO+tlQfM3E0JmM8Oei5HZsIk5S0COOl0MRi8h0NmHI4WSTF2GCfbFZkcr2VI/fRsocoN8Au4EZAug== dependencies: - "@react-native-community/cli-debugger-ui" "13.6.6" - "@react-native-community/cli-tools" "13.6.6" + "@react-native-community/cli-debugger-ui" "13.6.9" + "@react-native-community/cli-tools" "13.6.9" compression "^1.7.1" connect "^3.6.5" errorhandler "^1.5.1" @@ -1732,10 +1797,10 @@ serve-static "^1.13.1" ws "^6.2.2" -"@react-native-community/cli-tools@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-13.6.6.tgz#55c40cbabafbfc56cfb95a4d5fbf73ef60ec3cbc" - integrity sha512-ptOnn4AJczY5njvbdK91k4hcYazDnGtEPrqIwEI+k/CTBHNdb27Rsm2OZ7ye6f7otLBqF8gj/hK6QzJs8CEMgw== +"@react-native-community/cli-tools@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-13.6.9.tgz#2baee279358ba1a863e737b2fa9f45659ad91929" + integrity sha512-OXaSjoN0mZVw3nrAwcY1PC0uMfyTd9fz7Cy06dh+EJc+h0wikABsVRzV8cIOPrVV+PPEEXE0DBrH20T2puZzgQ== dependencies: appdirsjs "^1.2.4" chalk "^4.1.2" @@ -1749,26 +1814,26 @@ shell-quote "^1.7.3" sudo-prompt "^9.0.0" -"@react-native-community/cli-types@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-13.6.6.tgz#b45af119d61888fea1074a7c32ddb093e3f119a9" - integrity sha512-733iaYzlmvNK7XYbnWlMjdE+2k0hlTBJW071af/xb6Bs+hbJqBP9c03FZuYH2hFFwDDntwj05bkri/P7VgSxug== +"@react-native-community/cli-types@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-13.6.9.tgz#08bfb796eacf0daeb31e2de516e81e78a36a1a55" + integrity sha512-RLxDppvRxXfs3hxceW/mShi+6o5yS+kFPnPqZTaMKKR5aSg7LwDpLQW4K2D22irEG8e6RKDkZUeH9aL3vO2O0w== dependencies: joi "^17.2.1" -"@react-native-community/cli@13.6.6": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-13.6.6.tgz#b929c8668e88344c03a46a3e635cb382dba16773" - integrity sha512-IqclB7VQ84ye8Fcs89HOpOscY4284VZg2pojHNl8H0Lzd4DadXJWQoxC7zWm8v2f8eyeX2kdhxp2ETD5tceIgA== - dependencies: - "@react-native-community/cli-clean" "13.6.6" - "@react-native-community/cli-config" "13.6.6" - "@react-native-community/cli-debugger-ui" "13.6.6" - "@react-native-community/cli-doctor" "13.6.6" - "@react-native-community/cli-hermes" "13.6.6" - "@react-native-community/cli-server-api" "13.6.6" - "@react-native-community/cli-tools" "13.6.6" - "@react-native-community/cli-types" "13.6.6" +"@react-native-community/cli@13.6.9": + version "13.6.9" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-13.6.9.tgz#ba6360b94e0aba9c4001bda256cf7e57e2ecb02c" + integrity sha512-hFJL4cgLPxncJJd/epQ4dHnMg5Jy/7Q56jFvA3MHViuKpzzfTCJCB+pGY54maZbtym53UJON9WTGpM3S81UfjQ== + dependencies: + "@react-native-community/cli-clean" "13.6.9" + "@react-native-community/cli-config" "13.6.9" + "@react-native-community/cli-debugger-ui" "13.6.9" + "@react-native-community/cli-doctor" "13.6.9" + "@react-native-community/cli-hermes" "13.6.9" + "@react-native-community/cli-server-api" "13.6.9" + "@react-native-community/cli-tools" "13.6.9" + "@react-native-community/cli-types" "13.6.9" chalk "^4.1.2" commander "^9.4.1" deepmerge "^4.3.0" @@ -1779,27 +1844,20 @@ prompts "^2.4.2" semver "^7.5.2" -"@react-native-community/netinfo@^11.3.2": - version "11.3.2" - resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-11.3.2.tgz#e63201d0b87ad42d086d1003be48ae7b327f0594" - integrity sha512-YsaS3Dutnzqd1BEoeC+DEcuNJedYRkN6Ef3kftT5Sm8ExnCF94C/nl4laNxuvFli3+Jz8Df3jO25Jn8A9S0h4w== - -"@react-native-picker/picker@^2.7.7": - version "2.7.7" - resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.7.7.tgz#6e19c3a72a482be015f5194794e6c14efe8762e8" - integrity sha512-CTHthVmx8ujlH/u5AnxLQfsheh/DoEbo+Kbx0HGTlbKVLC1eZ4Kr9jXIIUcwB7JEgOXifdZIPQCsoTc/7GQ0ag== +"@react-native-community/netinfo@11.3.1": + version "11.3.1" + resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-11.3.1.tgz#4539371a2f4bd402d932031be82c2449ed63a1a5" + integrity sha512-UBnJxyV0b7i9Moa97Av+HKho1ByzX0DtbJXzUQS5E3xhQs6P2D/Os0iw3ouy7joY1TVd6uIhplPbr7l1SJNaNQ== -"@react-native/assets-registry@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.74.83.tgz#c1815dc10f9e1075e0d03b4c8a9619145969522e" - integrity sha512-2vkLMVnp+YTZYTNSDIBZojSsjz8sl5PscP3j4GcV6idD8V978SZfwFlk8K0ti0BzRs11mzL0Pj17km597S/eTQ== +"@react-native-picker/picker@2.7.5": + version "2.7.5" + resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.7.5.tgz#e43fcd65f260fa4f23e974ccb9fb7c1f7a9ff94a" + integrity sha512-vhMaOLkXSUb+YKVbukMJToU4g+89VMhBG2U9+cLYF8X8HtFRidrHjohGqT8/OyesDuKIXeLIP+UFYI9Q9CRA9Q== -"@react-native/babel-plugin-codegen@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.83.tgz#971f9cfec980dd05598d81964c05a26c6166f9fb" - integrity sha512-+S0st3t4Ro00bi9gjT1jnK8qTFOU+CwmziA7U9odKyWrCoRJrgmrvogq/Dr1YXlpFxexiGIupGut1VHxr+fxJA== - dependencies: - "@react-native/codegen" "0.74.83" +"@react-native/assets-registry@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.74.85.tgz#ae903c0c25f4d6a751d53d63245d5612c81edd98" + integrity sha512-59YmIQxfGDw4aP9S/nAM+sjSFdW8fUP6fsqczCcXgL2YVEjyER9XCaUT0J1K+PdHep8pi05KUgIKUds8P3jbmA== "@react-native/babel-plugin-codegen@0.74.84": version "0.74.84" @@ -1808,10 +1866,17 @@ dependencies: "@react-native/codegen" "0.74.84" -"@react-native/babel-preset@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.74.83.tgz#9828457779b4ce0219078652327ce3203115cdf9" - integrity sha512-KJuu3XyVh3qgyUer+rEqh9a/JoUxsDOzkJNfRpDyXiAyjDRoVch60X/Xa/NcEQ93iCVHAWs0yQ+XGNGIBCYE6g== +"@react-native/babel-plugin-codegen@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.85.tgz#067224bf5099ee2679babd700c7115822a747004" + integrity sha512-48TSDclRB5OMXiImiJkLxyCfRyLsqkCgI8buugCZzvXcYslfV7gCvcyFyQldtcOmerV+CK4RAj7QS4hmB5Mr8Q== + dependencies: + "@react-native/codegen" "0.74.85" + +"@react-native/babel-preset@0.74.84": + version "0.74.84" + resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.74.84.tgz#703ebfc810d82c9f51f033352abd5f9fa70d492b" + integrity sha512-WUfu6Y4aGuVdocQZvx33BJiQWFH6kRCHYbZfBn2psgFrSRLgQWEQrDCxqPFObNAVSayM0rNhp2FvI5K/Eyeqlg== dependencies: "@babel/core" "^7.20.0" "@babel/plugin-proposal-async-generator-functions" "^7.0.0" @@ -1853,14 +1918,14 @@ "@babel/plugin-transform-typescript" "^7.5.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" - "@react-native/babel-plugin-codegen" "0.74.83" + "@react-native/babel-plugin-codegen" "0.74.84" babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.14.0" -"@react-native/babel-preset@0.74.84": - version "0.74.84" - resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.74.84.tgz#703ebfc810d82c9f51f033352abd5f9fa70d492b" - integrity sha512-WUfu6Y4aGuVdocQZvx33BJiQWFH6kRCHYbZfBn2psgFrSRLgQWEQrDCxqPFObNAVSayM0rNhp2FvI5K/Eyeqlg== +"@react-native/babel-preset@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.74.85.tgz#3ce6ca77a318dec226fd9e3fff9c2ef7b0aa66e3" + integrity sha512-yMHUlN8INbK5BBwiBuQMftdWkpm1IgCsoJTKcGD2OpSgZhwwm8RUSvGhdRMzB2w7bsqqBmaEMleGtW6aCR7B9w== dependencies: "@babel/core" "^7.20.0" "@babel/plugin-proposal-async-generator-functions" "^7.0.0" @@ -1902,14 +1967,14 @@ "@babel/plugin-transform-typescript" "^7.5.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" - "@react-native/babel-plugin-codegen" "0.74.84" + "@react-native/babel-plugin-codegen" "0.74.85" babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.14.0" -"@react-native/codegen@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.74.83.tgz#7c56a82fe7603f0867f0d80ff29db3757b71be55" - integrity sha512-GgvgHS3Aa2J8/mp1uC/zU8HuTh8ZT5jz7a4mVMWPw7+rGyv70Ba8uOVBq6UH2Q08o617IATYc+0HfyzAfm4n0w== +"@react-native/codegen@0.74.84": + version "0.74.84" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.74.84.tgz#d3425a510b7da558ef5088d9b0aa5e0b1c05c783" + integrity sha512-0hXlnu9i0o8v+gXKQi+x6T471L85kCDwW4WrJiYAeOheWrQdNNW6rC3g8+LL7HXAf7QcHGU/8/d57iYfdVK2BQ== dependencies: "@babel/parser" "^7.20.0" glob "^7.1.1" @@ -1919,10 +1984,10 @@ mkdirp "^0.5.1" nullthrows "^1.1.1" -"@react-native/codegen@0.74.84": - version "0.74.84" - resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.74.84.tgz#d3425a510b7da558ef5088d9b0aa5e0b1c05c783" - integrity sha512-0hXlnu9i0o8v+gXKQi+x6T471L85kCDwW4WrJiYAeOheWrQdNNW6rC3g8+LL7HXAf7QcHGU/8/d57iYfdVK2BQ== +"@react-native/codegen@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.74.85.tgz#568464071c0b9be741da1a1ab43b1df88180ca5d" + integrity sha512-N7QwoS4Hq/uQmoH83Ewedy6D0M7xbQsOU3OMcQf0eY3ltQ7S2hd9/R4UTalQWRn1OUJfXR6OG12QJ4FStKgV6Q== dependencies: "@babel/parser" "^7.20.0" glob "^7.1.1" @@ -1932,15 +1997,15 @@ mkdirp "^0.5.1" nullthrows "^1.1.1" -"@react-native/community-cli-plugin@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.83.tgz#58808a58a5288895627548338731e72ebb5b507c" - integrity sha512-7GAFjFOg1mFSj8bnFNQS4u8u7+QtrEeflUIDVZGEfBZQ3wMNI5ycBzbBGycsZYiq00Xvoc6eKFC7kvIaqeJpUQ== +"@react-native/community-cli-plugin@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.85.tgz#5bf95599166fd2b8bf10612250006e282053f6c4" + integrity sha512-ODzND33eA2owAY3g9jgCdqB+BjAh8qJ7dvmSotXgrgDYr3MJMpd8gvHTIPe2fg4Kab+wk8uipRhrE0i0RYMwtQ== dependencies: - "@react-native-community/cli-server-api" "13.6.6" - "@react-native-community/cli-tools" "13.6.6" - "@react-native/dev-middleware" "0.74.83" - "@react-native/metro-babel-transformer" "0.74.83" + "@react-native-community/cli-server-api" "13.6.9" + "@react-native-community/cli-tools" "13.6.9" + "@react-native/dev-middleware" "0.74.85" + "@react-native/metro-babel-transformer" "0.74.85" chalk "^4.0.0" execa "^5.1.1" metro "^0.80.3" @@ -1950,23 +2015,23 @@ querystring "^0.2.1" readline "^1.3.0" -"@react-native/debugger-frontend@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.74.83.tgz#48050afa4e086438073b95f041c0cc84fe3f20de" - integrity sha512-RGQlVUegBRxAUF9c1ss1ssaHZh6CO+7awgtI9sDeU0PzDZY/40ImoPD5m0o0SI6nXoVzbPtcMGzU+VO590pRfA== - "@react-native/debugger-frontend@0.74.84": version "0.74.84" resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.74.84.tgz#0bde122a988916b6a50f05a7c3ab1c5db029b149" integrity sha512-YUEA03UNFbiYzHpYxlcS2D9+3eNT5YLGkl5yRg3nOSN6KbCc/OttGnNZme+tuSOJwjMN/vcvtDKYkTqjJw8U0A== -"@react-native/dev-middleware@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.74.83.tgz#9d09cfdb763e8ef81c003b0f99ae4ed1a3539639" - integrity sha512-UH8iriqnf7N4Hpi20D7M2FdvSANwTVStwFCSD7VMU9agJX88Yk0D1T6Meh2RMhUu4kY2bv8sTkNRm7LmxvZqgA== +"@react-native/debugger-frontend@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.74.85.tgz#a7af94a7b81cb59f241fd1771d1b083445329700" + integrity sha512-gUIhhpsYLUTYWlWw4vGztyHaX/kNlgVspSvKe2XaPA7o3jYKUoNLc3Ov7u70u/MBWfKdcEffWq44eSe3j3s5JQ== + +"@react-native/dev-middleware@0.74.84": + version "0.74.84" + resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.74.84.tgz#19ccfece791742f83f4c0a22a8c14593a45562a2" + integrity sha512-veYw/WmyrAOQHUiIeULzn2duJQnXDPiKq2jZ/lcmDo6jsLirpp+Q73lx09TYgy/oVoPRuV0nfmU3x9B6EV/7qQ== dependencies: "@isaacs/ttlcache" "^1.4.1" - "@react-native/debugger-frontend" "0.74.83" + "@react-native/debugger-frontend" "0.74.84" "@rnx-kit/chromium-edge-launcher" "^1.0.0" chrome-launcher "^0.15.2" connect "^3.6.5" @@ -1979,13 +2044,13 @@ temp-dir "^2.0.0" ws "^6.2.2" -"@react-native/dev-middleware@0.74.84": - version "0.74.84" - resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.74.84.tgz#19ccfece791742f83f4c0a22a8c14593a45562a2" - integrity sha512-veYw/WmyrAOQHUiIeULzn2duJQnXDPiKq2jZ/lcmDo6jsLirpp+Q73lx09TYgy/oVoPRuV0nfmU3x9B6EV/7qQ== +"@react-native/dev-middleware@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.74.85.tgz#eca35aceb882b1111385f7c20f1aad7a33a2734e" + integrity sha512-BRmgCK5vnMmHaKRO+h8PKJmHHH3E6JFuerrcfE3wG2eZ1bcSr+QTu8DAlpxsDWvJvHpCi8tRJGauxd+Ssj/c7w== dependencies: "@isaacs/ttlcache" "^1.4.1" - "@react-native/debugger-frontend" "0.74.84" + "@react-native/debugger-frontend" "0.74.85" "@rnx-kit/chromium-edge-launcher" "^1.0.0" chrome-launcher "^0.15.2" connect "^3.6.5" @@ -1998,40 +2063,40 @@ temp-dir "^2.0.0" ws "^6.2.2" -"@react-native/gradle-plugin@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.74.83.tgz#4ac60a6d6295d5b920173cbf184ee32e53690810" - integrity sha512-Pw2BWVyOHoBuJVKxGVYF6/GSZRf6+v1Ygc+ULGz5t20N8qzRWPa2fRZWqoxsN7TkNLPsECYY8gooOl7okOcPAQ== +"@react-native/gradle-plugin@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.74.85.tgz#7c7d16655a4c15da87402ae3f7d6566466aea723" + integrity sha512-1VQSLukJzaVMn1MYcs8Weo1nUW8xCas2XU1KuoV7OJPk6xPnEBFJmapmEGP5mWeEy7kcTXJmddEgy1wwW0tcig== -"@react-native/js-polyfills@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.74.83.tgz#0e189ce3ab0efecd00223f3bfc53663ce08ba013" - integrity sha512-/t74n8r6wFhw4JEoOj3bN71N1NDLqaawB75uKAsSjeCwIR9AfCxlzZG0etsXtOexkY9KMeZIQ7YwRPqUdNXuqw== +"@react-native/js-polyfills@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.74.85.tgz#1abfeeaec5ff24b6a1b3e2296e760359fce47739" + integrity sha512-gp4Rg9le3lVZeW7Cie6qLfekvRKZuhJ3LKgi1SFB4N154z1wIclypAJXVXgWBsy8JKJfTwRI+sffC4qZDlvzrg== -"@react-native/metro-babel-transformer@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.83.tgz#ba87c3cf041f4c0d2b991231af1a6b4a216e9b5d" - integrity sha512-hGdx5N8diu8y+GW/ED39vTZa9Jx1di2ZZ0aapbhH4egN1agIAusj5jXTccfNBwwWF93aJ5oVbRzfteZgjbutKg== +"@react-native/metro-babel-transformer@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.85.tgz#d530d9a6bd319ece226a2d6aaa00b464a1928089" + integrity sha512-JIrXqEwhTvWPtGArgMptIPGstMdXQIkwSjKVYt+7VC4a9Pw1GurIWanIJheEW6ZuCVvTc0VZkwglFz9JVjzDjA== dependencies: "@babel/core" "^7.20.0" - "@react-native/babel-preset" "0.74.83" + "@react-native/babel-preset" "0.74.85" hermes-parser "0.19.1" nullthrows "^1.1.1" -"@react-native/normalize-colors@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.74.83.tgz#86ef925bacf219d74df115bcfb615f62d8142e85" - integrity sha512-jhCY95gRDE44qYawWVvhTjTplW1g+JtKTKM3f8xYT1dJtJ8QWv+gqEtKcfmOHfDkSDaMKG0AGBaDTSK8GXLH8Q== - "@react-native/normalize-colors@0.74.84", "@react-native/normalize-colors@^0.74.1": version "0.74.84" resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.74.84.tgz#4764d59775c17a6ed193509cb01ae2f42dd5c045" integrity sha512-Y5W6x8cC5RuakUcTVUFNAIhUZ/tYpuqHZlRBoAuakrTwVuoNHXfQki8lj1KsYU7rW6e3VWgdEx33AfOQpdNp6A== -"@react-native/virtualized-lists@0.74.83": - version "0.74.83" - resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.74.83.tgz#5595d6aefd9679d1295c56a1d1653b1fb261bd62" - integrity sha512-rmaLeE34rj7py4FxTod7iMTC7BAsm+HrGA8WxYmEJeyTV7WSaxAkosKoYBz8038mOiwnG9VwA/7FrB6bEQvn1A== +"@react-native/normalize-colors@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz#62bcb9ab1b10b822ca0278fdfdf23d3b18e125da" + integrity sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw== + +"@react-native/virtualized-lists@0.74.85": + version "0.74.85" + resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.74.85.tgz#a6178c7168953807b3b610c9f8d208a6f758407d" + integrity sha512-jx2Zw0qlZteoQ+0KxRc7s4drsljLBEP534FaNZ950e9+CN9nVkLsV6rigcTjDR8wjKMSBWhKf0C0C3egYz7Ehg== dependencies: invariant "^2.2.4" nullthrows "^1.1.1" @@ -2405,6 +2470,14 @@ dependencies: "@types/istanbul-lib-coverage" "*" +"@types/istanbul-reports@^1.1.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2" + integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw== + dependencies: + "@types/istanbul-lib-coverage" "*" + "@types/istanbul-lib-report" "*" + "@types/istanbul-reports@^3.0.0": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" @@ -2486,6 +2559,13 @@ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== +"@types/yargs@^13.0.0": + version "13.0.12" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.12.tgz#d895a88c703b78af0465a9de88aa92c61430b092" + integrity sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ== + dependencies: + "@types/yargs-parser" "*" + "@types/yargs@^15.0.0": version "15.0.19" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.19.tgz#328fb89e46109ecbdb70c295d96ff2f46dfd01b9" @@ -2953,7 +3033,7 @@ ansi-fragments@^0.2.1: slice-ansi "^2.0.0" strip-ansi "^5.0.0" -ansi-regex@^4.1.0: +ansi-regex@^4.0.0, ansi-regex@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== @@ -3223,6 +3303,19 @@ babel-plugin-polyfill-regenerator@^0.6.1: dependencies: "@babel/helper-define-polyfill-provider" "^0.6.2" +babel-plugin-react-compiler@^0.0.0-experimental-592953e-20240517: + version "0.0.0-experimental-696af53-20240625" + resolved "https://registry.yarnpkg.com/babel-plugin-react-compiler/-/babel-plugin-react-compiler-0.0.0-experimental-696af53-20240625.tgz#ebf18487ce3fa795a7af78443be0a9f274df8df1" + integrity sha512-OUDKms8qmcm5bX0D+sJWC1YcKcd7AZ2aJ7eY6gkR+Xr7PDfkXLbqAld4Qs9B0ntjVbUMEtW/PjlQrxDtY4raHg== + dependencies: + "@babel/generator" "7.2.0" + "@babel/types" "^7.19.0" + chalk "4" + invariant "^2.2.4" + pretty-format "^24" + zod "^3.22.4" + zod-validation-error "^2.1.0" + babel-plugin-react-native-web@~0.19.10: version "0.19.12" resolved "https://registry.yarnpkg.com/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.19.12.tgz#90481ee72b515020b06cb644abe1e8a16590bd86" @@ -3235,10 +3328,10 @@ babel-plugin-transform-flow-enums@^0.0.2: dependencies: "@babel/plugin-syntax-flow" "^7.12.1" -babel-preset-expo@~11.0.10: - version "11.0.10" - resolved "https://registry.yarnpkg.com/babel-preset-expo/-/babel-preset-expo-11.0.10.tgz#408ea00f5336f079987146e1a3d9048facb47ce5" - integrity sha512-YBg40Om31gw9IPlRw5v8elzgtPUtNEh4GSibBi5MsmmYddGg4VPjWtCZIFJChN543qRmbGb/fa/kejvLX567hQ== +babel-preset-expo@~11.0.11: + version "11.0.11" + resolved "https://registry.yarnpkg.com/babel-preset-expo/-/babel-preset-expo-11.0.11.tgz#bf06b8ffd16e1904a1a64ecf08ef965b41c85fcb" + integrity sha512-5AM8FE6mH4IKda08brCzZs9uJU+1K2L/F+7dxWZCprxIlpvNOexqb9TeO/l8m8z1511jmuiAfML6at+46ls+tg== dependencies: "@babel/plugin-proposal-decorators" "^7.12.9" "@babel/plugin-transform-export-namespace-from" "^7.22.11" @@ -3247,6 +3340,7 @@ babel-preset-expo@~11.0.10: "@babel/preset-react" "^7.22.15" "@babel/preset-typescript" "^7.23.0" "@react-native/babel-preset" "0.74.84" + babel-plugin-react-compiler "^0.0.0-experimental-592953e-20240517" babel-plugin-react-native-web "~0.19.10" react-refresh "^0.14.2" @@ -3505,6 +3599,14 @@ cardinal@^2.1.1: ansicolors "~0.3.2" redeyed "~2.1.0" +chalk@4, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^2.0.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -3514,14 +3616,6 @@ chalk@^2.0.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - charenc@0.0.2, charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" @@ -4811,10 +4905,10 @@ expo-application@^5.9.1: resolved "https://registry.yarnpkg.com/expo-application/-/expo-application-5.9.1.tgz#a12e0cf2741b6f084cc49cd0121ad0a70c770459" integrity sha512-uAfLBNZNahnDZLRU41ZFmNSKtetHUT9Ua557/q189ua0AWV7pQjoVAx49E4953feuvqc9swtU3ScZ/hN1XO/FQ== -expo-asset@~10.0.9: - version "10.0.9" - resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-10.0.9.tgz#cf765b785f3d37b905520c0903172781142f8cbe" - integrity sha512-KX7LPtVf9eeMidUvYZafXZldrVdzfjZNKKFAjFvDy2twg7sTa2R0L4VdCXp32eGLWZyk+i/rpOUSbyD1YFyJnA== +expo-asset@~10.0.10: + version "10.0.10" + resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-10.0.10.tgz#9e6e02c1a6ec3d19b50d5e615e4dd8e5cc30e857" + integrity sha512-0qoTIihB79k+wGus9wy0JMKq7DdenziVx3iUkGvMAy2azscSgWH6bd2gJ9CGnhC6JRd3qTMFBL0ou/fx7WZl7A== dependencies: expo-constants "~16.0.0" invariant "^2.2.4" @@ -4857,10 +4951,10 @@ expo-image-loader@~4.7.0: resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-4.7.0.tgz#d403106822de80bda12d644c82b7a3b7983c0f0b" integrity sha512-cx+MxxsAMGl9AiWnQUzrkJMJH4eNOGlu7XkLGnAXSJrRoIiciGaKqzeaD326IyCTV+Z1fXvIliSgNW+DscvD8g== -expo-image-picker@~15.0.5: - version "15.0.5" - resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-15.0.5.tgz#8a3d4c3ecdb5bcf58f09e024597dd69edf7baa9c" - integrity sha512-Qqp16udsadx/YpNcNaWzfbmO0tbMxyX9bS1aFiDVC+Zffh8LY8S4HJJcnWqSC2TeuAl+9SxUwTloJagvPeMBBw== +expo-image-picker@~15.0.7: + version "15.0.7" + resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-15.0.7.tgz#eb25abfdb03cb940f0418add3d9814439526b025" + integrity sha512-u8qiPZNfDb+ap6PJ8pq2iTO7JKX+ikAUQ0K0c7gXGliKLxoXgDdDmXxz9/6QdICTshJBJlBvI0MwY5NWu7A/uw== dependencies: expo-image-loader "~4.7.0" @@ -4888,17 +4982,17 @@ expo-modules-autolinking@1.11.1: find-up "^5.0.0" fs-extra "^9.1.0" -expo-modules-core@1.12.15: - version "1.12.15" - resolved "https://registry.yarnpkg.com/expo-modules-core/-/expo-modules-core-1.12.15.tgz#62cd2aa46762f29c4c2271a1dfee5f8e3f651130" - integrity sha512-VjDPIgUyhCZzf692NF4p2iFTsKAQMcU3jc0pg33eNvN/kdrJqkeucqCDuuwoNxg0vIBKtoqAJDuPnWiemldsTg== +expo-modules-core@1.12.18: + version "1.12.18" + resolved "https://registry.yarnpkg.com/expo-modules-core/-/expo-modules-core-1.12.18.tgz#fd086c3177b42df979db912f8a2389494ef98483" + integrity sha512-YhIOJsMNjPvP0tmTbC1MRlxl5q7l21uQQDr1rlXEWHNmI2AEMW0gfr2wXrlB2Tz/oOIx8YqREsj3i0VsYXEaCA== dependencies: invariant "^2.2.4" -expo-secure-store@~13.0.1: - version "13.0.1" - resolved "https://registry.yarnpkg.com/expo-secure-store/-/expo-secure-store-13.0.1.tgz#fc886d3e0ed12890c8dd74e7cc44e35b03f2d79b" - integrity sha512-5DTKjbv98X7yPbm+1jER/sOEIlt2Ih7qwabTvkWDXry5bPcQGoulxH5zIX9+JvVH7of8GI4t7NSEbpAO3P7FZA== +expo-secure-store@~13.0.2: + version "13.0.2" + resolved "https://registry.yarnpkg.com/expo-secure-store/-/expo-secure-store-13.0.2.tgz#ba8f6076fc38062a28bb2ce5edab9cd28ef88598" + integrity sha512-3QYgoneo8p8yeeBPBiAfokNNc2xq6+n8+Ob4fAlErEcf4H7Y72LH+K/dx0nQyWau2ZKZUXBxyyfuHFyVKrEVLg== expo-splash-screen@~0.27.4: version "0.27.5" @@ -4912,24 +5006,24 @@ expo-status-bar@~1.12.1: resolved "https://registry.yarnpkg.com/expo-status-bar/-/expo-status-bar-1.12.1.tgz#52ce594aab5064a0511d14375364d718ab78aa66" integrity sha512-/t3xdbS8KB0prj5KG5w7z+wZPFlPtkgs95BsmrP/E7Q0xHXTcDcQ6Cu2FkFuRM+PKTb17cJDnLkawyS5vDLxMA== -expo@~51.0.8: - version "51.0.14" - resolved "https://registry.yarnpkg.com/expo/-/expo-51.0.14.tgz#98769b090a0b5c7d7c7028fdb9c21904f56cd9fa" - integrity sha512-99BAMSYBH1aq1TIEJqM03kRpsZjN8OqZXDqYHRq9/PXT67axRUOvRjwMMLprnCmqkAVM7m7FpiECNWN4U0gvLQ== +expo@~51.0.17: + version "51.0.17" + resolved "https://registry.yarnpkg.com/expo/-/expo-51.0.17.tgz#aa5217a38edd9fd0b28b598daf3661acd66537f2" + integrity sha512-VqLrdVMLdjCUhNuWWGdexqkiscnudY7OACafBrfqIFOejAeKceEaBU5YQIlNlOsKuB7PBMqDkhdZ+dG93Ul4ig== dependencies: "@babel/runtime" "^7.20.0" - "@expo/cli" "0.18.19" + "@expo/cli" "0.18.21" "@expo/config" "9.0.1" - "@expo/config-plugins" "8.0.5" - "@expo/metro-config" "0.18.7" + "@expo/config-plugins" "8.0.6" + "@expo/metro-config" "0.18.8" "@expo/vector-icons" "^14.0.0" - babel-preset-expo "~11.0.10" - expo-asset "~10.0.9" + babel-preset-expo "~11.0.11" + expo-asset "~10.0.10" expo-file-system "~17.0.1" expo-font "~12.0.7" expo-keep-awake "~13.0.2" expo-modules-autolinking "1.11.1" - expo-modules-core "1.12.15" + expo-modules-core "1.12.18" fbemitter "^3.0.0" whatwg-url-without-unicode "8.0.0-3" @@ -6628,7 +6722,7 @@ lodash.throttle@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== -lodash@^4.17.13, lodash@^4.17.21: +lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -7889,6 +7983,16 @@ pretty-bytes@5.6.0: resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== +pretty-format@^24: + version "24.9.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" + integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== + dependencies: + "@jest/types" "^24.9.0" + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + react-is "^16.8.4" + pretty-format@^26.5.2, pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" @@ -8080,7 +8184,7 @@ react-freeze@^1.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== -react-is@^16.13.0, react-is@^16.13.1, react-is@^16.7.0: +react-is@^16.13.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -8159,23 +8263,23 @@ react-native-redash@^18.1.3: normalize-svg-path "^1.0.1" parse-svg-path "^0.1.2" -react-native-safe-area-context@^4.8.2: - version "4.10.5" - resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.10.5.tgz#a9c677a48bd273afa6876772062ce08e8af1f18d" - integrity sha512-Wyb0Nqw2XJ6oZxW/cK8k5q7/UAhg/wbEG6UVf89rQqecDZTDA5ic//P9J6VvJRVZerzGmxWQpVuM7f+PRYUM4g== +react-native-safe-area-context@4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.10.1.tgz#29fb27395ff7dfa2fa38788a27226330d73a81cc" + integrity sha512-w8tCuowDorUkPoWPXmhqosovBr33YsukkwYCDERZFHAxIkx6qBadYxfeoaJ91nCQKjkNzGrK5qhoNOeSIcYSpA== -react-native-screens@^3.29.0: - version "3.32.0" - resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.32.0.tgz#47c3d2efc9cd5ed18af41b34efc8b46df05b87b4" - integrity sha512-wybqZAHX7v8ipOXhh90CqGLkBHw5JYqKNRBX7R/b0c2WQisTOgu0M0yGwBMM6LyXRBT+4k3NTGHdDbpJVpq0yQ== +react-native-screens@3.31.1: + version "3.31.1" + resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.31.1.tgz#909a890f669e32b0fb1b1410278b71ad2f8238f6" + integrity sha512-8fRW362pfZ9y4rS8KY5P3DFScrmwo/vu1RrRMMx0PNHbeC9TLq0Kw1ubD83591yz64gLNHFLTVkTJmWeWCXKtQ== dependencies: react-freeze "^1.0.0" warn-once "^0.1.0" -react-native-svg@^15.3.0: - version "15.3.0" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.3.0.tgz#e24b833fe330714c99f1dd894bb0da52ad859a4c" - integrity sha512-mBHu/fdlzUbpGX8SZFxgbKvK/sgqLfDLP8uh8G7Us+zJgdjO8OSEeqHQs+kPRdQmdLJQiqPJX2WXgCl7ToTWqw== +react-native-svg@15.2.0: + version "15.2.0" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.2.0.tgz#9561a6b3bd6b44689f437ba13182afee33bd5557" + integrity sha512-R0E6IhcJfVLsL0lRmnUSm72QO+mTqcAOM5Jb8FVGxJqX3NfJMlMP0YyvcajZiaRR8CqQUpEoqrY25eyZb006kw== dependencies: css-select "^5.1.0" css-tree "^1.1.3" @@ -8208,22 +8312,22 @@ react-native-web@~0.19.6: postcss-value-parser "^4.2.0" styleq "^0.1.3" -react-native@0.74.1: - version "0.74.1" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.74.1.tgz#8f5f59636242eb1b90ff675d9fcc7f5b8b1c9913" - integrity sha512-0H2XpmghwOtfPpM2LKqHIN7gxy+7G/r1hwJHKLV6uoyXGC/gCojRtoo5NqyKrWpFC8cqyT6wTYCLuG7CxEKilg== +react-native@0.74.3: + version "0.74.3" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.74.3.tgz#eef32cd10afb1f4b26f75b79eefd6b220c63953c" + integrity sha512-UFutCC6WEw6HkxlcpQ2BemKqi0JkwrgDchYB5Svi8Sp4Xwt4HA6LGEjNQgZ+3KM44bjyFRpofQym0uh0jACGng== dependencies: "@jest/create-cache-key-function" "^29.6.3" - "@react-native-community/cli" "13.6.6" - "@react-native-community/cli-platform-android" "13.6.6" - "@react-native-community/cli-platform-ios" "13.6.6" - "@react-native/assets-registry" "0.74.83" - "@react-native/codegen" "0.74.83" - "@react-native/community-cli-plugin" "0.74.83" - "@react-native/gradle-plugin" "0.74.83" - "@react-native/js-polyfills" "0.74.83" - "@react-native/normalize-colors" "0.74.83" - "@react-native/virtualized-lists" "0.74.83" + "@react-native-community/cli" "13.6.9" + "@react-native-community/cli-platform-android" "13.6.9" + "@react-native-community/cli-platform-ios" "13.6.9" + "@react-native/assets-registry" "0.74.85" + "@react-native/codegen" "0.74.85" + "@react-native/community-cli-plugin" "0.74.85" + "@react-native/gradle-plugin" "0.74.85" + "@react-native/js-polyfills" "0.74.85" + "@react-native/normalize-colors" "0.74.85" + "@react-native/virtualized-lists" "0.74.85" abort-controller "^3.0.0" anser "^1.4.9" ansi-regex "^5.0.0" @@ -8825,7 +8929,7 @@ source-map-support@^0.5.16, source-map-support@~0.5.20, source-map-support@~0.5. buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.5.6: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== @@ -9375,6 +9479,11 @@ traverse@~0.6.6: typedarray.prototype.slice "^1.0.3" which-typed-array "^1.1.15" +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw== + trpc-browser@^1.3.2: version "1.4.2" resolved "https://registry.yarnpkg.com/trpc-browser/-/trpc-browser-1.4.2.tgz#bcfd6cf04634567feb782b90606d6cef950f236c" @@ -10137,7 +10246,12 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zod@^3.22.2: +zod-validation-error@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-2.1.0.tgz#208eac75237dfed47c0018d2fe8fd03501bfc9ac" + integrity sha512-VJh93e2wb4c3tWtGgTa0OF/dTt/zoPCPzXq4V11ZjxmEAFaPi/Zss1xIZdEB5RD8GD00U0/iVXgqkF77RV7pdQ== + +zod@^3.22.2, zod@^3.22.4: version "3.23.8" resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==