diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..bb825cc
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,12 @@
+# 웹뷰로 띄울 stream-client-web 주소.
+# 이 파일을 .env.local로 복사한 뒤 값을 자기 환경에 맞게 채운다.
+#
+# 실행 환경마다 주소가 다르다 (docs/local-development.md 참고):
+# - iOS 시뮬레이터 http://localhost:5173
+# - Android 에뮬레이터 http://10.0.2.2:5173
+# - 실제 기기 http://{개발 PC의 LAN IP}:5173
+#
+# LAN IP 확인: ipconfig getifaddr en0
+# 실제 기기는 PC와 같은 네트워크에 있어야 하고, 웹도 pnpm dev --host로 띄워야 한다.
+# 배포 후에는 운영 URL로 바꾼다.
+EXPO_PUBLIC_WEB_URL=http://192.168.0.2:5173
diff --git a/README.md b/README.md
index 64640ce..23618d9 100644
--- a/README.md
+++ b/README.md
@@ -1,57 +1,61 @@
-# Welcome to your Expo app 👋
-
-This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app).
-
-## Get started
-
-1. Install dependencies
-
- ```bash
- npm install
- ```
+# stream-client-app
-2. Start the app
+국민대학교 소프트웨어융합대학 통합 플랫폼 'STREAM' 앱 (Expo + React Native + TypeScript).
- ```bash
- npx expo start
- ```
+화면 UI는 [stream-client-web](https://github.com/billilge/stream-client-web)이 전담한다. 이 저장소는 그 웹을 WebView로 띄우는 **네이티브 셸**이다. 앞으로 푸시 알림, 토큰 저장처럼 웹이 할 수 없는 기능을 네이티브에서 맡는다.
-In the output, you'll find options to open the app in a
+## 개발 환경
-- [development build](https://docs.expo.dev/develop/development-builds/introduction/)
-- [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/)
-- [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/)
-- [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo
+- Node: `.nvmrc` 참고 (`nvm use`)
+- 패키지 매니저: [pnpm](https://pnpm.io/) — Corepack으로 관리한다 (`corepack enable` 후 `pnpm install`만 실행하면 `packageManager` 필드에 고정된 버전이 자동으로 쓰인다)
-You can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction).
+```bash
+corepack enable
+pnpm install
+cp .env.example .env.local # 웹 주소를 실행 환경에 맞게 채운다
+pnpm start
+```
-## Get a fresh project
+### 웹 주소 설정
-When you're ready, run:
+WebView가 띄울 주소는 `.env.local`의 `EXPO_PUBLIC_WEB_URL`로 주입한다. 이 파일은 git에 올리지 않는다.
-```bash
-npm run reset-project
-```
+**실행 환경마다 가리켜야 하는 주소가 다르다.**
-This command will move the starter code to the **app-example** directory and create a blank **app** directory where you can start developing.
+| 실행 환경 | 웹 주소 |
+| --- | --- |
+| iOS 시뮬레이터 | `http://localhost:5173` |
+| Android 에뮬레이터 | `http://10.0.2.2:5173` |
+| 실제 기기 (Expo Go) | `http://{개발 PC의 LAN IP}:5173` |
-### Other setup steps
+실제 기기에서는 `localhost`가 기기 자신을 가리켜 개발 PC에 닿지 않으므로 LAN IP를 써야 하고, 웹도 `pnpm dev --host`로 띄워야 한다.
-- To set up ESLint for linting, run `npx expo lint`, or follow our guide on ["Using ESLint and Prettier"](https://docs.expo.dev/guides/using-eslint/)
-- If you'd like to set up unit testing, follow our guide on ["Unit Testing with Jest"](https://docs.expo.dev/develop/unit-testing/)
-- Learn more about the TypeScript setup in this template in our guide on ["Using TypeScript"](https://docs.expo.dev/guides/typescript/)
+자세한 실행 방법·준비물·트러블슈팅은 **[docs/local-development.md](docs/local-development.md)** 참고.
-## Learn more
+## 스크립트
-To learn more about developing your project with Expo, look at the following resources:
+| 명령 | 설명 |
+| --- | --- |
+| `pnpm start` | Expo 개발 서버 실행 |
+| `pnpm ios` | iOS 시뮬레이터에서 실행 |
+| `pnpm android` | Android 에뮬레이터에서 실행 |
+| `pnpm web` | 웹에서 실행 |
+| `pnpm lint` | Biome lint |
+| `pnpm format` | Biome로 포맷 적용 |
+| `pnpm check` | Biome lint + format 검증 |
-- [Expo documentation](https://docs.expo.dev/): Learn fundamentals, or go into advanced topics with our [guides](https://docs.expo.dev/guides).
-- [Learn Expo tutorial](https://docs.expo.dev/tutorial/introduction/): Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web.
+## 구조
-## Join the community
+```
+src/
+├─ app/ expo-router 라우팅 껍데기
+├─ features/webview/ WebView 셸 화면
+├─ constants/ 설정 상수
+└─ utils/ 공용 유틸
+```
-Join our community of developers creating universal apps.
+## 문서
-- [Expo on GitHub](https://github.com/expo/expo): View our open source platform and contribute.
-- [Discord community](https://chat.expo.dev): Chat with Expo users and ask questions.
-# stream-client-app
+- [로컬 실행 가이드](docs/local-development.md)
+- [코딩 컨벤션](docs/conventions/coding-style.md)
+- [Git 컨벤션](docs/conventions/git-convention.md)
diff --git a/assets/images/expo-badge-white.png b/assets/images/expo-badge-white.png
deleted file mode 100644
index 2863067..0000000
Binary files a/assets/images/expo-badge-white.png and /dev/null differ
diff --git a/assets/images/expo-badge.png b/assets/images/expo-badge.png
deleted file mode 100644
index 5d5c5bb..0000000
Binary files a/assets/images/expo-badge.png and /dev/null differ
diff --git a/assets/images/expo-logo.png b/assets/images/expo-logo.png
deleted file mode 100644
index 6b1642a..0000000
Binary files a/assets/images/expo-logo.png and /dev/null differ
diff --git a/assets/images/logo-glow.png b/assets/images/logo-glow.png
deleted file mode 100644
index edc99be..0000000
Binary files a/assets/images/logo-glow.png and /dev/null differ
diff --git a/assets/images/react-logo.png b/assets/images/react-logo.png
deleted file mode 100644
index 9d72a9f..0000000
Binary files a/assets/images/react-logo.png and /dev/null differ
diff --git a/assets/images/react-logo@2x.png b/assets/images/react-logo@2x.png
deleted file mode 100644
index 2229b13..0000000
Binary files a/assets/images/react-logo@2x.png and /dev/null differ
diff --git a/assets/images/react-logo@3x.png b/assets/images/react-logo@3x.png
deleted file mode 100644
index a99b203..0000000
Binary files a/assets/images/react-logo@3x.png and /dev/null differ
diff --git a/assets/images/tabIcons/explore.png b/assets/images/tabIcons/explore.png
deleted file mode 100644
index 73d8258..0000000
Binary files a/assets/images/tabIcons/explore.png and /dev/null differ
diff --git a/assets/images/tabIcons/explore@2x.png b/assets/images/tabIcons/explore@2x.png
deleted file mode 100644
index 21b9bd2..0000000
Binary files a/assets/images/tabIcons/explore@2x.png and /dev/null differ
diff --git a/assets/images/tabIcons/explore@3x.png b/assets/images/tabIcons/explore@3x.png
deleted file mode 100644
index 422202d..0000000
Binary files a/assets/images/tabIcons/explore@3x.png and /dev/null differ
diff --git a/assets/images/tabIcons/home.png b/assets/images/tabIcons/home.png
deleted file mode 100644
index ad5699c..0000000
Binary files a/assets/images/tabIcons/home.png and /dev/null differ
diff --git a/assets/images/tabIcons/home@2x.png b/assets/images/tabIcons/home@2x.png
deleted file mode 100644
index 22a1f2c..0000000
Binary files a/assets/images/tabIcons/home@2x.png and /dev/null differ
diff --git a/assets/images/tabIcons/home@3x.png b/assets/images/tabIcons/home@3x.png
deleted file mode 100644
index f5d1f9a..0000000
Binary files a/assets/images/tabIcons/home@3x.png and /dev/null differ
diff --git a/assets/images/tutorial-web.png b/assets/images/tutorial-web.png
deleted file mode 100644
index e4a8c58..0000000
Binary files a/assets/images/tutorial-web.png and /dev/null differ
diff --git a/docs/local-development.md b/docs/local-development.md
new file mode 100644
index 0000000..5bafd17
--- /dev/null
+++ b/docs/local-development.md
@@ -0,0 +1,122 @@
+# 로컬 실행 가이드
+
+> 이 앱은 `stream-client-web`을 WebView로 띄우는 셸이다. 따라서 **웹 서버와 앱을 함께 띄워야** 화면이 보인다.
+
+---
+
+## 1. 준비
+
+```bash
+corepack enable
+pnpm install
+cp .env.example .env.local
+```
+
+`.env.local`의 `EXPO_PUBLIC_WEB_URL`에 웹 주소를 넣는다. **실행 환경마다 주소가 다르다** — 아래 표 참고.
+
+| 실행 환경 | 웹 주소 | 비고 |
+| --- | --- | --- |
+| iOS 시뮬레이터 | `http://localhost:5173` | 시뮬레이터가 맥의 네트워크를 그대로 쓴다 |
+| Android 에뮬레이터 | `http://10.0.2.2:5173` | `10.0.2.2`가 호스트 PC의 `localhost`에 매핑된다 |
+| 실제 기기 (Expo Go) | `http://{개발 PC의 LAN IP}:5173` | 기기와 PC가 같은 네트워크에 있어야 한다 |
+
+LAN IP 확인:
+
+```bash
+ipconfig getifaddr en0 # 유선이면 en1 등 다른 인터페이스일 수 있다
+```
+
+## 2. 웹 서버 띄우기
+
+별도 터미널에서 `stream-client-web`을 실행한다.
+
+```bash
+cd ../stream-client-web
+pnpm dev
+```
+
+**실제 기기로 볼 때는 `--host`가 필요하다.** Vite dev 서버는 기본적으로 `localhost`에만 바인딩해서 다른 기기에서 닿지 않는다.
+
+```bash
+pnpm dev --host
+```
+
+## 3. 앱 실행
+
+```bash
+pnpm start # QR 코드가 뜬다
+pnpm ios # iOS 시뮬레이터로 바로 실행
+pnpm android # Android 에뮬레이터로 바로 실행
+pnpm web # 브라우저에서 실행
+```
+
+`.env.local`을 고쳤으면 **Expo 개발 서버를 재시작해야 반영된다.** `EXPO_PUBLIC_*` 값은 번들 시점에 주입되기 때문이다.
+
+---
+
+## 실행 환경별 준비물
+
+### 실제 기기 (권장 — 준비물이 가장 적다)
+
+기기에 **Expo Go** 앱만 설치하면 된다 (App Store / Play Store). `react-native-webview`는 Expo Go에 포함되어 있어 별도 네이티브 빌드가 필요 없다.
+
+1. `pnpm start`
+2. 터미널의 QR 코드를 스캔 — iOS는 기본 카메라 앱, Android는 Expo Go 앱 안에서
+3. 기기와 PC가 같은 와이파이에 있어야 한다
+
+### iOS 시뮬레이터
+
+**Xcode가 필요하다** (App Store에서 설치, 용량이 크고 시간이 오래 걸린다). Command Line Tools만으로는 시뮬레이터가 없다.
+
+```bash
+xcode-select -p # /Applications/Xcode.app/... 이 나와야 한다
+xcrun simctl list devices available # 사용 가능한 시뮬레이터 목록
+pnpm ios
+```
+
+`xcode-select -p`가 `/Library/Developer/CommandLineTools`를 가리키면 Xcode 설치 후 아래를 실행한다.
+
+```bash
+sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
+```
+
+### Android 에뮬레이터
+
+**Android Studio가 필요하다.** 설치 후 Device Manager에서 가상 기기(AVD)를 하나 만든다.
+
+```bash
+emulator -list-avds # 만든 AVD 목록
+pnpm android
+```
+
+### 웹 (`pnpm web`)
+
+브라우저에서 `react-native-web`으로 렌더링된다. 화면 확인용으로는 쓸 수 있지만 **하드웨어 백 버튼, 외부 링크 처리 같은 네이티브 동작은 검증되지 않는다.** 최종 확인은 기기나 시뮬레이터에서 한다.
+
+---
+
+## 확인할 것
+
+셸이 제대로 동작하는지 보려면 아래를 확인한다.
+
+- [ ] 웹 화면이 뜨는가
+- [ ] 로드 중 스피너가 보이고, 로드되면 사라지는가
+- [ ] Bottom Nav로 화면을 옮긴 뒤 **Android 하드웨어 백 버튼**이 앱 종료가 아니라 웹 뒤로 가기로 동작하는가 (Android 전용)
+- [ ] 네트워크를 끊고 앱을 다시 열면 오류 화면과 `다시 시도` 버튼이 뜨는가
+- [ ] 외부 도메인 링크가 웹뷰 안이 아니라 시스템 브라우저로 열리는가
+
+> 현재 웹의 `ScreenLayout`이 `375x812` 고정 프레임이라 화면이 꽉 차지 않고 가운데 정렬된 채 여백이 생긴다. 알려진 사항이며 web 레포에서 별도로 대응한다.
+
+---
+
+## 잘 안 될 때
+
+| 증상 | 원인 / 해결 |
+| --- | --- |
+| "웹 주소가 설정되지 않았습니다" 화면 | `.env.local`에 `EXPO_PUBLIC_WEB_URL`이 없다. 채운 뒤 Expo 서버를 **재시작**한다 |
+| "페이지를 불러오지 못했습니다" 화면 | 웹 dev 서버가 꺼져 있거나, 주소가 실행 환경과 맞지 않는다(위 표 확인) |
+| 실제 기기에서만 안 닿는다 | 웹을 `pnpm dev --host`로 띄웠는지, 기기와 PC가 같은 네트워크인지, 맥 방화벽이 막고 있지 않은지 확인 |
+| `.env.local`을 고쳤는데 그대로다 | `EXPO_PUBLIC_*`은 번들 시점에 주입된다. Expo 개발 서버를 재시작한다 |
+| LAN IP가 자꾸 바뀐다 | 공유기가 DHCP로 새 IP를 준 것이다. `ipconfig getifaddr en0`로 다시 확인해 `.env.local`을 갱신한다 |
+
+> 로컬 `http://` 접속은 Expo Go에서 동작한다. 나중에 자체 개발 빌드(EAS)로 넘어가면 iOS ATS 예외 설정이 필요할 수 있다.
diff --git a/package.json b/package.json
index 7d8a227..0e08f3f 100644
--- a/package.json
+++ b/package.json
@@ -3,18 +3,12 @@
"main": "expo-router/entry",
"version": "1.0.0",
"dependencies": {
- "@expo/ui": "~57.0.15",
"expo": "~57.0.19",
"expo-constants": "~57.0.17",
- "expo-device": "~57.0.1",
- "expo-font": "~57.0.3",
- "expo-glass-effect": "~57.0.1",
- "expo-image": "~57.0.4",
"expo-linking": "~57.0.9",
"expo-router": "~57.0.18",
"expo-splash-screen": "~57.0.8",
"expo-status-bar": "~57.0.1",
- "expo-symbols": "~57.0.2",
"expo-system-ui": "~57.0.3",
"expo-web-browser": "~57.0.2",
"react": "19.2.3",
@@ -26,6 +20,7 @@
"react-native-safe-area-context": "~5.7.0",
"react-native-screens": "~4.26.0",
"react-native-web": "~0.21.0",
+ "react-native-webview": "13.16.1",
"react-native-worklets": "0.10.1"
},
"devDependencies": {
@@ -37,7 +32,6 @@
},
"scripts": {
"start": "expo start",
- "reset-project": "node ./scripts/reset-project.js",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d2bfe97..efb66cb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,27 +8,12 @@ importers:
.:
dependencies:
- '@expo/ui':
- specifier: ~57.0.15
- version: 57.0.15(@babel/core@7.29.7(supports-color@8.1.1))(@types/react@19.2.18)(expo@57.0.19)(react-dom@19.2.3(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
expo:
specifier: ~57.0.19
- version: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ version: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
expo-constants:
specifier: ~57.0.17
version: 57.0.17(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(supports-color@8.1.1)
- expo-device:
- specifier: ~57.0.1
- version: 57.0.1(expo@57.0.19)
- expo-font:
- specifier: ~57.0.3
- version: 57.0.3(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
- expo-glass-effect:
- specifier: ~57.0.1
- version: 57.0.1(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
- expo-image:
- specifier: ~57.0.4
- version: 57.0.4(expo@57.0.19)(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
expo-linking:
specifier: ~57.0.9
version: 57.0.9(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)
@@ -41,9 +26,6 @@ importers:
expo-status-bar:
specifier: ~57.0.1
version: 57.0.1(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
- expo-symbols:
- specifier: ~57.0.2
- version: 57.0.2(expo-font@57.0.3)(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
expo-system-ui:
specifier: ~57.0.3
version: 57.0.3(expo@57.0.19)(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(supports-color@8.1.1)
@@ -77,6 +59,9 @@ importers:
react-native-web:
specifier: ~0.21.0
version: 0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react-native-webview:
+ specifier: 13.16.1
+ version: 13.16.1(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
react-native-worklets:
specifier: 0.10.1
version: 0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)
@@ -1567,11 +1552,6 @@ packages:
expo: '*'
react-native: '*'
- expo-device@57.0.1:
- resolution: {integrity: sha512-jyEMDUticH+dhcL3GHa2aiifOvGXJsmb3oVT2R2q4i8bN7Bddy61+NkpMmuS2VAZrvoLQwf0TJJ/1vi1ukvutA==}
- peerDependencies:
- expo: '*'
-
expo-file-system@57.0.6:
resolution: {integrity: sha512-pm8PMYEW6BnVOCBJ7df9FcDmQtE1tqImuYphlfYe1ipQRLYtdCayRczJcbKIsnB3mqEyp4gC2gWmMbsAsAOjVg==}
peerDependencies:
@@ -1592,17 +1572,6 @@ packages:
react: '*'
react-native: '*'
- expo-image@57.0.4:
- resolution: {integrity: sha512-DLVNjqIMLb71wh0F27kRv7nA9i4g80fvkVugiimVgGnO7Iot+gRSv5VhrFJCvX/OlSzbGQqd/3ktlEaPGFqP7g==}
- peerDependencies:
- expo: '*'
- react: '*'
- react-native: '*'
- react-native-web: '*'
- peerDependenciesMeta:
- react-native-web:
- optional: true
-
expo-keep-awake@57.0.1:
resolution: {integrity: sha512-28lkFImeXTS+bhAjuCFV7w7tW5bXg27BJVrxv+nC/nyYa86qEa0oFeHwqol6ha5k4pdVDQgBF09GM4A1k76Ssg==}
peerDependencies:
@@ -2593,6 +2562,12 @@ packages:
react: ^18.0.0 || ^19.0.0
react-dom: ^18.0.0 || ^19.0.0
+ react-native-webview@13.16.1:
+ resolution: {integrity: sha512-If0eHhoEdOYDcHsX+xBFwHMbWBGK1BvGDQDQdVkwtSIXiq1uiqjkpWVP2uQ1as94J0CzvFE9PUNDuhiX0Z6ubw==}
+ peerDependencies:
+ react: '*'
+ react-native: '*'
+
react-native-worklets@0.10.1:
resolution: {integrity: sha512-62mRM19bDpfpdI8HLkEErcdOsrAPDtE9lA/sw+5lLRpzBHNhxaoj9QyY2KjXqUmirelxkX4zuPGTC3VdA0feJA==}
peerDependencies:
@@ -2940,10 +2915,6 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
- ua-parser-js@0.7.41:
- resolution: {integrity: sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==}
- hasBin: true
-
ua-parser-js@1.0.41:
resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==}
hasBin: true
@@ -3689,7 +3660,7 @@ snapshots:
connect: 3.7.0(supports-color@8.1.1)
debug: 4.4.3(supports-color@8.1.1)
dnssd-advertise: 1.1.6
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
expo-server: 57.0.3
fetch-nodeshim: 0.4.10
getenv: 2.0.0
@@ -3788,7 +3759,7 @@ snapshots:
'@expo/dom-webview@57.0.1(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)':
dependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
react: 19.2.3
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
@@ -3855,7 +3826,7 @@ snapshots:
dependencies:
'@expo/dom-webview': 57.0.1(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
anser: 1.4.10
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
react: 19.2.3
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
stacktrace-parser: 0.1.11
@@ -3886,7 +3857,7 @@ snapshots:
postcss: 8.5.26
resolve-from: 5.0.0
optionalDependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
transitivePeerDependencies:
- bufferutil
- supports-color
@@ -3908,7 +3879,7 @@ snapshots:
dependencies:
'@expo/log-box': 57.0.4(@expo/dom-webview@57.0.1)(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
anser: 1.4.10
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
pretty-format: 29.7.0
react: 19.2.3
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
@@ -3986,7 +3957,7 @@ snapshots:
'@expo/router-server@57.0.9(@expo/metro-runtime@57.0.15)(expo-constants@57.0.17)(expo-font@57.0.3)(expo-router@57.0.18)(expo-server@57.0.3)(expo@57.0.19)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@8.1.1)':
dependencies:
debug: 4.4.3(supports-color@8.1.1)
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
expo-constants: 57.0.17(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(supports-color@8.1.1)
expo-font: 57.0.3(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
expo-server: 57.0.3
@@ -4010,7 +3981,7 @@ snapshots:
'@expo/ui@57.0.15(@babel/core@7.29.7(supports-color@8.1.1))(@types/react@19.2.18)(expo@57.0.19)(react-dom@19.2.3(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)':
dependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
react: 19.2.3
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
sf-symbols-typescript: 2.2.0
@@ -4605,7 +4576,7 @@ snapshots:
react-refresh: 0.14.2
optionalDependencies:
'@babel/runtime': 7.29.7
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
transitivePeerDependencies:
- '@babel/core'
- supports-color
@@ -4887,7 +4858,7 @@ snapshots:
expo-asset@57.0.16(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3):
dependencies:
'@expo/image-utils': 0.11.5(supports-color@8.1.1)(typescript@6.0.3)
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
expo-constants: 57.0.17(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(supports-color@8.1.1)
react: 19.2.3
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
@@ -4898,46 +4869,32 @@ snapshots:
expo-constants@57.0.17(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(supports-color@8.1.1):
dependencies:
'@expo/env': 2.4.3(supports-color@8.1.1)
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
- expo-device@57.0.1(expo@57.0.19):
- dependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
- ua-parser-js: 0.7.41
-
expo-file-system@57.0.6(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)):
dependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
expo-font@57.0.3(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3):
dependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
fontfaceobserver: 2.3.0
react: 19.2.3
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
expo-glass-effect@57.0.1(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3):
dependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
- react: 19.2.3
- react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
-
- expo-image@57.0.4(expo@57.0.19)(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3):
- dependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
react: 19.2.3
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
- sf-symbols-typescript: 2.2.0
- optionalDependencies:
- react-native-web: 0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
expo-keep-awake@57.0.1(expo@57.0.19)(react@19.2.3):
dependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
react: 19.2.3
expo-linking@57.0.9(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1):
@@ -4987,7 +4944,7 @@ snapshots:
color: 4.2.3
debug: 4.4.3(supports-color@8.1.1)
escape-string-regexp: 4.0.0
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
expo-constants: 57.0.17(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(supports-color@8.1.1)
expo-glass-effect: 57.0.1(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
expo-linking: 57.0.9(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)
@@ -5028,7 +4985,7 @@ snapshots:
dependencies:
'@expo/config-plugins': 57.0.9(supports-color@8.1.1)(typescript@6.0.3)
'@expo/image-utils': 0.11.5(supports-color@8.1.1)(typescript@6.0.3)
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
xml2js: 0.6.0
transitivePeerDependencies:
- supports-color
@@ -5036,14 +4993,14 @@ snapshots:
expo-status-bar@57.0.1(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3):
dependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
react: 19.2.3
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
expo-symbols@57.0.2(expo-font@57.0.3)(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3):
dependencies:
'@expo-google-fonts/material-symbols': 0.4.45
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
expo-font: 57.0.3(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
react: 19.2.3
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
@@ -5053,7 +5010,7 @@ snapshots:
dependencies:
'@react-native/normalize-colors': 0.86.3
debug: 4.4.3(supports-color@8.1.1)
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
optionalDependencies:
react-native-web: 0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -5062,10 +5019,10 @@ snapshots:
expo-web-browser@57.0.2(expo@57.0.19)(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)):
dependencies:
- expo: 57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
+ expo: 57.0.19(2b41da233386ad1d2b715aba6998b7ec)
react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
- expo@57.0.19(@babel/core@7.29.7(supports-color@8.1.1))(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-router@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3):
+ expo@57.0.19(2b41da233386ad1d2b715aba6998b7ec):
dependencies:
'@babel/runtime': 7.29.7
'@expo/cli': 57.0.21(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.15)(expo-constants@57.0.17)(expo-font@57.0.3)(expo-router@57.0.18)(expo@57.0.19)(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1)(typescript@6.0.3)
@@ -5096,6 +5053,7 @@ snapshots:
'@expo/metro-runtime': 57.0.15(@expo/log-box@57.0.4)(expo@57.0.19)(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
react-dom: 19.2.3(react@19.2.3)
react-native-web: 0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react-native-webview: 13.16.1(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
transitivePeerDependencies:
- '@babel/core'
- bufferutil
@@ -5981,6 +5939,13 @@ snapshots:
transitivePeerDependencies:
- encoding
+ react-native-webview@13.16.1(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3):
+ dependencies:
+ escape-string-regexp: 4.0.0
+ invariant: 2.2.4
+ react: 19.2.3
+ react-native: 0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
+
react-native-worklets@0.10.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(react-native@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.86.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1):
dependencies:
'@babel/core': 7.29.7(supports-color@8.1.1)
@@ -6359,8 +6324,6 @@ snapshots:
typescript@6.0.3: {}
- ua-parser-js@0.7.41: {}
-
ua-parser-js@1.0.41: {}
undici-types@8.3.0: {}
diff --git a/scripts/reset-project.js b/scripts/reset-project.js
deleted file mode 100644
index 16a975c..0000000
--- a/scripts/reset-project.js
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * This script is used to reset the project to a blank state.
- * It deletes or moves the /src and /scripts directories to /example based on user input and creates a new /src/app directory with an index.tsx and _layout.tsx file.
- * You can remove the `reset-project` script from package.json and safely delete this file after running it.
- */
-
-const fs = require("fs");
-const path = require("path");
-const readline = require("readline");
-
-const root = process.cwd();
-const oldDirs = ["src", "scripts"];
-const exampleDir = "example";
-const newAppDir = "src/app";
-const exampleDirPath = path.join(root, exampleDir);
-
-const indexContent = `import { Text, View, StyleSheet } from "react-native";
-
-export default function Index() {
- return (
-
- Edit src/app/index.tsx to edit this screen.
-
- );
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- alignItems: "center",
- justifyContent: "center",
- },
-});
-`;
-
-const layoutContent = `import { Stack } from "expo-router";
-
-export default function RootLayout() {
- return ;
-}
-`;
-
-const rl = readline.createInterface({
- input: process.stdin,
- output: process.stdout,
-});
-
-const moveDirectories = async (userInput) => {
- try {
- if (userInput === "y") {
- // Create the app-example directory
- await fs.promises.mkdir(exampleDirPath, { recursive: true });
- console.log(`📁 /${exampleDir} directory created.`);
- }
-
- // Move old directories to new app-example directory or delete them
- for (const dir of oldDirs) {
- const oldDirPath = path.join(root, dir);
- if (fs.existsSync(oldDirPath)) {
- if (userInput === "y") {
- const newDirPath = path.join(root, exampleDir, dir);
- await fs.promises.rename(oldDirPath, newDirPath);
- console.log(`➡️ /${dir} moved to /${exampleDir}/${dir}.`);
- } else {
- await fs.promises.rm(oldDirPath, { recursive: true, force: true });
- console.log(`❌ /${dir} deleted.`);
- }
- } else {
- console.log(`➡️ /${dir} does not exist, skipping.`);
- }
- }
-
- // Create new /src/app directory
- const newAppDirPath = path.join(root, newAppDir);
- await fs.promises.mkdir(newAppDirPath, { recursive: true });
- console.log("\n📁 New /src/app directory created.");
-
- // Create index.tsx
- const indexPath = path.join(newAppDirPath, "index.tsx");
- await fs.promises.writeFile(indexPath, indexContent);
- console.log("📄 src/app/index.tsx created.");
-
- // Create _layout.tsx
- const layoutPath = path.join(newAppDirPath, "_layout.tsx");
- await fs.promises.writeFile(layoutPath, layoutContent);
- console.log("📄 src/app/_layout.tsx created.");
-
- console.log("\n✅ Project reset complete. Next steps:");
- console.log(
- `1. Run \`npx expo start\` to start a development server.\n2. Edit src/app/index.tsx to edit the main screen.\n3. Put all your application code in /src, only screens and layout files should be in /src/app.${
- userInput === "y"
- ? `\n4. Delete the /${exampleDir} directory when you're done referencing it.`
- : ""
- }`,
- );
- } catch (error) {
- console.error(`❌ Error during script execution: ${error.message}`);
- }
-};
-
-rl.question(
- "Do you want to move existing files to /example instead of deleting them? (Y/n): ",
- (answer) => {
- const userInput = answer.trim().toLowerCase() || "y";
- if (userInput === "y" || userInput === "n") {
- moveDirectories(userInput).finally(() => rl.close());
- } else {
- console.log("❌ Invalid input. Please enter 'Y' or 'N'.");
- rl.close();
- }
- },
-);
diff --git a/src/app/_layout.tsx b/src/app/_layout.tsx
index ec17660..c01a945 100644
--- a/src/app/_layout.tsx
+++ b/src/app/_layout.tsx
@@ -1,18 +1,14 @@
-import { DarkTheme, DefaultTheme, ThemeProvider } from "expo-router";
-import * as SplashScreen from "expo-splash-screen";
-import { useColorScheme } from "react-native";
+import "@/global.css";
-import { AnimatedSplashOverlay } from "@/components/animated-icon";
-import AppTabs from "@/components/app-tabs";
+import { Stack } from "expo-router";
+import { StatusBar } from "expo-status-bar";
+import { SafeAreaProvider } from "react-native-safe-area-context";
-SplashScreen.preventAutoHideAsync();
-
-export default function TabLayout() {
- const colorScheme = useColorScheme();
+export default function RootLayout() {
return (
-
-
-
-
+
+
+
+
);
}
diff --git a/src/app/explore.tsx b/src/app/explore.tsx
deleted file mode 100644
index 05f284c..0000000
--- a/src/app/explore.tsx
+++ /dev/null
@@ -1,181 +0,0 @@
-import { Image } from "expo-image";
-import { SymbolView } from "expo-symbols";
-import { Platform, Pressable, ScrollView, StyleSheet } from "react-native";
-import { useSafeAreaInsets } from "react-native-safe-area-context";
-
-import { ExternalLink } from "@/components/external-link";
-import { ThemedText } from "@/components/themed-text";
-import { ThemedView } from "@/components/themed-view";
-import { Collapsible } from "@/components/ui/collapsible";
-import { WebBadge } from "@/components/web-badge";
-import { BottomTabInset, MaxContentWidth, Spacing } from "@/constants/theme";
-import { useTheme } from "@/hooks/use-theme";
-
-export default function TabTwoScreen() {
- const safeAreaInsets = useSafeAreaInsets();
- const insets = {
- ...safeAreaInsets,
- bottom: safeAreaInsets.bottom + BottomTabInset + Spacing.three,
- };
- const theme = useTheme();
-
- const contentPlatformStyle = Platform.select({
- android: {
- paddingTop: insets.top,
- paddingLeft: insets.left,
- paddingRight: insets.right,
- paddingBottom: insets.bottom,
- },
- web: {
- paddingTop: Spacing.six,
- paddingBottom: Spacing.four,
- },
- });
-
- return (
-
-
-
- Explore
-
- This starter app includes example{"\n"}code to help you get started.
-
-
-
- pressed && styles.pressed}>
-
- Expo documentation
-
-
-
-
-
-
-
-
-
- This app has two screens: src/app/index.tsx and{" "}
- src/app/explore.tsx
-
-
- The layout file in src/app/_layout.tsx sets up
- the tab navigator.
-
-
- Learn more
-
-
-
-
-
-
- You can open this project on Android, iOS, and the web. To open the web version,
- press w in the terminal running this
- project.
-
-
-
-
-
-
-
- For static images, you can use the @2x and{" "}
- @3x suffixes to provide files for different
- screen densities.
-
-
-
- Learn more
-
-
-
-
-
- This template has light and dark mode support. The{" "}
- useColorScheme() hook lets you inspect what the
- user's current color scheme is, and so you can adjust UI colors accordingly.
-
-
- Learn more
-
-
-
-
-
- This template includes an example of an animated component. The{" "}
- src/components/ui/collapsible.tsx component uses
- the powerful react-native-reanimated library to
- animate opening this hint.
-
-
-
- {Platform.OS === "web" && }
-
-
- );
-}
-
-const styles = StyleSheet.create({
- scrollView: {
- flex: 1,
- },
- contentContainer: {
- flexDirection: "row",
- justifyContent: "center",
- },
- container: {
- maxWidth: MaxContentWidth,
- flexGrow: 1,
- },
- titleContainer: {
- gap: Spacing.three,
- alignItems: "center",
- paddingHorizontal: Spacing.four,
- paddingVertical: Spacing.six,
- },
- centerText: {
- textAlign: "center",
- },
- pressed: {
- opacity: 0.7,
- },
- linkButton: {
- flexDirection: "row",
- paddingHorizontal: Spacing.four,
- paddingVertical: Spacing.two,
- borderRadius: Spacing.five,
- justifyContent: "center",
- gap: Spacing.one,
- alignItems: "center",
- },
- sectionsWrapper: {
- gap: Spacing.five,
- paddingHorizontal: Spacing.four,
- paddingTop: Spacing.three,
- },
- collapsibleContent: {
- alignItems: "center",
- },
- imageTutorial: {
- width: "100%",
- aspectRatio: 296 / 171,
- borderRadius: Spacing.three,
- marginTop: Spacing.two,
- },
- imageReact: {
- width: 100,
- height: 100,
- alignSelf: "center",
- },
-});
diff --git a/src/app/index.tsx b/src/app/index.tsx
index 88d3d40..1e00607 100644
--- a/src/app/index.tsx
+++ b/src/app/index.tsx
@@ -1,98 +1,3 @@
-import * as Device from "expo-device";
-import { Platform, StyleSheet } from "react-native";
-import { SafeAreaView } from "react-native-safe-area-context";
+import WebViewScreen from "@/features/webview/WebViewScreen";
-import { AnimatedIcon } from "@/components/animated-icon";
-import { HintRow } from "@/components/hint-row";
-import { ThemedText } from "@/components/themed-text";
-import { ThemedView } from "@/components/themed-view";
-import { WebBadge } from "@/components/web-badge";
-import { BottomTabInset, MaxContentWidth, Spacing } from "@/constants/theme";
-
-function getDevMenuHint() {
- if (Platform.OS === "web") {
- return use browser devtools;
- }
- if (Device.isDevice) {
- return (
-
- shake device or press m in terminal
-
- );
- }
- const shortcut = Platform.OS === "android" ? "cmd+m (or ctrl+m)" : "cmd+d";
- return (
-
- press {shortcut}
-
- );
-}
-
-export default function HomeScreen() {
- return (
-
-
-
-
-
- Welcome to Expo
-
-
-
-
- get started
-
-
-
- src/app/index.tsx}
- />
-
- npm run reset-project}
- />
-
-
- {Platform.OS === "web" && }
-
-
- );
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: "center",
- flexDirection: "row",
- },
- safeArea: {
- flex: 1,
- paddingHorizontal: Spacing.four,
- alignItems: "center",
- gap: Spacing.three,
- paddingBottom: BottomTabInset + Spacing.three,
- maxWidth: MaxContentWidth,
- },
- heroSection: {
- alignItems: "center",
- justifyContent: "center",
- flex: 1,
- paddingHorizontal: Spacing.four,
- gap: Spacing.four,
- },
- title: {
- textAlign: "center",
- },
- code: {
- textTransform: "uppercase",
- },
- stepContainer: {
- gap: Spacing.three,
- alignSelf: "stretch",
- paddingHorizontal: Spacing.three,
- paddingVertical: Spacing.four,
- borderRadius: Spacing.four,
- },
-});
+export default WebViewScreen;
diff --git a/src/components/animated-icon.module.css b/src/components/animated-icon.module.css
deleted file mode 100644
index f8156fe..0000000
--- a/src/components/animated-icon.module.css
+++ /dev/null
@@ -1,6 +0,0 @@
-.expoLogoBackground {
- background-image: linear-gradient(180deg, #3c9ffe, #0274df);
- border-radius: 40px;
- width: 128px;
- height: 128px;
-}
diff --git a/src/components/animated-icon.tsx b/src/components/animated-icon.tsx
deleted file mode 100644
index bffda2e..0000000
--- a/src/components/animated-icon.tsx
+++ /dev/null
@@ -1,150 +0,0 @@
-import { Image } from "expo-image";
-import * as SplashScreen from "expo-splash-screen";
-import { useState } from "react";
-import { Dimensions, StyleSheet, View } from "react-native";
-import Animated, { Easing, Keyframe } from "react-native-reanimated";
-import { scheduleOnRN } from "react-native-worklets";
-
-const INITIAL_SCALE_FACTOR = Dimensions.get("screen").height / 90;
-const DURATION = 600;
-
-export function AnimatedSplashOverlay() {
- const [animate, setAnimate] = useState(false);
- const [visible, setVisible] = useState(true);
-
- if (!visible) return null;
-
- const splashKeyframe = new Keyframe({
- 0: {
- transform: [{ scale: 1 }],
- opacity: 1,
- },
- 20: {
- opacity: 1,
- },
- 70: {
- opacity: 0,
- easing: Easing.elastic(0.7),
- },
- 100: {
- opacity: 0,
- transform: [{ scale: 1 }],
- easing: Easing.elastic(0.7),
- },
- });
-
- const image = ;
-
- return animate ? (
- {
- "worklet";
- if (finished) {
- scheduleOnRN(setVisible, false);
- }
- })}
- style={styles.splashOverlay}
- >
- {image}
-
- ) : (
- {
- SplashScreen.hideAsync().finally(() => {
- setAnimate(true);
- });
- }}
- style={styles.splashOverlay}
- >
- {image}
-
- );
-}
-
-const keyframe = new Keyframe({
- 0: {
- transform: [{ scale: INITIAL_SCALE_FACTOR }],
- },
- 100: {
- transform: [{ scale: 1 }],
- easing: Easing.elastic(0.7),
- },
-});
-
-const logoKeyframe = new Keyframe({
- 0: {
- transform: [{ scale: 1.3 }],
- opacity: 0,
- },
- 40: {
- transform: [{ scale: 1.3 }],
- opacity: 0,
- easing: Easing.elastic(0.7),
- },
- 100: {
- opacity: 1,
- transform: [{ scale: 1 }],
- easing: Easing.elastic(0.7),
- },
-});
-
-const glowKeyframe = new Keyframe({
- 0: {
- transform: [{ rotateZ: "0deg" }],
- },
- 100: {
- transform: [{ rotateZ: "7200deg" }],
- },
-});
-
-export function AnimatedIcon() {
- return (
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-const styles = StyleSheet.create({
- imageContainer: {
- justifyContent: "center",
- alignItems: "center",
- },
- glow: {
- width: 201,
- height: 201,
- position: "absolute",
- },
- iconContainer: {
- justifyContent: "center",
- alignItems: "center",
- width: 128,
- height: 128,
- zIndex: 100,
- },
- image: {
- width: 76,
- height: 71,
- },
- background: {
- borderRadius: 40,
- experimental_backgroundImage: `linear-gradient(180deg, #3C9FFE, #0274DF)`,
- width: 128,
- height: 128,
- position: "absolute",
- },
- splashOverlay: {
- ...StyleSheet.absoluteFill,
- backgroundColor: "#208AEF",
- alignItems: "center",
- justifyContent: "center",
- zIndex: 1000,
- },
-});
diff --git a/src/components/animated-icon.web.tsx b/src/components/animated-icon.web.tsx
deleted file mode 100644
index eb7b23c..0000000
--- a/src/components/animated-icon.web.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import { Image } from "expo-image";
-import { StyleSheet, View } from "react-native";
-import Animated, { Easing, Keyframe } from "react-native-reanimated";
-
-import classes from "./animated-icon.module.css";
-
-const DURATION = 300;
-
-export function AnimatedSplashOverlay() {
- return null;
-}
-
-const keyframe = new Keyframe({
- 0: {
- transform: [{ scale: 0 }],
- },
- 60: {
- transform: [{ scale: 1.2 }],
- easing: Easing.elastic(1.2),
- },
- 100: {
- transform: [{ scale: 1 }],
- easing: Easing.elastic(1.2),
- },
-});
-
-const logoKeyframe = new Keyframe({
- 0: {
- opacity: 0,
- },
- 60: {
- transform: [{ scale: 1.2 }],
- opacity: 0,
- easing: Easing.elastic(1.2),
- },
- 100: {
- transform: [{ scale: 1 }],
- opacity: 1,
- easing: Easing.elastic(1.2),
- },
-});
-
-const glowKeyframe = new Keyframe({
- 0: {
- transform: [{ rotateZ: "-180deg" }, { scale: 0.8 }],
- opacity: 0,
- },
- [DURATION / 1000]: {
- transform: [{ rotateZ: "0deg" }, { scale: 1 }],
- opacity: 1,
- easing: Easing.elastic(0.7),
- },
- 100: {
- transform: [{ rotateZ: "7200deg" }],
- },
-});
-
-export function AnimatedIcon() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-const styles = StyleSheet.create({
- container: {
- alignItems: "center",
- width: "100%",
- zIndex: 1000,
- position: "absolute",
- top: 128 / 2 + 138,
- },
- imageContainer: {
- justifyContent: "center",
- alignItems: "center",
- },
- glow: {
- width: 201,
- height: 201,
- position: "absolute",
- },
- iconContainer: {
- justifyContent: "center",
- alignItems: "center",
- width: 128,
- height: 128,
- },
- image: {
- position: "absolute",
- width: 76,
- height: 71,
- },
- background: {
- width: 128,
- height: 128,
- position: "absolute",
- },
-});
diff --git a/src/components/app-tabs.tsx b/src/components/app-tabs.tsx
deleted file mode 100644
index 8170afb..0000000
--- a/src/components/app-tabs.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import { NativeTabs } from "expo-router/unstable-native-tabs";
-import { useColorScheme } from "react-native";
-
-import { Colors } from "@/constants/theme";
-
-export default function AppTabs() {
- const scheme = useColorScheme();
- const colors = Colors[scheme === "unspecified" ? "light" : scheme];
-
- return (
-
-
- Home
-
-
-
-
- Explore
-
-
-
- );
-}
diff --git a/src/components/app-tabs.web.tsx b/src/components/app-tabs.web.tsx
deleted file mode 100644
index c554bdf..0000000
--- a/src/components/app-tabs.web.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-import {
- TabList,
- type TabListProps,
- TabSlot,
- Tabs,
- TabTrigger,
- type TabTriggerSlotProps,
-} from "expo-router/ui";
-import { SymbolView } from "expo-symbols";
-import { Pressable, StyleSheet, useColorScheme, View } from "react-native";
-import { Colors, MaxContentWidth, Spacing } from "@/constants/theme";
-import { ExternalLink } from "./external-link";
-import { ThemedText } from "./themed-text";
-import { ThemedView } from "./themed-view";
-
-export default function AppTabs() {
- return (
-
-
-
-
-
- Home
-
-
- Explore
-
-
-
-
- );
-}
-
-export function TabButton({ children, isFocused, ...props }: TabTriggerSlotProps) {
- return (
- pressed && styles.pressed}>
-
-
- {children}
-
-
-
- );
-}
-
-export function CustomTabList(props: TabListProps) {
- const scheme = useColorScheme();
- const colors = Colors[scheme === "unspecified" ? "light" : scheme];
-
- return (
-
-
-
- Expo Starter
-
-
- {props.children}
-
-
-
- Docs
-
-
-
-
-
- );
-}
-
-const styles = StyleSheet.create({
- tabListContainer: {
- position: "absolute",
- width: "100%",
- padding: Spacing.three,
- justifyContent: "center",
- alignItems: "center",
- flexDirection: "row",
- },
- innerContainer: {
- paddingVertical: Spacing.two,
- paddingHorizontal: Spacing.five,
- borderRadius: Spacing.five,
- flexDirection: "row",
- alignItems: "center",
- flexGrow: 1,
- gap: Spacing.two,
- maxWidth: MaxContentWidth,
- },
- brandText: {
- marginRight: "auto",
- },
- pressed: {
- opacity: 0.7,
- },
- tabButtonView: {
- paddingVertical: Spacing.one,
- paddingHorizontal: Spacing.three,
- borderRadius: Spacing.three,
- },
- externalPressable: {
- flexDirection: "row",
- justifyContent: "center",
- alignItems: "center",
- gap: Spacing.one,
- marginLeft: Spacing.three,
- },
-});
diff --git a/src/components/external-link.tsx b/src/components/external-link.tsx
deleted file mode 100644
index 53d895b..0000000
--- a/src/components/external-link.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { type Href, Link } from "expo-router";
-import { openBrowserAsync, WebBrowserPresentationStyle } from "expo-web-browser";
-import type { ComponentProps } from "react";
-
-type Props = Omit, "href"> & { href: Href & string };
-
-export function ExternalLink({ href, ...rest }: Props) {
- return (
- {
- if (process.env.EXPO_OS !== "web") {
- // Prevent the default behavior of linking to the default browser on native.
- event.preventDefault();
- // Open the link in an in-app browser.
- await openBrowserAsync(href, {
- presentationStyle: WebBrowserPresentationStyle.AUTOMATIC,
- });
- }
- }}
- />
- );
-}
diff --git a/src/components/hint-row.tsx b/src/components/hint-row.tsx
deleted file mode 100644
index 04a4d9f..0000000
--- a/src/components/hint-row.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { ReactNode } from "react";
-import { StyleSheet, View } from "react-native";
-import { Spacing } from "@/constants/theme";
-import { ThemedText } from "./themed-text";
-import { ThemedView } from "./themed-view";
-
-type HintRowProps = {
- title?: string;
- hint?: ReactNode;
-};
-
-export function HintRow({ title = "Try editing", hint = "app/index.tsx" }: HintRowProps) {
- return (
-
- {title}
-
- {hint}
-
-
- );
-}
-
-const styles = StyleSheet.create({
- stepRow: {
- flexDirection: "row",
- justifyContent: "space-between",
- },
- codeSnippet: {
- borderRadius: Spacing.two,
- paddingVertical: Spacing.half,
- paddingHorizontal: Spacing.two,
- },
-});
diff --git a/src/components/themed-text.tsx b/src/components/themed-text.tsx
deleted file mode 100644
index d7310fb..0000000
--- a/src/components/themed-text.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import { Platform, StyleSheet, Text, type TextProps } from "react-native";
-
-import { Fonts, type ThemeColor } from "@/constants/theme";
-import { useTheme } from "@/hooks/use-theme";
-
-export type ThemedTextProps = TextProps & {
- type?: "default" | "title" | "small" | "smallBold" | "subtitle" | "link" | "linkPrimary" | "code";
- themeColor?: ThemeColor;
-};
-
-export function ThemedText({ style, type = "default", themeColor, ...rest }: ThemedTextProps) {
- const theme = useTheme();
-
- return (
-
- );
-}
-
-const styles = StyleSheet.create({
- small: {
- fontSize: 14,
- lineHeight: 20,
- fontWeight: 500,
- },
- smallBold: {
- fontSize: 14,
- lineHeight: 20,
- fontWeight: 700,
- },
- default: {
- fontSize: 16,
- lineHeight: 24,
- fontWeight: 500,
- },
- title: {
- fontSize: 48,
- fontWeight: 600,
- lineHeight: 52,
- },
- subtitle: {
- fontSize: 32,
- lineHeight: 44,
- fontWeight: 600,
- },
- link: {
- lineHeight: 30,
- fontSize: 14,
- },
- linkPrimary: {
- lineHeight: 30,
- fontSize: 14,
- color: "#3c87f7",
- },
- code: {
- fontFamily: Fonts.mono,
- fontWeight: Platform.select({ android: 700 }) ?? 500,
- fontSize: 12,
- },
-});
diff --git a/src/components/themed-view.tsx b/src/components/themed-view.tsx
deleted file mode 100644
index 990bb54..0000000
--- a/src/components/themed-view.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import { View, type ViewProps } from "react-native";
-
-import type { ThemeColor } from "@/constants/theme";
-import { useTheme } from "@/hooks/use-theme";
-
-export type ThemedViewProps = ViewProps & {
- lightColor?: string;
- darkColor?: string;
- type?: ThemeColor;
-};
-
-export function ThemedView({ style, lightColor, darkColor, type, ...otherProps }: ThemedViewProps) {
- const theme = useTheme();
-
- return ;
-}
diff --git a/src/components/ui/collapsible.tsx b/src/components/ui/collapsible.tsx
deleted file mode 100644
index 76dc278..0000000
--- a/src/components/ui/collapsible.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import { SymbolView } from "expo-symbols";
-import { type PropsWithChildren, useState } from "react";
-import { Pressable, StyleSheet } from "react-native";
-import Animated, { FadeIn } from "react-native-reanimated";
-
-import { ThemedText } from "@/components/themed-text";
-import { ThemedView } from "@/components/themed-view";
-import { Spacing } from "@/constants/theme";
-import { useTheme } from "@/hooks/use-theme";
-
-export function Collapsible({ children, title }: PropsWithChildren & { title: string }) {
- const [isOpen, setIsOpen] = useState(false);
- const theme = useTheme();
-
- return (
-
- [styles.heading, pressed && styles.pressedHeading]}
- onPress={() => setIsOpen((value) => !value)}
- >
-
-
-
-
- {title}
-
- {isOpen && (
-
-
- {children}
-
-
- )}
-
- );
-}
-
-const styles = StyleSheet.create({
- heading: {
- flexDirection: "row",
- alignItems: "center",
- gap: Spacing.two,
- },
- pressedHeading: {
- opacity: 0.7,
- },
- button: {
- width: Spacing.four,
- height: Spacing.four,
- borderRadius: 12,
- justifyContent: "center",
- alignItems: "center",
- },
- content: {
- marginTop: Spacing.three,
- borderRadius: Spacing.three,
- marginLeft: Spacing.four,
- padding: Spacing.four,
- },
-});
diff --git a/src/components/web-badge.tsx b/src/components/web-badge.tsx
deleted file mode 100644
index 241ec8b..0000000
--- a/src/components/web-badge.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { version } from "expo/package.json";
-import { Image } from "expo-image";
-import { StyleSheet, useColorScheme } from "react-native";
-import { Spacing } from "@/constants/theme";
-import { ThemedText } from "./themed-text";
-import { ThemedView } from "./themed-view";
-
-export function WebBadge() {
- const scheme = useColorScheme();
-
- return (
-
-
- v{version}
-
-
-
- );
-}
-
-const styles = StyleSheet.create({
- container: {
- padding: Spacing.five,
- alignItems: "center",
- gap: Spacing.two,
- },
- versionText: {
- textAlign: "center",
- },
- badgeImage: {
- width: 123,
- aspectRatio: 123 / 24,
- },
-});
diff --git a/src/constants/config.ts b/src/constants/config.ts
new file mode 100644
index 0000000..91969f3
--- /dev/null
+++ b/src/constants/config.ts
@@ -0,0 +1,8 @@
+/**
+ * 웹뷰로 띄울 stream-client-web 주소.
+ *
+ * 개발 중에는 실행 환경(시뮬레이터·에뮬레이터·실제 기기)마다 가리켜야 하는 주소가 달라
+ * 커밋에 박을 수 없으므로 `.env.local`의 `EXPO_PUBLIC_WEB_URL`로 주입한다.
+ * 환경별 주소는 `docs/local-development.md` 참고.
+ */
+export const WEB_URL = process.env.EXPO_PUBLIC_WEB_URL ?? "";
diff --git a/src/constants/theme.ts b/src/constants/theme.ts
deleted file mode 100644
index 2a76d02..0000000
--- a/src/constants/theme.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Below are the colors that are used in the app. The colors are defined in the light and dark mode.
- * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
- */
-
-import "@/global.css";
-
-import { Platform } from "react-native";
-
-export const Colors = {
- light: {
- text: "#000000",
- background: "#ffffff",
- backgroundElement: "#F0F0F3",
- backgroundSelected: "#E0E1E6",
- textSecondary: "#60646C",
- },
- dark: {
- text: "#ffffff",
- background: "#000000",
- backgroundElement: "#212225",
- backgroundSelected: "#2E3135",
- textSecondary: "#B0B4BA",
- },
-} as const;
-
-export type ThemeColor = keyof typeof Colors.light & keyof typeof Colors.dark;
-
-export const Fonts = Platform.select({
- ios: {
- /** iOS `UIFontDescriptorSystemDesignDefault` */
- sans: "system-ui",
- /** iOS `UIFontDescriptorSystemDesignSerif` */
- serif: "ui-serif",
- /** iOS `UIFontDescriptorSystemDesignRounded` */
- rounded: "ui-rounded",
- /** iOS `UIFontDescriptorSystemDesignMonospaced` */
- mono: "ui-monospace",
- },
- default: {
- sans: "normal",
- serif: "serif",
- rounded: "normal",
- mono: "monospace",
- },
- web: {
- sans: "var(--font-display)",
- serif: "var(--font-serif)",
- rounded: "var(--font-rounded)",
- mono: "var(--font-mono)",
- },
-});
-
-export const Spacing = {
- half: 2,
- one: 4,
- two: 8,
- three: 16,
- four: 24,
- five: 32,
- six: 64,
-} as const;
-
-export const BottomTabInset = Platform.select({ ios: 50, android: 80 }) ?? 0;
-export const MaxContentWidth = 800;
diff --git a/src/features/webview/WebViewScreen.tsx b/src/features/webview/WebViewScreen.tsx
new file mode 100644
index 0000000..342e7f3
--- /dev/null
+++ b/src/features/webview/WebViewScreen.tsx
@@ -0,0 +1,122 @@
+import * as WebBrowser from "expo-web-browser";
+import { useCallback, useEffect, useRef, useState } from "react";
+import { ActivityIndicator, BackHandler, Linking, Platform, StyleSheet, View } from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { WebView, type WebViewNavigation } from "react-native-webview";
+import type { ShouldStartLoadRequest } from "react-native-webview/lib/WebViewTypes";
+import { WEB_URL } from "@/constants/config";
+import WebViewMessage from "@/features/webview/components/WebViewMessage";
+import { isSameOrigin } from "@/utils/url";
+
+// WebView는 서드파티 컴포넌트라 NativeWind의 className이 적용되지 않는다. style로 채운다.
+const styles = StyleSheet.create({
+ webView: { flex: 1 },
+});
+
+export default function WebViewScreen() {
+ const insets = useSafeAreaInsets();
+ const webViewRef = useRef(null);
+ const [isLoading, setIsLoading] = useState(true);
+ const [hasError, setHasError] = useState(false);
+ const [canGoBack, setCanGoBack] = useState(false);
+
+ // 안드로이드 하드웨어 백 버튼은 기본적으로 앱을 종료한다. 웹 히스토리가 남아 있으면 뒤로 보낸다.
+ useEffect(() => {
+ if (Platform.OS !== "android") {
+ return;
+ }
+
+ const subscription = BackHandler.addEventListener("hardwareBackPress", () => {
+ if (!canGoBack) {
+ return false;
+ }
+ webViewRef.current?.goBack();
+ return true;
+ });
+
+ return () => subscription.remove();
+ }, [canGoBack]);
+
+ const handleRetry = useCallback(() => {
+ setHasError(false);
+ setIsLoading(true);
+ webViewRef.current?.reload();
+ }, []);
+
+ const handleNavigationStateChange = useCallback((navigation: WebViewNavigation) => {
+ setCanGoBack(navigation.canGoBack);
+ }, []);
+
+ // 서비스 바깥 주소는 웹뷰 안에서 열지 않고 시스템 브라우저·기본 앱으로 넘긴다.
+ const handleShouldStartLoad = useCallback((request: ShouldStartLoadRequest) => {
+ const { url } = request;
+
+ if (url.startsWith("about:") || isSameOrigin(url, WEB_URL)) {
+ return true;
+ }
+
+ const open =
+ url.startsWith("http://") || url.startsWith("https://")
+ ? WebBrowser.openBrowserAsync(url)
+ : Linking.openURL(url);
+
+ open.catch((error) => {
+ console.warn(`외부 링크를 열지 못했습니다: ${url}`, error);
+ });
+
+ return false;
+ }, []);
+
+ if (!WEB_URL) {
+ return (
+
+ );
+ }
+
+ if (hasError) {
+ return (
+
+ );
+ }
+
+ return (
+ // 세이프에어리어는 네이티브가 담당하고 웹은 주어진 영역을 100%로 채우기만 한다.
+ // 위아래 스트립은 맞닿는 웹 화면과 같은 색으로 칠해야 경계선이 보이지 않는데,
+ // 위는 웹 본문 배경 / 아래는 Bottom Nav 배경이라 색이 서로 달라
+ // SafeAreaView 하나로는 칠할 수 없다. 인셋을 직접 재서 나눠 칠한다.
+
+
+
+ setHasError(true)}
+ // 이미지·스크립트 같은 하위 리소스 실패까지 오류 화면으로 넘기지 않도록 본문 요청만 본다.
+ onHttpError={({ nativeEvent }) => {
+ if (nativeEvent.url === WEB_URL) {
+ setHasError(true);
+ }
+ }}
+ onLoadEnd={() => setIsLoading(false)}
+ onLoadStart={() => setIsLoading(true)}
+ onNavigationStateChange={handleNavigationStateChange}
+ onShouldStartLoadWithRequest={handleShouldStartLoad}
+ ref={webViewRef}
+ source={{ uri: WEB_URL }}
+ style={styles.webView}
+ />
+ {isLoading && (
+
+
+
+ )}
+
+
+
+ );
+}
diff --git a/src/features/webview/components/WebViewMessage.tsx b/src/features/webview/components/WebViewMessage.tsx
new file mode 100644
index 0000000..eb75797
--- /dev/null
+++ b/src/features/webview/components/WebViewMessage.tsx
@@ -0,0 +1,30 @@
+import { Pressable, Text, View } from "react-native";
+import { SafeAreaView } from "react-native-safe-area-context";
+
+interface WebViewMessageProps {
+ title: string;
+ description: string;
+ /** 있으면 재시도 버튼을 노출한다. */
+ onRetry?: () => void;
+}
+
+/** 웹을 띄우지 못했을 때 웹뷰 대신 보여주는 안내 화면. */
+export default function WebViewMessage({ title, description, onRetry }: WebViewMessageProps) {
+ return (
+
+ {title}
+ {description}
+ {onRetry && (
+
+
+ 다시 시도
+
+
+ )}
+
+ );
+}
diff --git a/src/hooks/use-color-scheme.ts b/src/hooks/use-color-scheme.ts
deleted file mode 100644
index 93a8fde..0000000
--- a/src/hooks/use-color-scheme.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { useColorScheme } from "react-native";
diff --git a/src/hooks/use-color-scheme.web.ts b/src/hooks/use-color-scheme.web.ts
deleted file mode 100644
index 66cccac..0000000
--- a/src/hooks/use-color-scheme.web.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { useEffect, useState } from "react";
-import { useColorScheme as useRNColorScheme } from "react-native";
-
-/**
- * To support static rendering, this value needs to be re-calculated on the client side for web
- */
-export function useColorScheme() {
- const [hasHydrated, setHasHydrated] = useState(false);
-
- useEffect(() => {
- setHasHydrated(true);
- }, []);
-
- const colorScheme = useRNColorScheme();
-
- if (hasHydrated) {
- return colorScheme;
- }
-
- return "light";
-}
diff --git a/src/hooks/use-theme.ts b/src/hooks/use-theme.ts
deleted file mode 100644
index 4b6210d..0000000
--- a/src/hooks/use-theme.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Learn more about light and dark modes:
- * https://docs.expo.dev/guides/color-schemes/
- */
-
-import { Colors } from "@/constants/theme";
-import { useColorScheme } from "@/hooks/use-color-scheme";
-
-export function useTheme() {
- const scheme = useColorScheme();
- const theme = scheme === "unspecified" ? "light" : scheme;
-
- return Colors[theme];
-}
diff --git a/src/utils/url.ts b/src/utils/url.ts
new file mode 100644
index 0000000..f8a8f1d
--- /dev/null
+++ b/src/utils/url.ts
@@ -0,0 +1,16 @@
+/**
+ * URL에서 origin(`scheme://host:port`)만 뽑는다.
+ *
+ * RN에 내장된 `URL` 구현은 불완전해 `origin`/`hostname`을 신뢰할 수 없으므로 직접 파싱한다.
+ * 형식을 알아볼 수 없으면 빈 문자열을 돌려준다.
+ */
+export function getOrigin(url: string): string {
+ const matched = url.match(/^[a-zA-Z][\w+.-]*:\/\/[^/?#]*/);
+ return matched ? matched[0].toLowerCase() : "";
+}
+
+/** 두 URL이 같은 origin인지 판단한다. 어느 한쪽이라도 파싱되지 않으면 false다. */
+export function isSameOrigin(a: string, b: string): boolean {
+ const originA = getOrigin(a);
+ return originA !== "" && originA === getOrigin(b);
+}
diff --git a/tailwind.config.js b/tailwind.config.js
index 407a91f..58480d0 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -3,7 +3,15 @@ module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
presets: [require("nativewind/preset")],
theme: {
- extend: {},
+ extend: {
+ colors: {
+ // stream-client-web이 쓰는 WDS 배경 토큰 값을 그대로 옮긴 것.
+ // 세이프에어리어 스트립을 웹 화면과 같은 색으로 잇는 용도로만 쓴다.
+ // 웹에서 토큰 값이 바뀌면 여기도 함께 맞춰야 한다.
+ "web-background-alternative": "#F7F7F8",
+ "web-background-normal": "#FFFFFF",
+ },
+ },
},
plugins: [],
};