lv 1 mesiac pred
rodič
commit
5fbd7bc60b
7 zmenil súbory, kde vykonal 163 pridanie a 23 odobranie
  1. 1 0
      .yarnrc.yml
  2. 2 0
      android/gradle.properties
  3. 7 3
      app.json
  4. 6 4
      package.json
  5. 114 0
      pnpm-lock.yaml
  6. 13 3
      src/app/_layout.tsx
  7. 20 13
      src/app/sign-in.tsx

+ 1 - 0
.yarnrc.yml

@@ -0,0 +1 @@
+nodeLinker: node-modules

+ 2 - 0
android/gradle.properties

@@ -59,3 +59,5 @@ EX_DEV_CLIENT_NETWORK_INSPECTOR=true
 
 
 # Use legacy packaging to compress native libraries in the resulting APK.
 # Use legacy packaging to compress native libraries in the resulting APK.
 expo.useLegacyPackaging=false
 expo.useLegacyPackaging=false
+
+ndk.dir=~/lv/Library/Android/sdk/ndk/27.1.12297006

+ 7 - 3
app.json

@@ -39,7 +39,10 @@
     "web": {
     "web": {
       "bundler": "metro",
       "bundler": "metro",
       "output": "static",
       "output": "static",
-      "favicon": "./assets/images/favicon.png"
+      "favicon": "./assets/images/favicon.png",
+      "experiments": {
+        "baseUrl": "/h5"
+      }
     },
     },
     "plugins": [
     "plugins": [
       "expo-router",
       "expo-router",
@@ -56,12 +59,13 @@
     ],
     ],
     "experiments": {
     "experiments": {
       "typedRoutes": true,
       "typedRoutes": true,
-      "reactCompiler": true
+      "reactCompiler": true,
+      "baseUrl": "/h5"
     },
     },
     "updates": {
     "updates": {
       "enabled": true,
       "enabled": true,
       "checkAutomatically": "ON_LOAD",
       "checkAutomatically": "ON_LOAD",
-      "url": "https://loan.ewaga.com/airpatch/manifest", // 你的服务器地址
+      "url": "https://loan.ewaga.com/airpatch/api/manifest", // 你的服务器地址
       "fallbackToCacheTimeout": 30000,
       "fallbackToCacheTimeout": 30000,
       // "codeSigningCertificate": "./code-signing/certificate.pem",
       // "codeSigningCertificate": "./code-signing/certificate.pem",
       // "codeSigningMetadata": {
       // "codeSigningMetadata": {

+ 6 - 4
package.json

@@ -8,11 +8,12 @@
     "android": "expo run:android",
     "android": "expo run:android",
     "ios": "expo run:ios",
     "ios": "expo run:ios",
     "web": "expo start --web",
     "web": "expo start --web",
-    "build:web": "expo export --platform web",
+    "build:web": "expo export --platform web --output-dir dist/web",
     "build:ios": "",
     "build:ios": "",
-    "build:apk": "cd android && ./gradlew app:bundleRelease",
-    "build:ios-patch": "expo export --platform ios --output-dir dist/ios-patch",
-    "build:android-patch": "expo export --platform android --output-dir dist/android-patch",
+    "build:apk": "cd android && ./gradlew app:assembleRelease",
+    "build:aab": "cd android && ./gradlew app:bundleRelease",
+    "build:ios-patch": "expo export --platform ios --output-dir dist/ios",
+    "build:android-patch": "expo export --platform android --output-dir dist/android",
     "lint": "expo lint"
     "lint": "expo lint"
   },
   },
   "dependencies": {
   "dependencies": {
@@ -34,6 +35,7 @@
     "expo-status-bar": "~55.0.5",
     "expo-status-bar": "~55.0.5",
     "expo-symbols": "~55.0.7",
     "expo-symbols": "~55.0.7",
     "expo-system-ui": "~55.0.14",
     "expo-system-ui": "~55.0.14",
+    "expo-updates": "~55.0.20",
     "expo-web-browser": "~55.0.13",
     "expo-web-browser": "~55.0.13",
     "nativewind": "^4.2.3",
     "nativewind": "^4.2.3",
     "react": "19.2.0",
     "react": "19.2.0",

+ 114 - 0
pnpm-lock.yaml

@@ -62,6 +62,9 @@ importers:
       expo-system-ui:
       expo-system-ui:
         specifier: ~55.0.14
         specifier: ~55.0.14
         version: 55.0.14(expo@55.0.12)(react-native-web@0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))
         version: 55.0.14(expo@55.0.12)(react-native-web@0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))
