diff --git a/app.config.ts b/app.config.ts index 15666b8..7fbad9d 100644 --- a/app.config.ts +++ b/app.config.ts @@ -11,7 +11,7 @@ const googleServicesFile = const config: ExpoConfig = { name: appName, slug: 'konect-react-native', - version: '1.0.7', + version: '1.0.8', orientation: 'portrait', icon: './assets/images/icon.png', scheme: 'konect', @@ -20,13 +20,13 @@ const config: ExpoConfig = { supportsTablet: true, usesAppleSignIn: true, bundleIdentifier: packageName, - buildNumber: '1010700', + buildNumber: '1010800', infoPlist: { ITSAppUsesNonExemptEncryption: false, }, }, android: { - versionCode: 1010700, + versionCode: 1010800, package: packageName, googleServicesFile: googleServicesFile, }, diff --git a/app/webview/[path].tsx b/app/webview/[path].tsx index 27008b8..5c0d96b 100644 --- a/app/webview/[path].tsx +++ b/app/webview/[path].tsx @@ -1,4 +1,4 @@ -import { useRef, useEffect, useCallback } from 'react'; +import { useRef, useEffect, useCallback, useState } from 'react'; import { BackHandler, Platform, @@ -9,7 +9,7 @@ import { AppState, AppStateStatus, } from 'react-native'; -import { Slot, useLocalSearchParams } from 'expo-router'; +import { Slot, Stack, useLocalSearchParams } from 'expo-router'; import { WebView, WebViewMessageEvent } from 'react-native-webview'; import { SafeAreaView } from 'react-native-safe-area-context'; import CookieManager from '@preeternal/react-native-cookie-manager'; @@ -21,12 +21,37 @@ import { webUrl } from '../../constants/constants'; import { getStoredToken } from '../../utils/pushTokenStore'; import { saveAccessToken, clearAccessToken } from '../../services/nativeAuthStore'; import { registerPushToken, unregisterPushToken } from '../../services/pushTokenApi'; +import { disableTimerDisplayMode, enableTimerDisplayMode } from '../../services/timerDisplayMode'; const ALLOWED_URL_SCHEMES = ['kakaotalk', 'nidlogin']; const ALLOWED_ORIGINS = [new URL(webUrl).origin]; +const NATIVE_BACK_REQUEST_EVENT = 'KONECT_NATIVE_BACK_REQUEST'; const userAgent = generateUserAgent(); +function getUrlOrigin(url: string): string | null { + try { + return new URL(url).origin; + } catch { + return null; + } +} + +type NativeBridgeMessage = + | { type: 'LOGIN_COMPLETE'; accessToken?: string } + | { type: 'TOKEN_REFRESH'; accessToken?: string } + | { type: 'LOGOUT' } + | { type: 'TIMER_ACTIVE'; keepAwake?: boolean; dimScreen?: boolean; brightnessLevel?: number } + | { type: 'TIMER_INACTIVE' } + | { type: 'NAVIGATE_BACK' }; + +interface TimerDisplayModeState { + brightnessLevel?: number; + dimScreen: boolean; + isActive: boolean; + keepAwake: boolean; +} + const injectedJavaScript = ` (function () { const allowedOrigins = ${JSON.stringify(ALLOWED_ORIGINS)}; @@ -58,16 +83,34 @@ const handleOnShouldStartLoadWithRequest = ({ url }: ShouldStartLoadRequest) => export default function Index() { const webViewRef = useRef(null); const canGoBackRef = useRef(false); + const currentOriginRef = useRef(ALLOWED_ORIGINS[0]); + const timerDisplayModeRef = useRef({ + brightnessLevel: undefined, + isActive: false, + keepAwake: true, + dimScreen: true, + }); const local = useLocalSearchParams(); + const [isTimerActive, setIsTimerActive] = useState(false); + + const requestWebBackConfirmation = useCallback(() => { + webViewRef.current?.injectJavaScript( + `window.dispatchEvent(new Event(${JSON.stringify(NATIVE_BACK_REQUEST_EVENT)}));true;` + ); + }, []); const handleMessage = useCallback(async (event: WebViewMessageEvent) => { - const origin = event.nativeEvent.url; - if (!origin || !ALLOWED_ORIGINS.some((allowed) => origin.startsWith(allowed))) { + const messageOrigin = getUrlOrigin(event.nativeEvent.url); + if ( + messageOrigin === null || + messageOrigin === 'null' || + !ALLOWED_ORIGINS.includes(messageOrigin) + ) { return; } try { - const data = JSON.parse(event.nativeEvent.data); + const data: NativeBridgeMessage = JSON.parse(event.nativeEvent.data); const { type } = data; if (type === 'LOGIN_COMPLETE') { @@ -110,6 +153,37 @@ export default function Index() { } await clearAccessToken(); console.log('LOGOUT: accessToken 삭제 완료'); + } else if (type === 'TIMER_ACTIVE') { + const keepAwake = data.keepAwake !== false; + const dimScreen = data.dimScreen !== false; + const brightnessLevel = data.brightnessLevel; + + timerDisplayModeRef.current = { + brightnessLevel, + isActive: true, + keepAwake, + dimScreen, + }; + setIsTimerActive(true); + + await enableTimerDisplayMode({ keepAwake, dimScreen, brightnessLevel }); + } else if (type === 'TIMER_INACTIVE') { + timerDisplayModeRef.current = { + ...timerDisplayModeRef.current, + isActive: false, + }; + setIsTimerActive(false); + + await disableTimerDisplayMode(); + } else if (type === 'NAVIGATE_BACK') { + if (webViewRef.current && canGoBackRef.current) { + webViewRef.current.goBack(); + return; + } + + if (Platform.OS === 'android') { + BackHandler.exitApp(); + } } } catch { // JSON 파싱 실패 등 무시 @@ -119,6 +193,15 @@ export default function Index() { useEffect(() => { if (Platform.OS === 'android') { const onBackPress = () => { + const isAllowedOrigin = currentOriginRef.current + ? ALLOWED_ORIGINS.includes(currentOriginRef.current) + : false; + + if (timerDisplayModeRef.current.isActive && isAllowedOrigin) { + requestWebBackConfirmation(); + return true; + } + if (webViewRef.current && canGoBackRef.current) { webViewRef.current.goBack(); return true; @@ -128,17 +211,30 @@ export default function Index() { const subscription = BackHandler.addEventListener('hardwareBackPress', onBackPress); return () => subscription.remove(); } - }, []); + }, [requestWebBackConfirmation]); useEffect(() => { const handleAppStateChange = (nextAppState: AppStateStatus) => { if (nextAppState === 'background' || nextAppState === 'inactive') { CookieManager.flush(); + void disableTimerDisplayMode(); + return; + } + + if (nextAppState === 'active' && timerDisplayModeRef.current.isActive) { + void enableTimerDisplayMode({ + brightnessLevel: timerDisplayModeRef.current.brightnessLevel, + keepAwake: timerDisplayModeRef.current.keepAwake, + dimScreen: timerDisplayModeRef.current.dimScreen, + }); } }; const subscription = AppState.addEventListener('change', handleAppStateChange); - return () => subscription.remove(); + return () => { + subscription.remove(); + void disableTimerDisplayMode(); + }; }, []); if (Platform.OS === 'web') { @@ -146,35 +242,39 @@ export default function Index() { } return ( - - - { - canGoBackRef.current = navState.canGoBack; - }} - source={{ uri: `${webUrl}/${local.path ?? ''}` }} - style={styles.webview} - javaScriptEnabled - domStorageEnabled - thirdPartyCookiesEnabled={true} - sharedCookiesEnabled={true} - userAgent={userAgent} - hideKeyboardAccessoryView={Platform.OS === 'ios'} - injectedJavaScript={injectedJavaScript} - onShouldStartLoadWithRequest={handleOnShouldStartLoadWithRequest} - setSupportMultipleWindows - onOpenWindow={(event) => { - WebBrowser.openBrowserAsync(event.nativeEvent.targetUrl); - }} - originWhitelist={['*']} - startInLoadingState - onMessage={handleMessage} - /> - + <> + + + + { + canGoBackRef.current = navState.canGoBack; + currentOriginRef.current = getUrlOrigin(navState.url); + }} + source={{ uri: `${webUrl}/${local.path ?? ''}` }} + style={styles.webview} + javaScriptEnabled + domStorageEnabled + thirdPartyCookiesEnabled={true} + sharedCookiesEnabled={true} + userAgent={userAgent} + hideKeyboardAccessoryView={Platform.OS === 'ios'} + injectedJavaScript={injectedJavaScript} + onShouldStartLoadWithRequest={handleOnShouldStartLoadWithRequest} + setSupportMultipleWindows + onOpenWindow={(event) => { + WebBrowser.openBrowserAsync(event.nativeEvent.targetUrl); + }} + originWhitelist={['*']} + startInLoadingState + onMessage={handleMessage} + /> + + ); } diff --git a/package.json b/package.json index d7a550e..e1973bb 100644 --- a/package.json +++ b/package.json @@ -16,22 +16,24 @@ "dependencies": { "@babel/runtime": "^7.28.6", "@preeternal/react-native-cookie-manager": "^6.3.1", - "expo": "^55.0.8", + "expo": "~55.0.9", "expo-apple-authentication": "~55.0.9", "expo-application": "~55.0.10", + "expo-brightness": "~55.0.8", "expo-build-properties": "~55.0.10", "expo-constants": "~55.0.9", "expo-device": "~55.0.10", "expo-font": "~55.0.4", - "expo-linking": "~55.0.8", - "expo-notifications": "~55.0.13", - "expo-router": "~55.0.7", + "expo-keep-awake": "~55.0.4", + "expo-linking": "~55.0.9", + "expo-notifications": "~55.0.14", + "expo-router": "~55.0.8", "expo-secure-store": "~55.0.9", - "expo-splash-screen": "~55.0.12", + "expo-splash-screen": "~55.0.13", "expo-web-browser": "~55.0.10", "react": "19.2.0", "react-dom": "19.2.0", - "react-native": "^0.83.2", + "react-native": "0.83.2", "react-native-gesture-handler": "~2.30.1", "react-native-reanimated": "~4.2.1", "react-native-safe-area-context": "~5.6.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 60bb5ae..006d8bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,44 +15,50 @@ importers: specifier: ^6.3.1 version: 6.3.1(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) expo: - specifier: ^55.0.8 - version: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + specifier: ~55.0.9 + version: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) expo-apple-authentication: specifier: ~55.0.9 - version: 55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) + version: 55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) expo-application: specifier: ~55.0.10 - version: 55.0.10(expo@55.0.8) + version: 55.0.10(expo@55.0.9) + expo-brightness: + specifier: ~55.0.8 + version: 55.0.13(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) expo-build-properties: specifier: ~55.0.10 - version: 55.0.10(expo@55.0.8) + version: 55.0.10(expo@55.0.9) expo-constants: specifier: ~55.0.9 - version: 55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + version: 55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) expo-device: specifier: ~55.0.10 - version: 55.0.10(expo@55.0.8) + version: 55.0.10(expo@55.0.9) expo-font: specifier: ~55.0.4 - version: 55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 55.0.4(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-keep-awake: + specifier: ~55.0.4 + version: 55.0.4(expo@55.0.9)(react@19.2.0) expo-linking: - specifier: ~55.0.8 - version: 55.0.8(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + specifier: ~55.0.9 + version: 55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) expo-notifications: - specifier: ~55.0.13 - version: 55.0.13(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + specifier: ~55.0.14 + version: 55.0.14(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) expo-router: - specifier: ~55.0.7 - version: 55.0.7(7511b7cdea3486076770b15ac1f40957) + specifier: ~55.0.8 + version: 55.0.8(9db59377a3fbcf0eb63542ffa9ff8e3f) expo-secure-store: specifier: ~55.0.9 - version: 55.0.9(expo@55.0.8) + version: 55.0.9(expo@55.0.9) expo-splash-screen: - specifier: ~55.0.12 - version: 55.0.12(expo@55.0.8)(typescript@5.9.3) + specifier: ~55.0.13 + version: 55.0.13(expo@55.0.9)(typescript@5.9.3) expo-web-browser: specifier: ~55.0.10 - version: 55.0.10(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) + version: 55.0.10(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) react: specifier: 19.2.0 version: 19.2.0 @@ -60,7 +66,7 @@ importers: specifier: 19.2.0 version: 19.2.0(react@19.2.0) react-native: - specifier: ^0.83.2 + specifier: 0.83.2 version: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) react-native-gesture-handler: specifier: ~2.30.1 @@ -110,7 +116,7 @@ importers: version: 29.7.0(@types/node@25.2.0) jest-expo: specifier: ~55.0.11 - version: 55.0.11(@babel/core@7.29.0)(expo@55.0.8)(jest@29.7.0(@types/node@25.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + version: 55.0.11(@babel/core@7.29.0)(expo@55.0.9)(jest@29.7.0(@types/node@25.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react-test-renderer: specifier: ^19.1.0 version: 19.2.4(react@19.2.0) @@ -683,8 +689,8 @@ packages: '@expo-google-fonts/material-symbols@0.4.27': resolution: {integrity: sha512-cnb3DZnWUWpezGFkJ8y4MT5f/lw6FcgDzeJzic+T+vpQHLHG1cg3SC3i1w1i8Bk4xKR4HPY3t9iIRNvtr5ml8A==} - '@expo/cli@55.0.18': - resolution: {integrity: sha512-3sJwu8KvCvQIXBnhUlHgLBZBe+ZK4Da9R5rgI4znaowJavYWMqzRClLzyE6Kri66WVoMX7Q4HUVIh8prRlO0XA==} + '@expo/cli@55.0.19': + resolution: {integrity: sha512-PPNWwPXHcLDFgNNmkLmlLm3fLiNTxr7sbhNx4mXdjo0U/2Wg3rWaCeg1yMx49llOpDLZEWJpyAwPvTBqWc8glw==} hasBin: true peerDependencies: expo: '*' @@ -708,6 +714,9 @@ packages: '@expo/config@55.0.10': resolution: {integrity: sha512-qCHxo9H1ZoeW+y0QeMtVZ3JfGmumpGrgUFX60wLWMarraoQZSe47ZUm9kJSn3iyoPjUtUNanO3eXQg+K8k4rag==} + '@expo/config@55.0.11': + resolution: {integrity: sha512-14AkSmR1gOIUhCsPJ0cAo5ZduMNsPQsmFV9jBNZn1xC5Zb3D8x5eqvUie5QzWaUwdcyrq79uYJ2bTCiC6+nD0Q==} + '@expo/devcert@1.2.1': resolution: {integrity: sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==} @@ -746,8 +755,8 @@ packages: '@expo/local-build-cache-provider@55.0.7': resolution: {integrity: sha512-Qg9uNZn1buv4zJUA4ZQaz+ZnKDCipRgjoEg2Gcp8Qfy+2Gq5yZKX4YN1TThCJ01LJk/pvJsCRxXlXZSwdZppgg==} - '@expo/log-box@55.0.7': - resolution: {integrity: sha512-m7V1k2vlMp4NOj3fopjOg4zl/ANXyTRF3HMTMep2GZAKsPiDzgOQ41nm8CaU50/HlDIGXlCObss07gOn20UpHQ==} + '@expo/log-box@55.0.8': + resolution: {integrity: sha512-WVEuW1XcntUdOpQk8k9cUymM5FHKmEcPr6QO9SVIin3WYk5FbbwHRYr1T6GfwWF0UA2s9w9heeYolesq99vFIw==} peerDependencies: '@expo/dom-webview': ^55.0.3 expo: '*' @@ -780,8 +789,8 @@ packages: '@expo/plist@0.5.2': resolution: {integrity: sha512-o4xdVdBpe4aTl3sPMZ2u3fJH4iG1I768EIRk1xRZP+GaFI93MaR3JvoFibYqxeTmLQ1p1kNEVqylfUjezxx45g==} - '@expo/prebuild-config@55.0.10': - resolution: {integrity: sha512-AMylDld5G7YJGfEhEyXtgWRuBB83802QBoewF1vJ6NMDtufukuPhMJzOs9E4UXNsjLTaQcgT4yTWhsAWl7o1AQ==} + '@expo/prebuild-config@55.0.11': + resolution: {integrity: sha512-PqjbTTHXS0dnZMH4X5/0rnLxKfQqyN1s/5lmxITn+U6WDUNibatUepfjwV+5C2jU4hv5z2haqX6e9hQ0zUtDMA==} peerDependencies: expo: '*' @@ -796,7 +805,7 @@ packages: '@expo/router-server@55.0.11': resolution: {integrity: sha512-Kd8J1OOlFR00DZxn+1KfiQiXZtRut6cj8+ynqHJa7dtt/lTL4tGkYistqmVhpKJ6w886eRY5WivKy7o0ZBFkJA==} peerDependencies: - '@expo/metro-runtime': 5.0.4 + '@expo/metro-runtime': ^55.0.6 expo: '*' expo-constants: ^55.0.9 expo-font: ^55.0.4 @@ -1212,12 +1221,12 @@ packages: resolution: {integrity: sha512-9I5l3pGAKnlpQ15uVkeB9Mgjvt3cZEaEc8EDtdexvdtZvLSjtwBzgourrOW4yZUijbjJr8h3YO2Y0q+THwUHTA==} engines: {node: '>= 20.19.4'} - '@react-native/babel-plugin-codegen@0.83.2': - resolution: {integrity: sha512-XbcN/BEa64pVlb0Hb/E/Ph2SepjVN/FcNKrJcQvtaKZA6mBSO8pW8Eircdlr61/KBH94LihHbQoQDzkQFpeaTg==} + '@react-native/babel-plugin-codegen@0.83.4': + resolution: {integrity: sha512-UFsK+c1rvT84XZfzpmwKePsc5nTr5LK7hh18TI0DooNlVcztDbMDsQZpDnhO/gmk7aTbWEqO5AB3HJ7tvGp+Jg==} engines: {node: '>= 20.19.4'} - '@react-native/babel-preset@0.83.2': - resolution: {integrity: sha512-X/RAXDfe6W+om/Fw1i6htTxQXFhBJ2jgNOWx3WpI3KbjeIWbq7ib6vrpTeIAW2NUMg+K3mML1NzgD4dpZeqdjA==} + '@react-native/babel-preset@0.83.4': + resolution: {integrity: sha512-SXPFn3Jp4gOzlBDnDOKPzMfxQPKJMYJs05EmEeFB/6km46xZ9l+2YKXwAwxfNhHnmwNf98U/bnVndU95I0TMCw==} engines: {node: '>= 20.19.4'} peerDependencies: '@babel/core': '*' @@ -1228,6 +1237,12 @@ packages: peerDependencies: '@babel/core': '*' + '@react-native/codegen@0.83.4': + resolution: {integrity: sha512-CJ7XutzIqJPz3Lp/5TOiRWlU/JAjTboMT1BHNLSXjYHXwTmgHM3iGEbpCOtBMjWvsojRTJyRO/G3ghInIIXEYg==} + engines: {node: '>= 20.19.4'} + peerDependencies: + '@babel/core': '*' + '@react-native/community-cli-plugin@0.83.2': resolution: {integrity: sha512-sTEF0eiUKtmImEP07Qo5c3Khvm1LIVX1Qyb6zWUqPL6W3MqFiXutZvKBjqLz6p49Szx8cplQLoXfLHT0bcDXKg==} engines: {node: '>= 20.19.4'} @@ -1244,14 +1259,26 @@ packages: resolution: {integrity: sha512-t4fYfa7xopbUF5S4+ihNEwgaq4wLZLKLY0Ms8z72lkMteVd3bOX2Foxa8E2wTfRvdhPOkSpOsTeNDmD8ON4DoQ==} engines: {node: '>= 20.19.4'} + '@react-native/debugger-frontend@0.83.4': + resolution: {integrity: sha512-mCE2s/S7SEjax3gZb6LFAraAI3x13gRVWJWqT0HIm71e4ITObENNTDuMw4mvZ/wr4Gz2wv4FcBH5/Nla9LXOcg==} + engines: {node: '>= 20.19.4'} + '@react-native/debugger-shell@0.83.2': resolution: {integrity: sha512-z9go6NJMsLSDJT5MW6VGugRsZHjYvUTwxtsVc3uLt4U9W6T3J6FWI2wHpXIzd2dUkXRfAiRQ3Zi8ZQQ8fRFg9A==} engines: {node: '>= 20.19.4'} + '@react-native/debugger-shell@0.83.4': + resolution: {integrity: sha512-FtAnrvXqy1xeZ+onwilvxEeeBsvBlhtfrHVIC2R/BOJAK9TbKEtFfjio0wsn3DQIm+UZq48DSa+p9jJZ2aJUww==} + engines: {node: '>= 20.19.4'} + '@react-native/dev-middleware@0.83.2': resolution: {integrity: sha512-Zi4EVaAm28+icD19NN07Gh8Pqg/84QQu+jn4patfWKNkcToRFP5vPEbbp0eLOGWS+BVB1d1Fn5lvMrJsBbFcOg==} engines: {node: '>= 20.19.4'} + '@react-native/dev-middleware@0.83.4': + resolution: {integrity: sha512-3s9nXZc/kj986nI2RPqxiIJeTS3o7pvZDxbHu7GE9WVIGX9YucA1l/tEiXd7BAm3TBFOfefDOT08xD46wH+R3Q==} + engines: {node: '>= 20.19.4'} + '@react-native/gradle-plugin@0.83.2': resolution: {integrity: sha512-PqN11fXRAU+uJ0inZY1HWYlwJOXHOhF4SPyeHBBxjajKpm2PGunmvFWwkmBjmmUkP/CNO0ezTUudV0oj+2wiHQ==} engines: {node: '>= 20.19.4'} @@ -1266,6 +1293,9 @@ packages: '@react-native/normalize-colors@0.83.2': resolution: {integrity: sha512-gkZAb9LoVVzNuYzzOviH7DiPTXQoZPHuiTH2+O2+VWNtOkiznjgvqpwYAhg58a5zfRq5GXlbBdf5mzRj5+3Y5Q==} + '@react-native/normalize-colors@0.83.4': + resolution: {integrity: sha512-9ezxaHjxqTkTOLg62SGg7YhFaE+fxa/jlrWP0nwf7eGFHlGOiTAaRR2KUfiN3K05e+EMbEhgcH/c7bgaXeGyJw==} + '@react-native/virtualized-lists@0.83.2': resolution: {integrity: sha512-N7mRjHLW/+KWxMp9IHRWyE3VIkeG1m3PnZJAGEFLCN8VFb7e4VfI567o7tE/HYcdcXCylw+Eqhlciz8gDeQ71g==} engines: {node: '>= 20.19.4'} @@ -1759,12 +1789,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 || ^8.0.0-0 - babel-preset-expo@55.0.12: - resolution: {integrity: sha512-oR46ExGZpRijmPUsr0rFH5X4lR/mvwqJAFXJRLpynZcvyv2pHPTeGMNfd/p5oPMbdbaeMS6G+3k18p48u2Qjbw==} + babel-preset-expo@55.0.13: + resolution: {integrity: sha512-7m3Hpi6R1M+3u2LEU15OV59ATtbqz6kFvL6y9TaZTeOGLV28MFULawCQw3BtO/qMYUPz0vkH1OdbCuG7E2cTbg==} peerDependencies: '@babel/runtime': ^7.20.0 expo: '*' - expo-widgets: ^55.0.6 + expo-widgets: ^55.0.8 react-refresh: '>=0.14.0 <1.0.0' peerDependenciesMeta: '@babel/runtime': @@ -2414,6 +2444,12 @@ packages: react: '*' react-native: '*' + expo-brightness@55.0.13: + resolution: {integrity: sha512-vFMrB+ZLn9CBO4cTngh7oaogzYEhUlXvA0/V+iWBYwXrSQNb1lYZIfV2KYsehnwWvox8mDlVEGXtd9rU5Hi11A==} + peerDependencies: + expo: '*' + react-native: '*' + expo-build-properties@55.0.10: resolution: {integrity: sha512-9+JCQuIQaEi27XDIFTR2Y4vok0FidWux2UKrKWD5E38/0fozbZcVUzS14FgMF1F0lalmXMgebH/vjRpbYWJIMA==} peerDependencies: @@ -2430,8 +2466,8 @@ packages: peerDependencies: expo: '*' - expo-file-system@55.0.11: - resolution: {integrity: sha512-KMUd6OY375J9WD79ZvjvCDZMveT7YfgiGWdi58/gfuTBsr14TRuoPk8RRQHAtc4UquzWViKcHwna9aPY7/XPpw==} + expo-file-system@55.0.12: + resolution: {integrity: sha512-MFN/3L3gm174nxP2HqKQsSsPbjAj92wuidKFGSbl3Lt6oJTS09EbTwszX5BhYeeVSprcsw8pnlxYSmhkSqGEFw==} peerDependencies: expo: '*' react-native: '*' @@ -2467,39 +2503,39 @@ packages: expo: '*' react: '*' - expo-linking@55.0.8: - resolution: {integrity: sha512-O9QgKAfEqKfsjL6IKs5p7pFAjo/3/TQwjMzzNPl8BCndbxWMPQfMeViXPYYNS9bA2ujUqrtF1OYhO6woI7GNQQ==} + expo-linking@55.0.9: + resolution: {integrity: sha512-QWEefQZUu7PuJzye19Hr6msqpO4VB4TiY4T/6AkISJzZnoZGxWg16s3JTZS7D/b3VMm8VQfhw9I5NF/7f8EPcA==} peerDependencies: react: '*' react-native: '*' - expo-modules-autolinking@55.0.11: - resolution: {integrity: sha512-9dqnPzQoIl1dIvEctMWpQ8eaiXDeBTgAwebCc1WF0BbEo+pcdKjZWoCSqlLj+d7IX+OnTgM+k6cY2kPDGIu4sg==} + expo-modules-autolinking@55.0.12: + resolution: {integrity: sha512-nZOPjpl4v5YInNftJpX10bYxDNNq2HM+hWTfr3FPE1/i0lES/cnvaB8v4XKpDTuAUdBwkGYadTfNwNG9k/Ftgw==} hasBin: true - expo-modules-core@55.0.17: - resolution: {integrity: sha512-pw3cZiaSlBrqRJUD/pHuMnKGsRTW6XJ255FrjDd3HC4QrqErCnfSQPmz+Sv4Qkelcvd9UGdAewyTqZdFwjLwOw==} + expo-modules-core@55.0.18: + resolution: {integrity: sha512-Qwr3qCCZd/aMtenUo6KmPaFy/uFeNz0rLfRxv0tNsWFF27XS2wjDwb87A7lD2ii8iJhjYEHVetRvFkcDxCw8Lw==} peerDependencies: react: '*' react-native: '*' - expo-notifications@55.0.13: - resolution: {integrity: sha512-vbtSBcMkYtNTO+6WKdeOzysOqvtmiq/sQrUKJpYcB75m9hBFcAfI2klpXdUiGg5kMr/ygBmFENSolQt1B9QY8A==} + expo-notifications@55.0.14: + resolution: {integrity: sha512-fwWTd0OK82Yj2MLJJK0cIgaRtAu8OUcjGuucdtsp/dOsErqBsGQQWpotoEXoRPrDrCL4sHwSvg9QzGdeouJ/jQ==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-router@55.0.7: - resolution: {integrity: sha512-UdraTi8/1LGCCEnq/3+wEVnM11b4ezFEIvMsWP9ajFvEhFGkcXlQitvSehT2yI5cbBrBaIMP2p/2naBiPyYVyw==} + expo-router@55.0.8: + resolution: {integrity: sha512-SG51cnmH84Htxa+vXJPw4xl10rDCrWkC/3m38Sn51Bg+9N2nPPJMhCYifAcR9ZYK6mlb2BPG1GiHVjZw78DSxQ==} peerDependencies: - '@expo/log-box': 55.0.7 - '@expo/metro-runtime': 5.0.4 + '@expo/log-box': 55.0.8 + '@expo/metro-runtime': ^55.0.7 '@react-navigation/drawer': ^7.9.4 '@testing-library/react-native': '>= 13.2.0' expo: '*' - expo-constants: ^55.0.8 - expo-linking: ^55.0.8 + expo-constants: ^55.0.9 + expo-linking: ^55.0.9 react: '*' react-dom: '*' react-native: '*' @@ -2534,8 +2570,8 @@ packages: resolution: {integrity: sha512-xI72FTm469FfuuBL2R5aNtthgH+GR7ygOpsx/KcPS0K8AZaZd7VjtEExbzn9/qyyYkWW3T+3dAmCDKOMX8gdmQ==} engines: {node: '>=20.16.0'} - expo-splash-screen@55.0.12: - resolution: {integrity: sha512-+QYsmW+fIF4bL6zXDeVRkxQr+i6w3UJRwDGOybT1NgN9GWxAO7J/lT9Q0IKVPyW4hDiQrdEMbVISOfpYm6QPIw==} + expo-splash-screen@55.0.13: + resolution: {integrity: sha512-dEainzjUZbqdmcQjO7tIqoh432jloxOGzHJHErGIMxg1QlahKj0e5D/4CY1Xd6qIOs1rRBlG63mPxx7iGBWbHQ==} peerDependencies: expo: '*' @@ -2553,12 +2589,12 @@ packages: expo: '*' react-native: '*' - expo@55.0.8: - resolution: {integrity: sha512-sziDGiDmeRmaSpFwMuSxFhr4vfWrQS1UgVXSTovsUDY0ximABzYdnF5L2OwtD8zjtIww8x2oJGmD6mKS+AoVsw==} + expo@55.0.9: + resolution: {integrity: sha512-bYDhqr2v2UtTf/9s493bUVRtxsYqXF4KXkaS3sSW827DmgxNJv0NuWKWwfqFdDxKvDELd488J5X9l9ogqUrwOA==} hasBin: true peerDependencies: '@expo/dom-webview': '*' - '@expo/metro-runtime': 5.0.4 + '@expo/metro-runtime': '*' react: '*' react-native: '*' react-native-webview: '*' @@ -5425,29 +5461,29 @@ snapshots: '@expo-google-fonts/material-symbols@0.4.27': {} - '@expo/cli@55.0.18(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-constants@55.0.9)(expo-font@55.0.4)(expo-router@55.0.7)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)': + '@expo/cli@55.0.19(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-constants@55.0.9)(expo-font@55.0.4)(expo-router@55.0.8)(expo@55.0.9)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)': dependencies: '@expo/code-signing-certificates': 0.0.6 - '@expo/config': 55.0.10(typescript@5.9.3) + '@expo/config': 55.0.11(typescript@5.9.3) '@expo/config-plugins': 55.0.7 '@expo/devcert': 1.2.1 '@expo/env': 2.1.1 '@expo/image-utils': 0.8.12 '@expo/json-file': 10.0.12 - '@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/log-box': 55.0.8(@expo/dom-webview@55.0.3)(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) '@expo/metro': 54.2.0 - '@expo/metro-config': 55.0.11(expo@55.0.8)(typescript@5.9.3) + '@expo/metro-config': 55.0.11(expo@55.0.9)(typescript@5.9.3) '@expo/osascript': 2.4.2 '@expo/package-manager': 1.10.3 '@expo/plist': 0.5.2 - '@expo/prebuild-config': 55.0.10(expo@55.0.8)(typescript@5.9.3) + '@expo/prebuild-config': 55.0.11(expo@55.0.9)(typescript@5.9.3) '@expo/require-utils': 55.0.3(typescript@5.9.3) - '@expo/router-server': 55.0.11(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-constants@55.0.9)(expo-font@55.0.4)(expo-router@55.0.7)(expo-server@55.0.6)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@expo/router-server': 55.0.11(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-constants@55.0.9)(expo-font@55.0.4)(expo-router@55.0.8)(expo-server@55.0.6)(expo@55.0.9)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@expo/schema-utils': 55.0.2 '@expo/spawn-async': 1.7.2 '@expo/ws-tunnel': 1.0.6 '@expo/xcpretty': 4.4.0 - '@react-native/dev-middleware': 0.83.2 + '@react-native/dev-middleware': 0.83.4 accepts: 1.3.8 arg: 5.0.2 better-opn: 3.0.2 @@ -5459,7 +5495,7 @@ snapshots: connect: 3.7.0 debug: 4.4.3 dnssd-advertise: 1.1.4 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) expo-server: 55.0.6 fetch-nodeshim: 0.4.10 getenv: 2.0.0 @@ -5486,7 +5522,7 @@ snapshots: ws: 8.19.0 zod: 3.25.76 optionalDependencies: - expo-router: 55.0.7(7511b7cdea3486076770b15ac1f40957) + expo-router: 55.0.8(9db59377a3fbcf0eb63542ffa9ff8e3f) react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) transitivePeerDependencies: - '@expo/dom-webview' @@ -5542,6 +5578,23 @@ snapshots: - supports-color - typescript + '@expo/config@55.0.11(typescript@5.9.3)': + dependencies: + '@expo/config-plugins': 55.0.7 + '@expo/config-types': 55.0.5 + '@expo/json-file': 10.0.12 + '@expo/require-utils': 55.0.3(typescript@5.9.3) + deepmerge: 4.3.1 + getenv: 2.0.0 + glob: 13.0.1 + resolve-from: 5.0.0 + resolve-workspace-root: 2.0.1 + semver: 7.7.3 + slugify: 1.6.6 + transitivePeerDependencies: + - supports-color + - typescript + '@expo/devcert@1.2.1': dependencies: '@expo/sudo-prompt': 9.3.2 @@ -5556,9 +5609,9 @@ snapshots: react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - '@expo/dom-webview@55.0.3(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@expo/dom-webview@55.0.3(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) @@ -5603,27 +5656,27 @@ snapshots: '@expo/local-build-cache-provider@55.0.7(typescript@5.9.3)': dependencies: - '@expo/config': 55.0.10(typescript@5.9.3) + '@expo/config': 55.0.11(typescript@5.9.3) chalk: 4.1.2 transitivePeerDependencies: - supports-color - typescript - '@expo/log-box@55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@expo/log-box@55.0.8(@expo/dom-webview@55.0.3)(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': dependencies: - '@expo/dom-webview': 55.0.3(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/dom-webview': 55.0.3(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) anser: 1.4.10 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) stacktrace-parser: 0.1.11 - '@expo/metro-config@55.0.11(expo@55.0.8)(typescript@5.9.3)': + '@expo/metro-config@55.0.11(expo@55.0.9)(typescript@5.9.3)': dependencies: '@babel/code-frame': 7.29.0 '@babel/core': 7.29.0 '@babel/generator': 7.29.0 - '@expo/config': 55.0.10(typescript@5.9.3) + '@expo/config': 55.0.11(typescript@5.9.3) '@expo/env': 2.1.1 '@expo/json-file': 10.0.12 '@expo/metro': 54.2.0 @@ -5633,14 +5686,14 @@ snapshots: debug: 4.4.3 getenv: 2.0.0 glob: 13.0.1 - hermes-parser: 0.32.0 + hermes-parser: 0.32.1 jsc-safe-url: 0.2.4 lightningcss: 1.31.1 picomatch: 4.0.3 postcss: 8.4.49 resolve-from: 5.0.0 optionalDependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) transitivePeerDependencies: - bufferutil - supports-color @@ -5691,16 +5744,16 @@ snapshots: base64-js: 1.5.1 xmlbuilder: 15.1.1 - '@expo/prebuild-config@55.0.10(expo@55.0.8)(typescript@5.9.3)': + '@expo/prebuild-config@55.0.11(expo@55.0.9)(typescript@5.9.3)': dependencies: - '@expo/config': 55.0.10(typescript@5.9.3) + '@expo/config': 55.0.11(typescript@5.9.3) '@expo/config-plugins': 55.0.7 '@expo/config-types': 55.0.5 '@expo/image-utils': 0.8.12 '@expo/json-file': 10.0.12 - '@react-native/normalize-colors': 0.83.2 + '@react-native/normalize-colors': 0.83.4 debug: 4.4.3 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) resolve-from: 5.0.0 semver: 7.7.3 xml2js: 0.6.0 @@ -5718,17 +5771,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/router-server@55.0.11(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-constants@55.0.9)(expo-font@55.0.4)(expo-router@55.0.7)(expo-server@55.0.6)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@expo/router-server@55.0.11(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-constants@55.0.9)(expo-font@55.0.4)(expo-router@55.0.8)(expo-server@55.0.6)(expo@55.0.9)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: debug: 4.4.3 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-constants: 55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) - expo-font: 55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo-constants: 55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + expo-font: 55.0.4(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) expo-server: 55.0.6 react: 19.2.0 optionalDependencies: '@expo/metro-runtime': 5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) - expo-router: 55.0.7(7511b7cdea3486076770b15ac1f40957) + expo-router: 55.0.8(9db59377a3fbcf0eb63542ffa9ff8e3f) react-dom: 19.2.0(react@19.2.0) transitivePeerDependencies: - supports-color @@ -5745,7 +5798,7 @@ snapshots: '@expo/vector-icons@15.0.3(expo-font@55.0.4)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': dependencies: - expo-font: 55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-font: 55.0.4(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) @@ -6190,15 +6243,15 @@ snapshots: '@react-native/assets-registry@0.83.2': {} - '@react-native/babel-plugin-codegen@0.83.2(@babel/core@7.29.0)': + '@react-native/babel-plugin-codegen@0.83.4(@babel/core@7.29.0)': dependencies: '@babel/traverse': 7.29.0 - '@react-native/codegen': 0.83.2(@babel/core@7.29.0) + '@react-native/codegen': 0.83.4(@babel/core@7.29.0) transitivePeerDependencies: - '@babel/core' - supports-color - '@react-native/babel-preset@0.83.2(@babel/core@7.29.0)': + '@react-native/babel-preset@0.83.4(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.29.0) @@ -6241,7 +6294,7 @@ snapshots: '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) '@babel/template': 7.28.6 - '@react-native/babel-plugin-codegen': 0.83.2(@babel/core@7.29.0) + '@react-native/babel-plugin-codegen': 0.83.4(@babel/core@7.29.0) babel-plugin-syntax-hermes-parser: 0.32.0 babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.29.0) react-refresh: 0.14.2 @@ -6258,6 +6311,16 @@ snapshots: nullthrows: 1.1.1 yargs: 17.7.2 + '@react-native/codegen@0.83.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + glob: 7.2.3 + hermes-parser: 0.32.0 + invariant: 2.2.4 + nullthrows: 1.1.1 + yargs: 17.7.2 + '@react-native/community-cli-plugin@0.83.2': dependencies: '@react-native/dev-middleware': 0.83.2 @@ -6274,11 +6337,18 @@ snapshots: '@react-native/debugger-frontend@0.83.2': {} + '@react-native/debugger-frontend@0.83.4': {} + '@react-native/debugger-shell@0.83.2': dependencies: cross-spawn: 7.0.6 fb-dotslash: 0.5.8 + '@react-native/debugger-shell@0.83.4': + dependencies: + cross-spawn: 7.0.6 + fb-dotslash: 0.5.8 + '@react-native/dev-middleware@0.83.2': dependencies: '@isaacs/ttlcache': 1.4.1 @@ -6298,6 +6368,25 @@ snapshots: - supports-color - utf-8-validate + '@react-native/dev-middleware@0.83.4': + dependencies: + '@isaacs/ttlcache': 1.4.1 + '@react-native/debugger-frontend': 0.83.4 + '@react-native/debugger-shell': 0.83.4 + chrome-launcher: 0.15.2 + chromium-edge-launcher: 0.2.0 + connect: 3.7.0 + debug: 4.4.3 + invariant: 2.2.4 + nullthrows: 1.1.1 + open: 7.4.2 + serve-static: 1.16.3 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + '@react-native/gradle-plugin@0.83.2': {} '@react-native/js-polyfills@0.83.2': {} @@ -6306,6 +6395,8 @@ snapshots: '@react-native/normalize-colors@0.83.2': {} + '@react-native/normalize-colors@0.83.4': {} + '@react-native/virtualized-lists@0.83.2(@types/react@19.2.14)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': dependencies: invariant: 2.2.4 @@ -6882,7 +6973,7 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0) - babel-preset-expo@55.0.12(@babel/core@7.29.0)(@babel/runtime@7.28.6)(expo@55.0.8)(react-refresh@0.14.2): + babel-preset-expo@55.0.13(@babel/core@7.29.0)(@babel/runtime@7.28.6)(expo@55.0.9)(react-refresh@0.14.2): dependencies: '@babel/generator': 7.29.0 '@babel/helper-module-imports': 7.28.6 @@ -6900,7 +6991,7 @@ snapshots: '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) '@babel/preset-react': 7.28.5(@babel/core@7.29.0) '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) - '@react-native/babel-preset': 0.83.2(@babel/core@7.29.0) + '@react-native/babel-preset': 0.83.4(@babel/core@7.29.0) babel-plugin-react-compiler: 1.0.0 babel-plugin-react-native-web: 0.21.2 babel-plugin-syntax-hermes-parser: 0.32.1 @@ -6910,7 +7001,7 @@ snapshots: resolve-from: 5.0.0 optionalDependencies: '@babel/runtime': 7.28.6 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) transitivePeerDependencies: - '@babel/core' - supports-color @@ -7668,83 +7759,88 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - expo-apple-authentication@55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): + expo-apple-authentication@55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - expo-application@55.0.10(expo@55.0.8): + expo-application@55.0.10(expo@55.0.9): dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-asset@55.0.10(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + expo-asset@55.0.10(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): dependencies: '@expo/image-utils': 0.8.12 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-constants: 55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo-constants: 55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) transitivePeerDependencies: - supports-color - typescript - expo-build-properties@55.0.10(expo@55.0.8): + expo-brightness@55.0.13(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): + dependencies: + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + + expo-build-properties@55.0.10(expo@55.0.9): dependencies: '@expo/schema-utils': 55.0.2 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) resolve-from: 5.0.0 semver: 7.7.3 - expo-constants@55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3): + expo-constants@55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3): dependencies: '@expo/config': 55.0.10(typescript@5.9.3) '@expo/env': 2.1.1 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) transitivePeerDependencies: - supports-color - typescript - expo-device@55.0.10(expo@55.0.8): + expo-device@55.0.10(expo@55.0.9): dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) ua-parser-js: 0.7.41 - expo-file-system@55.0.11(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): + expo-file-system@55.0.12(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - expo-font@55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-font@55.0.4(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) fontfaceobserver: 2.3.0 react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - expo-glass-effect@55.0.8(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-glass-effect@55.0.8(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - expo-image@55.0.6(expo@55.0.8)(react-native-web@0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-image@55.0.6(expo@55.0.9)(react-native-web@0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) sf-symbols-typescript: 2.2.0 optionalDependencies: react-native-web: 0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - expo-keep-awake@55.0.4(expo@55.0.8)(react@19.2.0): + expo-keep-awake@55.0.4(expo@55.0.9)(react@19.2.0): dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react: 19.2.0 - expo-linking@55.0.8(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + expo-linking@55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): dependencies: - expo-constants: 55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + expo-constants: 55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) invariant: 2.2.4 react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) @@ -7753,7 +7849,7 @@ snapshots: - supports-color - typescript - expo-modules-autolinking@55.0.11(typescript@5.9.3): + expo-modules-autolinking@55.0.12(typescript@5.9.3): dependencies: '@expo/require-utils': 55.0.3(typescript@5.9.3) '@expo/spawn-async': 1.7.2 @@ -7763,29 +7859,29 @@ snapshots: - supports-color - typescript - expo-modules-core@55.0.17(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-modules-core@55.0.18(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): dependencies: invariant: 2.2.4 react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - expo-notifications@55.0.13(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + expo-notifications@55.0.14(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): dependencies: '@expo/image-utils': 0.8.12 abort-controller: 3.0.0 badgin: 1.2.3 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-application: 55.0.10(expo@55.0.8) - expo-constants: 55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo-application: 55.0.10(expo@55.0.9) + expo-constants: 55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) transitivePeerDependencies: - supports-color - typescript - expo-router@55.0.7(7511b7cdea3486076770b15ac1f40957): + expo-router@55.0.8(9db59377a3fbcf0eb63542ffa9ff8e3f): dependencies: - '@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/log-box': 55.0.8(@expo/dom-webview@55.0.3)(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) '@expo/metro-runtime': 5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) '@expo/schema-utils': 55.0.2 '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.0) @@ -7796,13 +7892,13 @@ snapshots: client-only: 0.0.1 debug: 4.4.3 escape-string-regexp: 4.0.0 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-constants: 55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) - expo-glass-effect: 55.0.8(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - expo-image: 55.0.6(expo@55.0.8)(react-native-web@0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - expo-linking: 55.0.8(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo-constants: 55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + expo-glass-effect: 55.0.8(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-image: 55.0.6(expo@55.0.9)(react-native-web@0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-linking: 55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) expo-server: 55.0.6 - expo-symbols: 55.0.5(expo-font@55.0.4)(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-symbols: 55.0.5(expo-font@55.0.4)(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) fast-deep-equal: 3.1.3 invariant: 2.2.4 nanoid: 3.3.11 @@ -7831,63 +7927,63 @@ snapshots: - expo-font - supports-color - expo-secure-store@55.0.9(expo@55.0.8): + expo-secure-store@55.0.9(expo@55.0.9): dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) expo-server@55.0.6: {} - expo-splash-screen@55.0.12(expo@55.0.8)(typescript@5.9.3): + expo-splash-screen@55.0.13(expo@55.0.9)(typescript@5.9.3): dependencies: - '@expo/prebuild-config': 55.0.10(expo@55.0.8)(typescript@5.9.3) - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + '@expo/prebuild-config': 55.0.11(expo@55.0.9)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) transitivePeerDependencies: - supports-color - typescript - expo-symbols@55.0.5(expo-font@55.0.4)(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-symbols@55.0.5(expo-font@55.0.4)(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): dependencies: '@expo-google-fonts/material-symbols': 0.4.27 - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-font: 55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo-font: 55.0.4(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) sf-symbols-typescript: 2.2.0 - expo-web-browser@55.0.10(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): + expo-web-browser@55.0.10(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): dependencies: - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - expo@55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + expo@55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): dependencies: '@babel/runtime': 7.28.6 - '@expo/cli': 55.0.18(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-constants@55.0.9)(expo-font@55.0.4)(expo-router@55.0.7)(expo@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - '@expo/config': 55.0.10(typescript@5.9.3) + '@expo/cli': 55.0.19(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-constants@55.0.9)(expo-font@55.0.4)(expo-router@55.0.8)(expo@55.0.9)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + '@expo/config': 55.0.11(typescript@5.9.3) '@expo/config-plugins': 55.0.7 '@expo/devtools': 55.0.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) '@expo/fingerprint': 0.16.6 '@expo/local-build-cache-provider': 55.0.7(typescript@5.9.3) - '@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/log-box': 55.0.8(@expo/dom-webview@55.0.3)(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) '@expo/metro': 54.2.0 - '@expo/metro-config': 55.0.11(expo@55.0.8)(typescript@5.9.3) + '@expo/metro-config': 55.0.11(expo@55.0.9)(typescript@5.9.3) '@expo/vector-icons': 15.0.3(expo-font@55.0.4)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) '@ungap/structured-clone': 1.3.0 - babel-preset-expo: 55.0.12(@babel/core@7.29.0)(@babel/runtime@7.28.6)(expo@55.0.8)(react-refresh@0.14.2) - expo-asset: 55.0.10(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-constants: 55.0.9(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) - expo-file-system: 55.0.11(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) - expo-font: 55.0.4(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - expo-keep-awake: 55.0.4(expo@55.0.8)(react@19.2.0) - expo-modules-autolinking: 55.0.11(typescript@5.9.3) - expo-modules-core: 55.0.17(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + babel-preset-expo: 55.0.13(@babel/core@7.29.0)(@babel/runtime@7.28.6)(expo@55.0.9)(react-refresh@0.14.2) + expo-asset: 55.0.10(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo-constants: 55.0.9(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + expo-file-system: 55.0.12(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) + expo-font: 55.0.4(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-keep-awake: 55.0.4(expo@55.0.9)(react@19.2.0) + expo-modules-autolinking: 55.0.12(typescript@5.9.3) + expo-modules-core: 55.0.18(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) pretty-format: 29.7.0 react: 19.2.0 react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) react-refresh: 0.14.2 whatwg-url-minimum: 0.1.1 optionalDependencies: - '@expo/dom-webview': 55.0.3(expo@55.0.8)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/dom-webview': 55.0.3(expo@55.0.9)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) '@expo/metro-runtime': 5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) react-native-webview: 13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) transitivePeerDependencies: @@ -8534,14 +8630,14 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 - jest-expo@55.0.11(@babel/core@7.29.0)(expo@55.0.8)(jest@29.7.0(@types/node@25.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + jest-expo@55.0.11(@babel/core@7.29.0)(expo@55.0.9)(jest@29.7.0(@types/node@25.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): dependencies: '@expo/config': 55.0.10(typescript@5.9.3) '@expo/json-file': 10.0.12 '@jest/create-cache-key-function': 29.7.0 '@jest/globals': 29.7.0 babel-jest: 29.7.0(@babel/core@7.29.0) - expo: 55.0.8(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.7)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.9(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@5.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)))(expo-router@55.0.8)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.16.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) jest-environment-jsdom: 29.7.0 jest-snapshot: 29.7.0 jest-watch-select-projects: 2.0.0 diff --git a/services/timerDisplayMode.ts b/services/timerDisplayMode.ts new file mode 100644 index 0000000..fce219e --- /dev/null +++ b/services/timerDisplayMode.ts @@ -0,0 +1,179 @@ +import { Platform } from 'react-native'; +import * as Brightness from 'expo-brightness'; +import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake'; + +const TIMER_KEEP_AWAKE_TAG = 'study-timer'; +const DIM_SCREEN_DELAY_MS = 10000; +const IOS_DIMMED_SCREEN_BRIGHTNESS = 0.35; +const ANDROID_DIMMED_SCREEN_BRIGHTNESS = 0.28; +const MIN_BRIGHTNESS = 0.05; +const IOS_MAX_BRIGHTNESS = 0.6; +const ANDROID_MAX_BRIGHTNESS = 0.5; + +interface TimerDisplayModeOptions { + brightnessLevel?: number; + dimScreen?: boolean; + keepAwake?: boolean; +} + +let isKeepAwakeActive = false; +let isScreenDimmed = false; +let savedIosBrightness: number | null = null; +let appliedBrightnessLevel: number | null = null; +let displayModeOperation: Promise = Promise.resolve(); +let dimScreenTimeout: ReturnType | null = null; + +function enqueueDisplayModeOperation(task: () => Promise): Promise { + displayModeOperation = displayModeOperation.then(task, task); + return displayModeOperation; +} + +function clearPendingDimScreen(): void { + if (dimScreenTimeout === null) return; + + clearTimeout(dimScreenTimeout); + dimScreenTimeout = null; +} + +function getTargetBrightness(brightnessLevel?: number): number { + const defaultBrightness = + Platform.OS === 'ios' ? IOS_DIMMED_SCREEN_BRIGHTNESS : ANDROID_DIMMED_SCREEN_BRIGHTNESS; + + if (brightnessLevel == null || Number.isNaN(brightnessLevel)) { + return defaultBrightness; + } + + if (Platform.OS === 'ios') { + return Math.min(IOS_MAX_BRIGHTNESS, Math.max(MIN_BRIGHTNESS, brightnessLevel)); + } + + return Math.min(ANDROID_MAX_BRIGHTNESS, Math.max(MIN_BRIGHTNESS, brightnessLevel)); +} + +async function setScreenBrightness(brightness: number): Promise { + const isBrightnessAvailable = await Brightness.isAvailableAsync(); + if (!isBrightnessAvailable) return false; + + await Brightness.setBrightnessAsync(brightness); + return true; +} + +async function activateKeepAwakeIfNeeded(): Promise { + if (isKeepAwakeActive) return; + + try { + await activateKeepAwakeAsync(TIMER_KEEP_AWAKE_TAG); + isKeepAwakeActive = true; + } catch (error) { + console.error('타이머 keep-awake 활성화 실패:', error); + } +} + +async function deactivateKeepAwakeIfNeeded(): Promise { + if (!isKeepAwakeActive) return; + + try { + await deactivateKeepAwake(TIMER_KEEP_AWAKE_TAG); + isKeepAwakeActive = false; + } catch (error) { + console.error('타이머 keep-awake 비활성화 실패:', error); + } +} + +async function dimScreenIfNeeded(dimScreen: boolean, brightnessLevel?: number): Promise { + if (!dimScreen) return; + + const targetBrightness = getTargetBrightness(brightnessLevel); + if (isScreenDimmed && appliedBrightnessLevel === targetBrightness) return; + + try { + if (Platform.OS === 'android') { + const isBrightnessApplied = await setScreenBrightness(targetBrightness); + if (!isBrightnessApplied) return; + + isScreenDimmed = true; + appliedBrightnessLevel = targetBrightness; + return; + } + + if (Platform.OS === 'ios') { + const isBrightnessAvailable = await Brightness.isAvailableAsync(); + if (!isBrightnessAvailable) return; + + const currentBrightness = savedIosBrightness ?? (await Brightness.getBrightnessAsync()); + await Brightness.setBrightnessAsync(targetBrightness); + savedIosBrightness = currentBrightness; + isScreenDimmed = true; + appliedBrightnessLevel = targetBrightness; + } + } catch (error) { + console.error('타이머 화면 밝기 조절 실패:', error); + } +} + +async function restoreScreenBrightness(): Promise { + clearPendingDimScreen(); + + if (!isScreenDimmed) return; + + try { + if (Platform.OS === 'android') { + await Brightness.restoreSystemBrightnessAsync(); + return; + } + + if (Platform.OS === 'ios' && savedIosBrightness !== null) { + await setScreenBrightness(savedIosBrightness); + } + } catch (error) { + console.error('타이머 화면 밝기 복원 실패:', error); + } finally { + isScreenDimmed = false; + savedIosBrightness = null; + appliedBrightnessLevel = null; + } +} + +function scheduleScreenDim(brightnessLevel?: number): void { + clearPendingDimScreen(); + + dimScreenTimeout = setTimeout(() => { + dimScreenTimeout = null; + void enqueueDisplayModeOperation(async () => { + await dimScreenIfNeeded(true, brightnessLevel); + }); + }, DIM_SCREEN_DELAY_MS); +} + +export async function enableTimerDisplayMode({ + brightnessLevel, + keepAwake = true, + dimScreen = true, +}: TimerDisplayModeOptions = {}): Promise { + return enqueueDisplayModeOperation(async () => { + if (keepAwake) { + await activateKeepAwakeIfNeeded(); + } else { + await deactivateKeepAwakeIfNeeded(); + } + + if (!dimScreen) { + await restoreScreenBrightness(); + return; + } + + if (isScreenDimmed) { + await dimScreenIfNeeded(true, brightnessLevel); + return; + } + + scheduleScreenDim(brightnessLevel); + }); +} + +export async function disableTimerDisplayMode(): Promise { + return enqueueDisplayModeOperation(async () => { + await restoreScreenBrightness(); + await deactivateKeepAwakeIfNeeded(); + }); +}