+      expo-updates:
+        specifier: ~55.0.20
+        version: 55.0.20(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
       expo-web-browser:
       expo-web-browser:
         specifier: ~55.0.13
         specifier: ~55.0.13
         version: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))
         version: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))
@@ -967,6 +970,9 @@ packages:
   '@expo/config@55.0.13':
   '@expo/config@55.0.13':
     resolution: {integrity: sha512-mO6le0JXEk7whsIb5E7rT36wOtdcLRFlApc7eLCOyu24uQUvWKk00HSEPVjiOuMd7EgYz/8JBPCA+Rb96uNjIg==}
     resolution: {integrity: sha512-mO6le0JXEk7whsIb5E7rT36wOtdcLRFlApc7eLCOyu24uQUvWKk00HSEPVjiOuMd7EgYz/8JBPCA+Rb96uNjIg==}
 
 
+  '@expo/config@55.0.15':
+    resolution: {integrity: sha512-lHc0ELIQ8126jYOMZpLv3WIuvordW98jFg5aT/J1/12n2ycuXu01XLZkJsdw0avO34cusUYb1It+MvY8JiMduA==}
+
   '@expo/devcert@1.2.1':
   '@expo/devcert@1.2.1':
     resolution: {integrity: sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==}
     resolution: {integrity: sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==}
 
 
@@ -1058,6 +1064,14 @@ packages:
       typescript:
       typescript:
         optional: true
         optional: true
 
 
+  '@expo/require-utils@55.0.4':
+    resolution: {integrity: sha512-JAANvXqV7MOysWeVWgaiDzikoyDjJWOV/ulOW60Zb3kXJfrx2oZOtGtDXDFKD1mXuahQgoM5QOjuZhF7gFRNjA==}
+    peerDependencies:
+      typescript: ^5.0.0 || ^5.0.0-0
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
   '@expo/router-server@55.0.13':
   '@expo/router-server@55.0.13':
     resolution: {integrity: sha512-AoxfxJYkAIMey8YqAohFovp4M4DjzoCDH9ampVN/ZKt+bzXkTIFmWEinQ5mpMfHdfIWaumvxQbohgoo6D5xUZA==}
     resolution: {integrity: sha512-AoxfxJYkAIMey8YqAohFovp4M4DjzoCDH9ampVN/ZKt+bzXkTIFmWEinQ5mpMfHdfIWaumvxQbohgoo6D5xUZA==}
     peerDependencies:
     peerDependencies:
@@ -1848,6 +1862,9 @@ packages:
     resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
     resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
     engines: {node: '>= 8'}
     engines: {node: '>= 8'}
 
 
+  arg@4.1.3:
+    resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
+
   arg@5.0.2:
   arg@5.0.2:
     resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
     resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
 
 
@@ -2637,6 +2654,9 @@ packages:
     peerDependencies:
     peerDependencies:
       expo: '*'
       expo: '*'
 
 
+  expo-eas-client@55.0.5:
+    resolution: {integrity: sha512-wRagCeSbSnSGVXgP7V+qiGfXzZ9hTVKWvKIOP7lwrX3MIEenNmNlO4D3RVC3aNU2GhmO3ZCZIIEre80KZoUUHA==}
+
   expo-file-system@55.0.15:
   expo-file-system@55.0.15:
     resolution: {integrity: sha512-GEo0CzfmRfR7nOjp5p4Tb9XWtgPxDIYRiQws79DpBQsX15UsCdDw7/se3aFO6NyZuGFx/85KsdD7SPGphbE/jw==}
     resolution: {integrity: sha512-GEo0CzfmRfR7nOjp5p4Tb9XWtgPxDIYRiQws79DpBQsX15UsCdDw7/se3aFO6NyZuGFx/85KsdD7SPGphbE/jw==}
     peerDependencies:
     peerDependencies:
@@ -2668,6 +2688,9 @@ packages:
       react-native-web:
       react-native-web:
         optional: true
         optional: true
 
 
+  expo-json-utils@55.0.2:
+    resolution: {integrity: sha512-QJMOZOPOG7CTnKcrdVaiummn2va1MCO56z++eyWkDv3GBRODldM6MFMDf/jTREWthFc2Nxo6TuyWRrEV9S6n/Q==}
+
   expo-keep-awake@55.0.6:
   expo-keep-awake@55.0.6:
     resolution: {integrity: sha512-acJjeHqkNxMVckEcJhGQeIksqqsarscSHJtT559bNgyiM4r14dViQ66su7bb6qDVeBt0K7z3glXI1dHVck1Zgg==}
     resolution: {integrity: sha512-acJjeHqkNxMVckEcJhGQeIksqqsarscSHJtT559bNgyiM4r14dViQ66su7bb6qDVeBt0K7z3glXI1dHVck1Zgg==}
     peerDependencies:
     peerDependencies:
@@ -2680,6 +2703,11 @@ packages:
       react: '*'
       react: '*'
       react-native: '*'
       react-native: '*'
 
 
+  expo-manifests@55.0.15:
+    resolution: {integrity: sha512-p40ftXpgLTFGddFy35MYZMyjm/E6IQdn3l6fBZZ6zeraEzYLt+VLHYsplOL9ccTYvUSWKN9aOWRpoEYpyGVBVw==}
+    peerDependencies:
+      expo: '*'
+
   expo-modules-autolinking@55.0.15:
   expo-modules-autolinking@55.0.15:
     resolution: {integrity: sha512-89WNHlSo+hmH8O7sEHDgOpb3MyHON/NmDIl+LiEGMiHHHSrSbU10DSglYWKUk68yjQebxkmfzXcEghbous3LcA==}
     resolution: {integrity: sha512-89WNHlSo+hmH8O7sEHDgOpb3MyHON/NmDIl+LiEGMiHHHSrSbU10DSglYWKUk68yjQebxkmfzXcEghbous3LcA==}
     hasBin: true
     hasBin: true
@@ -2740,6 +2768,9 @@ packages:
       react: '*'
       react: '*'
       react-native: '*'
       react-native: '*'
 
 
+  expo-structured-headers@55.0.2:
+    resolution: {integrity: sha512-KITovrWigTOtsII5hRQ9/3ydaNcxCux5g6O+eTPLyjnye9dpkDKl5GmCLVPVKIL/d7253OtbGtWMD4m0gha5pw==}
+
   expo-symbols@55.0.7:
   expo-symbols@55.0.7:
     resolution: {integrity: sha512-y4ALLbncSGQzhFLw1PaIBbO39xzaw3ie249HmK6zK/WLJYfw4Z/9UU4iPKO3KCE4FyCKIzd+yRsvzvlri23YrQ==}
     resolution: {integrity: sha512-y4ALLbncSGQzhFLw1PaIBbO39xzaw3ie249HmK6zK/WLJYfw4Z/9UU4iPKO3KCE4FyCKIzd+yRsvzvlri23YrQ==}
     peerDependencies:
     peerDependencies:
@@ -2758,6 +2789,19 @@ packages:
       react-native-web:
       react-native-web:
         optional: true
         optional: true
 
 
+  expo-updates-interface@55.1.5:
+    resolution: {integrity: sha512-YOk9vhplWi0djoeqxMlEQgcDFeOGhnj4dWU0v1QvF5RqpqwLGdx780E0k3zL85xw6LXljVN78d6g8z51qIZu5g==}
+    peerDependencies:
+      expo: '*'
+
+  expo-updates@55.0.20:
+    resolution: {integrity: sha512-bRVsm+2ax3rQkErV+YX9uw+2N5DJ7C2S4ETPZPFbnLubSCJtlPuMHZ2SDQvmh3mAOl0yURKkbIMWVCvT89GmIQ==}
+    hasBin: true
+    peerDependencies:
+      expo: '*'
+      react: '*'
+      react-native: '*'
+
   expo-web-browser@55.0.13:
   expo-web-browser@55.0.13:
     resolution: {integrity: sha512-phzsFucUw0uHm0f2f4tJ7ZO3vYnGm0Y7izyWDD71TjP8pyMsvNOh5RKJGLUqk1diSrAFUbHKZYdt6D2b30deiw==}
     resolution: {integrity: sha512-phzsFucUw0uHm0f2f4tJ7ZO3vYnGm0Y7izyWDD71TjP8pyMsvNOh5RKJGLUqk1diSrAFUbHKZYdt6D2b30deiw==}
     peerDependencies:
     peerDependencies:
@@ -6310,6 +6354,22 @@ snapshots:
       - supports-color
       - supports-color
       - typescript
       - typescript
 
 
+  '@expo/config@55.0.15(typescript@5.9.3)':
+    dependencies:
+      '@expo/config-plugins': 55.0.8
+      '@expo/config-types': 55.0.5
+      '@expo/json-file': 10.0.13
+      '@expo/require-utils': 55.0.4(typescript@5.9.3)
+      deepmerge: 4.3.1
+      getenv: 2.0.0
+      glob: 13.0.6
+      resolve-workspace-root: 2.0.1
+      semver: 7.7.4
+      slugify: 1.6.9
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+
   '@expo/devcert@1.2.1':
   '@expo/devcert@1.2.1':
     dependencies:
     dependencies:
       '@expo/sudo-prompt': 9.3.2
       '@expo/sudo-prompt': 9.3.2
@@ -6497,6 +6557,16 @@ snapshots:
     transitivePeerDependencies:
     transitivePeerDependencies:
       - supports-color
       - supports-color
 
 
+  '@expo/require-utils@55.0.4(typescript@5.9.3)':
+    dependencies:
+      '@babel/code-frame': 7.29.0
+      '@babel/core': 7.29.0
+      '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0)
+    optionalDependencies:
+      typescript: 5.9.3
+    transitivePeerDependencies:
+      - supports-color
+
   '@expo/router-server@55.0.13(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo-server@55.0.7)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
   '@expo/router-server@55.0.13(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo-server@55.0.7)(expo@55.0.12)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
     dependencies:
     dependencies:
       debug: 4.4.3
       debug: 4.4.3
@@ -7345,6 +7415,8 @@ snapshots:
       normalize-path: 3.0.0
       normalize-path: 3.0.0
       picomatch: 2.3.2
       picomatch: 2.3.2
 
 
+  arg@4.1.3: {}
+
   arg@5.0.2: {}
   arg@5.0.2: {}
 
 
   argparse@1.0.10:
   argparse@1.0.10:
@@ -8372,6 +8444,8 @@ snapshots:
       expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@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.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@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
       ua-parser-js: 0.7.41
 
 
+  expo-eas-client@55.0.5: {}
+
   expo-file-system@55.0.15(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)):
   expo-file-system@55.0.15(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)):
     dependencies:
     dependencies:
       expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@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.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
@@ -8399,6 +8473,8 @@ snapshots:
     optionalDependencies:
     optionalDependencies:
       react-native-web: 0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
       react-native-web: 0.21.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
 
 
+  expo-json-utils@55.0.2: {}
+
   expo-keep-awake@55.0.6(expo@55.0.12)(react@19.2.0):
   expo-keep-awake@55.0.6(expo@55.0.12)(react@19.2.0):
     dependencies:
     dependencies:
       expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@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.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
@@ -8415,6 +8491,15 @@ snapshots:
       - supports-color
       - supports-color
       - typescript
       - typescript
 
 
+  expo-manifests@55.0.15(expo@55.0.12)(typescript@5.9.3):
+    dependencies:
+      '@expo/config': 55.0.15(typescript@5.9.3)
+      expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
+      expo-json-utils: 55.0.2
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+
   expo-modules-autolinking@55.0.15(typescript@5.9.3):
   expo-modules-autolinking@55.0.15(typescript@5.9.3):
     dependencies:
     dependencies:
       '@expo/require-utils': 55.0.3(typescript@5.9.3)
       '@expo/require-utils': 55.0.3(typescript@5.9.3)
@@ -8495,6 +8580,8 @@ snapshots:
       react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)
       react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)
       react-native-is-edge-to-edge: 1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
       react-native-is-edge-to-edge: 1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)
 
 
+  expo-structured-headers@55.0.2: {}
+
   expo-symbols@55.0.7(expo-font@55.0.6)(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0):
   expo-symbols@55.0.7(expo-font@55.0.6)(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0):
     dependencies:
     dependencies:
       '@expo-google-fonts/material-symbols': 0.4.29
       '@expo-google-fonts/material-symbols': 0.4.29
@@ -8515,6 +8602,33 @@ snapshots:
     transitivePeerDependencies:
     transitivePeerDependencies:
       - supports-color
       - supports-color
 
 
+  expo-updates-interface@55.1.5(expo@55.0.12):
+    dependencies:
+      expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
+
+  expo-updates@55.0.20(expo@55.0.12)(react-native@0.83.4(@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/plist': 0.5.2
+      '@expo/spawn-async': 1.7.2
+      arg: 4.1.3
+      chalk: 4.1.2
+      debug: 4.4.3
+      expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
+      expo-eas-client: 55.0.5
+      expo-manifests: 55.0.15(expo@55.0.12)(typescript@5.9.3)
+      expo-structured-headers: 55.0.2
+      expo-updates-interface: 55.1.5(expo@55.0.12)
+      getenv: 2.0.0
+      glob: 13.0.6
+      ignore: 5.3.2
+      react: 19.2.0
+      react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)
+      resolve-from: 5.0.0
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+
   expo-web-browser@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)):
   expo-web-browser@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)):
     dependencies:
     dependencies:
       expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@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.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.0(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)

+ 13 - 3
src/app/_layout.tsx

@@ -1,17 +1,18 @@
 import '@/global.css';
 import '@/global.css';
-
 import {
 import {
   DefaultTheme as ReactNavigationDefaultTheme,
   DefaultTheme as ReactNavigationDefaultTheme,
   Theme,
   Theme,
   ThemeProvider,
   ThemeProvider,
 } from '@react-navigation/native';
 } from '@react-navigation/native';
+import * as updates from 'expo-updates';
 
 
 import { AnimatedSplashOverlay } from '@/components/animated-icon';
 import { AnimatedSplashOverlay } from '@/components/animated-icon';
 import { AuthProvider } from '@/utils/auth';
 import { AuthProvider } from '@/utils/auth';
-import { Provider } from '@ant-design/react-native';
+import { Provider, Toast } from '@ant-design/react-native';
 import antdDefaultTheme from '@ant-design/react-native/lib/style/themes/default';
 import antdDefaultTheme from '@ant-design/react-native/lib/style/themes/default';
 import { useFonts } from 'expo-font';
 import { useFonts } from 'expo-font';
 import { Stack } from 'expo-router';
 import { Stack } from 'expo-router';
+import { useEffect } from 'react';
 
 
 const antdTheme = antdDefaultTheme;
 const antdTheme = antdDefaultTheme;
 
 
@@ -29,10 +30,17 @@ export const DefaultTheme: Theme = {
 };
 };
 
 
 export default function RootLayout() {
 export default function RootLayout() {
+
+  const up = updates.useUpdates()
   // const colorScheme = useColorScheme();
   // const colorScheme = useColorScheme();
   const [fontsLoaded] = useFonts({
   const [fontsLoaded] = useFonts({
     antoutline: require('@ant-design/icons-react-native/fonts/antoutline.ttf'),
     antoutline: require('@ant-design/icons-react-native/fonts/antoutline.ttf'),
   });
   });
+  useEffect(() => {
+    if (up.isUpdateAvailable) {
+      Toast.loading("版本更新中");
+    }
+  })
 
 
   // useEffect(() => {
   // useEffect(() => {
   //   if (!fontsLoaded) {
   //   if (!fontsLoaded) {
@@ -41,7 +49,9 @@ export default function RootLayout() {
   // }, [fontsLoaded]);
   // }, [fontsLoaded]);
 
 
   if (!fontsLoaded) {
   if (!fontsLoaded) {
-    return null; // 或者返回一个加载中的组件
+    return <Provider theme={antdTheme}>
+      {null}
+      </Provider>; // 或者返回一个加载中的组件
   }
   }
 
 
   return (
   return (

+ 20 - 13
src/app/sign-in.tsx

@@ -2,7 +2,7 @@ import { signIn, useAuthContext } from '@/utils/auth';
 import { Toast } from '@ant-design/react-native';
 import { Toast } from '@ant-design/react-native';
 import { Ionicons } from '@expo/vector-icons';
 import { Ionicons } from '@expo/vector-icons';
 import { router, useLocalSearchParams } from 'expo-router';
 import { router, useLocalSearchParams } from 'expo-router';
-import React, { useState } from 'react';
+import React, { useRef, useState } from 'react';
 import {
 import {
   KeyboardAvoidingView,
   KeyboardAvoidingView,
   Platform,
   Platform,
@@ -30,6 +30,7 @@ export default function SignInScreen({
 }) {
 }) {
   const [authMode, setAuthMode] = useState<'sms' | 'password'>('sms');
   const [authMode, setAuthMode] = useState<'sms' | 'password'>('sms');
   const [agreed, setAgreed] = useState(false);
   const [agreed, setAgreed] = useState(false);
+  const [flushAgree, setFlushAgree] = useState(false);
   const [loading, setLoading] = useState(false);
   const [loading, setLoading] = useState(false);
   const [phone, setPhone] = useState('');
   const [phone, setPhone] = useState('');
   const [code, setCode] = useState('');
   const [code, setCode] = useState('');
@@ -37,7 +38,7 @@ export default function SignInScreen({
 
 
   const { redirectTo } = useLocalSearchParams<{ redirectTo?: string }>();
   const { redirectTo } = useLocalSearchParams<{ redirectTo?: string }>();
   const { setToken } = useAuthContext();
   const { setToken } = useAuthContext();
-
+  const scrollView = useRef<ScrollView>(null);
   const handleSendCode = () => {
   const handleSendCode = () => {
     if (phone.trim().length !== 11) {
     if (phone.trim().length !== 11) {
       Toast.fail('请先输入 11 位手机号');
       Toast.fail('请先输入 11 位手机号');
@@ -47,12 +48,8 @@ export default function SignInScreen({
   };
   };
 
 
   const handleLogin = async () => {
   const handleLogin = async () => {
-    if (!agreed) {
-      Toast.fail('请先阅读并同意协议');
-      callback?.(false);
-      return;
-    }
-
+   
+    setFlushAgree(false);
     if (phone.trim().length !== 11) {
     if (phone.trim().length !== 11) {
       Toast.fail('请输入正确的手机号');
       Toast.fail('请输入正确的手机号');
       callback?.(false);
       callback?.(false);
@@ -71,6 +68,15 @@ export default function SignInScreen({
       return;
       return;
     }
     }
 
 
+     if (!agreed) {
+      Toast.fail('请先阅读并同意协议');
+      // scroll to agree
+      setFlushAgree(true);
+      scrollView.current?.scrollToEnd({animated: true});
+      return;
+    }
+
+
     setLoading(true);
     setLoading(true);
     const toastKey = Toast.loading('正在登录...');
     const toastKey = Toast.loading('正在登录...');
 
 
@@ -102,6 +108,7 @@ export default function SignInScreen({
         behavior={Platform.OS === 'ios' ? 'padding' : undefined}
         behavior={Platform.OS === 'ios' ? 'padding' : undefined}
       >
       >
         <ScrollView
         <ScrollView
+        ref={scrollView}
           className="flex-1"
           className="flex-1"
           contentContainerClassName="px-8 pt-12 pb-10"
           contentContainerClassName="px-8 pt-12 pb-10"
           contentContainerStyle={{ flexGrow: 1 }}
           contentContainerStyle={{ flexGrow: 1 }}
@@ -122,7 +129,7 @@ export default function SignInScreen({
                   欢迎回来
                   欢迎回来
                 </Text>
                 </Text>
                 <Text className="text-base font-medium leading-7 text-on-surface-variant">
                 <Text className="text-base font-medium leading-7 text-on-surface-variant">
-                  登录贷款助手,开启您的财务管理之旅
+                  登录贷款助手,开启您的
                 </Text>
                 </Text>
               </View>
               </View>
 
 
@@ -281,14 +288,14 @@ export default function SignInScreen({
                 ))}
                 ))}
               </View>
               </View>
 
 
-              <View className="flex-row items-start gap-3 px-2">
+              <View className={`flex-row items-start gap-3 px-2 rounded-md border-transparent border-2 transition-colors delay-300 ${flushAgree ? ' border-primary/50' : ''}`}>
                 <Pressable
                 <Pressable
                   onPress={() => setAgreed((value) => !value)}
                   onPress={() => setAgreed((value) => !value)}
                   hitSlop={8}
                   hitSlop={8}
                   className="pt-1"
                   className="pt-1"
                 >
                 >
                   <View
                   <View
-                    className={`h-6 w-6 items-center justify-center rounded-full border ${
+                    className={`h-6 w-6 items-center justify-center rounded-full cursor-pointer ${
                       agreed
                       agreed
                         ? 'border-primary bg-primary'
                         ? 'border-primary bg-primary'
                         : 'border-outline-variant bg-surface-container-low'
                         : 'border-outline-variant bg-surface-container-low'
@@ -301,9 +308,9 @@ export default function SignInScreen({
                 </Pressable>
                 </Pressable>
                 <Text className="flex-1 text-sm leading-7 text-on-surface-variant">
                 <Text className="flex-1 text-sm leading-7 text-on-surface-variant">
                   登录即代表您已阅读并同意
                   登录即代表您已阅读并同意
-                  <Text className="font-semibold text-primary">《用户服务协议》</Text>
+                  <Text className="font-semibold text-primary cursor-pointer">《用户服务协议》</Text>
-                  <Text className="font-semibold text-primary">《隐私政策》</Text>
+                  <Text className="font-semibold text-primary cursor-pointer">《隐私政策》</Text>
                   ,以及授权该应用获取您的公开信息。
                   ,以及授权该应用获取您的公开信息。
                 </Text>
                 </Text>
               </View>
               </View>