diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index a149e47..add2c83 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -1,50 +1,133 @@ -name: Build preview for pull requests +name: Manual Expo Preview on: - push: - # REQUIRED: push main(default) branch is necessary for this action to update its fingerprint database - branches: [master] - pull_request: - types: [opened, synchronize] + issue_comment: + types: [created] + +permissions: + contents: read + pull-requests: write + issues: write jobs: - build: + check_permissions: runs-on: ubuntu-latest - # REQUIRED: limit concurrency when pushing main(default) branch to prevent conflict for this action to update its fingerprint database - concurrency: fingerprint-${{ github.event_name != 'pull_request' && 'master' || github.run_id }} - permissions: - # REQUIRED: Allow comments of PRs - pull-requests: write # Allow comments on PRs - # REQUIRED: Allow updating fingerprint in acton caches - actions: write - # Following permissions are required for private repos - contents: read - packages: write + if: github.event_name == 'issue_comment' && contains(github.event.comment.body, '/preview') && github.event.issue.pull_request + outputs: + has_permissions: ${{ steps.check.outputs.has_permissions }} + pr_number: ${{ steps.get_pr_details.outputs.pr_number }} + pr_head_ref: ${{ steps.get_pr_details.outputs.pr_head_ref }} steps: - - name: Checkout code - uses: actions/checkout@v4 + - name: Get PR details + id: get_pr_details + uses: actions/github-script@v7 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + const { data: pullRequest } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + core.setOutput('pr_number', pullRequest.number); + core.setOutput('pr_head_ref', pullRequest.head.ref); - - name: 🏗 Setup EAS - uses: expo/expo-github-action@v8 + - name: Check permissions + id: check + uses: actions/github-script@v7 with: - eas-version: latest - token: ${{ secrets.EXPO_TOKEN }} + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: context.payload.comment.user.login + }); + const hasPermissions = ['admin', 'write'].includes(permission.permission); + core.setOutput('has_permissions', hasPermissions); + + preview: + needs: check_permissions + if: needs.check_permissions.outputs.has_permissions == 'true' + runs-on: ubuntu-latest + steps: + - name: Get PR details + uses: actions/github-script@v7 + id: pr-details + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + const { data: pr } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: ${{ needs.check_permissions.outputs.pr_number }} + }); + core.setOutput('head_sha', pr.head.sha); + core.setOutput('head_repo', pr.head.repo.full_name); + core.setOutput('head_ref', pr.head.ref); + + - uses: actions/checkout@v4 + with: + repository: ${{ steps.pr-details.outputs.head_repo }} + ref: ${{ steps.pr-details.outputs.head_ref }} + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' - name: Install dependencies run: npm install - - name: 🚀 Create preview - if: ${{ github.event_name == 'pull_request' }} + - name: Setup Expo + uses: expo/expo-github-action@v8 + with: + eas-version: latest + eas-cache: true + expo-version: latest + expo-cache: true + packager: npm + token: ${{ secrets.EXPO_TOKEN }} + + - name: Create preview + id: preview uses: expo/expo-github-action/preview@v8 with: - command: eas update --auto --branch ${{ github.event.pull_request.head.ref }} - comment: true + comment: false qr-target: 'expo-go' - working-directory: ${{ github.workspace }} github-token: ${{ secrets.GITHUB_TOKEN }} + command: eas update --auto --branch pr-${{ needs.check_permissions.outputs.pr_head_ref }} - - name: Create preview builds if needed - uses: expo/expo-github-action/preview-build@main + - name: Find Comment + uses: peter-evans/find-comment@v3 + id: find_comment with: - command: eas build --profile development --platform all + issue-number: ${{ needs.check_permissions.outputs.pr_number }} + comment-author: 'github-actions[bot]' + body-includes: Expo Preview + - name: Create or Update Comment + uses: peter-evans/create-or-update-comment@v4 + with: + issue-number: ${{ needs.check_permissions.outputs.pr_number }} + comment-id: ${{ steps.find_comment.outputs.comment-id }} + body: | + ## Expo Preview + ${{steps.preview.outputs.comment}} + > Commit hash: ${{steps.preview.outputs.gitCommitHash}} + > Update published at: ${{steps.preview.outputs.createdAt}} + edit-mode: replace + + pr_comment: + needs: check_permissions + if: needs.check_permissions.outputs.has_permissions != 'true' + runs-on: ubuntu-latest + steps: + - name: Comment on PR (insufficient permissions) + uses: peter-evans/create-or-update-comment@v4 + with: + issue-number: ${{ needs.check_permissions.outputs.pr_number }} + body: | + Sorry, you do not have the required permissions to trigger an Expo preview. + Please ask a maintainer to review and trigger the preview if necessary. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e037f7..6e73ae7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,60 +29,18 @@ jobs: - name: Install npm dependencies run: | npm install && npx expo prebuild --platform android - - name: Build Android Release run: | cd android && ./gradlew assembleRelease mv app/build/outputs/apk/release/app-release.apk app/build/outputs/apk/release/casdoorapp.apk - - name: Upload Artifact uses: actions/upload-artifact@v4 with: name: casdoorapp.apk path: android/app/build/outputs/apk/release/ - - build-ipa: - runs-on: macos-14 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: set up JDK 18 - uses: actions/setup-java@v4 - with: - java-version: 18 - distribution: temurin - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - - name: Install dependencies - run: npm install && npx expo prebuild --platform ios - - - name: Pod Install - run: cd ios && rm Podfile.lock && pod install --repo-update - - - name: build - run: cd ios && xcodebuild -scheme casdoorapp -workspace casdoorapp.xcworkspace -configuration Release clean archive -archivePath "build/casdoorapp.xcarchive" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO - - - name: archive to ipa - run: | - cd ios - mkdir build/Payload - mv build/casdoorapp.xcarchive/Products/Applications/casdoorapp.app build/Payload/casdoorapp.app - cd build - zip -r casdoorapp.ipa Payload/ - - - name: Update artifact - uses: actions/upload-artifact@v4 - with: - name: casdoorapp.ipa - path: ios/build/casdoorapp.ipa semantic-release: - needs: [build-ipa, build-apk] + needs: [build-apk] runs-on: ubuntu-latest steps: - name: Checkout code @@ -92,12 +50,6 @@ jobs: with: node-version: 20.x - - name: Download iOS build artifacts - uses: actions/download-artifact@v4 - with: - name: casdoorapp.ipa - path: release/ios/ - - name: Download Android build artifacts uses: actions/download-artifact@v4 with: diff --git a/README.md b/README.md index 3d3796e..485b7b8 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,35 @@ cd casdoor-app npm install && npm run start ``` +## Installation + +You can download the latest version of the Casdoor Authenticator App from the GitHub Releases page. + +- Android: Download and install the APK file directly on your device. + +### Building from Source + +If you prefer to build the app yourself, follow these steps: + +### Common Steps + +```bash +git clone git@github.com:casdoor/casdoor-app.git +cd casdoor-app +npm install +``` + +### android build + + ```bash + npm install && npx expo prebuild --platform android + cd android && ./gradlew assembleRelease + ``` + + The APK file in the `app/build/outputs/apk/release/` directory. + +Note: You'll need to have the necessary development environments set up for React Native, Android. Refer to the React Native documentation for detailed setup instructions. + ## Usage - Open the app on your mobile device. diff --git a/app.json b/app.json index 02e03f8..6c06744 100644 --- a/app.json +++ b/app.json @@ -48,4 +48,4 @@ ], "owner": "zzbs" } -} +} \ No newline at end of file diff --git a/eas.json b/eas.json index 96bf9bf..b64945e 100644 --- a/eas.json +++ b/eas.json @@ -1,45 +1,45 @@ { - "cli": { - "version": ">= 10.2.1" - }, - "build": { - "base": { - "android": { - "image": "latest", - "buildType": "apk" - }, - "ios": { - "image": "latest", - "simulator": true - } + "cli": { + "version": ">= 10.2.1" }, - "development": { - "extends": "base", - "channel": "development", - "developmentClient": true, - "distribution": "internal", - "android": { - "withoutCredentials": true - }, - "ios": { - "buildConfiguration": "Debug" - } + "build": { + "base": { + "android": { + "image": "latest", + "buildType": "apk" + }, + "ios": { + "image": "latest", + "simulator": true + } + }, + "development": { + "extends": "base", + "channel": "development", + "developmentClient": true, + "distribution": "internal", + "android": { + "withoutCredentials": true + }, + "ios": { + "buildConfiguration": "Debug" + } + }, + "preview": { + "extends": "base", + "channel": "preview", + "distribution": "internal", + "ios": { + "simulator": true + } + }, + "production": { + "extends": "base", + "channel": "production", + "autoIncrement": true + } }, - "preview": { - "extends": "base", - "channel": "preview", - "distribution": "internal", - "ios": { - "simulator": true - } - }, - "production": { - "extends": "base", - "channel": "production", - "autoIncrement": true + "submit": { + "production": {} } - }, - "submit": { - "production": {} - } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8305466..b130c7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,16 +8,19 @@ "name": "casdoor-app", "version": "1.0.0", "dependencies": { + "@react-native-async-storage/async-storage": "1.23.1", + "@react-native-community/masked-view": "^0.1.11", "@react-native-community/netinfo": "11.3.1", "@react-navigation/bottom-tabs": "^6.5.8", "@react-navigation/native": "^6.1.7", "casdoor-react-native-sdk": "1.1.0", "eslint-plugin-import": "^2.28.1", - "expo": "~51.0.22", + "expo": "~51.0.24", "expo-camera": "~15.0.14", - "expo-dev-client": "~4.0.20", + "expo-dev-client": "^4.0.21", "expo-image": "^1.12.13", "expo-status-bar": "~1.12.1", + "expo-system-ui": "~3.0.7", "expo-updates": "~0.25.21", "hotp-totp": "^1.0.6", "prop-types": "^15.8.1", @@ -27,7 +30,10 @@ "react-native-countdown-circle-timer": "^3.2.1", "react-native-gesture-handler": "~2.16.1", "react-native-paper": "^5.10.3", + "react-native-reanimated": "~3.10.1", "react-native-root-toast": "^3.6.0", + "react-native-safe-area-context": "4.10.5", + "react-native-screens": "^3.31.1", "react-native-svg": "15.2.0", "react-native-web": "~0.19.6", "react-native-webview": "13.8.6", @@ -1457,7 +1463,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -1538,7 +1543,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", @@ -1798,7 +1802,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, @@ -2375,9 +2378,9 @@ } }, "node_modules/@expo/cli": { - "version": "0.18.25", - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.18.25.tgz", - "integrity": "sha512-Kh0uZGCxwu58Pu7Jto9T/ABlBR7nkx8QC0Wv8pI3YtISyQZIKtbtNNeTPWYbVK1ddswKwtBUj+MNhKoDL49TLg==", + "version": "0.18.26", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.18.26.tgz", + "integrity": "sha512-u9bTTXgcjaTloE9CHwxgrb8Me/Al4jiPykbVQpJydakH3GsIZfHy1zaLc7O39CoLjRz37WWi6Y5ZdgtQw9dCPQ==", "dependencies": { "@babel/runtime": "^7.20.0", "@expo/code-signing-certificates": "0.0.5", @@ -3205,9 +3208,9 @@ } }, "node_modules/@expo/metro-config": { - "version": "0.18.9", - "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.18.9.tgz", - "integrity": "sha512-kcqT/wuO43zxuFeR5AR/pMuq/O9qtIyuTI1wYvBY97blHAYU/wfPJKW3xFL14fDkPqQOc87hEEhjlJiXoebvcw==", + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.18.10.tgz", + "integrity": "sha512-HTYQqKfV0JSuRp5aDvrPHezj5udXOWoXqHOjfTSnce2m13j6D0yYXTJNaKRhlgpPBrkg5DL7z1fL3zwDUpLM4w==", "dependencies": { "@babel/core": "^7.20.0", "@babel/generator": "^7.20.5", @@ -5569,6 +5572,16 @@ "node": ">=8" } }, + "node_modules/@react-native-community/masked-view": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@react-native-community/masked-view/-/masked-view-0.1.11.tgz", + "integrity": "sha512-rQfMIGSR/1r/SyN87+VD8xHHzDYeHaJq6elOSCAD+0iLagXkSI2pfA0LmSXP21uw5i3em7GkkRjfJ8wpqWXZNw==", + "deprecated": "Repository was moved to @react-native-masked-view/masked-view", + "peerDependencies": { + "react": ">=16.0", + "react-native": ">=0.57" + } + }, "node_modules/@react-native-community/netinfo": { "version": "11.3.1", "resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-11.3.1.tgz", @@ -7458,20 +7471,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cacache/node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -8205,6 +8204,62 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/del/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/del/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -9165,15 +9220,15 @@ } }, "node_modules/expo": { - "version": "51.0.22", - "resolved": "https://registry.npmjs.org/expo/-/expo-51.0.22.tgz", - "integrity": "sha512-AtdqmtKNRC+cRBTsYGfwQFMLWAWWC531V2V+bAO3S9wVSTP2eLh34V06/IsBIjCCAJQPaaeR05XcST8U3apXFw==", + "version": "51.0.24", + "resolved": "https://registry.npmjs.org/expo/-/expo-51.0.24.tgz", + "integrity": "sha512-HoOuNIWXzS6Gxifcb0N+qRt5K6iR9YitQaWIVNB8elyupvQdyI566IMgMBiO45NgpO5es0sfFNNBasxBHLkbUw==", "dependencies": { "@babel/runtime": "^7.20.0", - "@expo/cli": "0.18.25", + "@expo/cli": "0.18.26", "@expo/config": "9.0.3", "@expo/config-plugins": "8.0.8", - "@expo/metro-config": "0.18.9", + "@expo/metro-config": "0.18.10", "@expo/vector-icons": "^14.0.0", "babel-preset-expo": "~11.0.12", "expo-asset": "~10.0.10", @@ -9181,7 +9236,7 @@ "expo-font": "~12.0.9", "expo-keep-awake": "~13.0.2", "expo-modules-autolinking": "1.11.1", - "expo-modules-core": "1.12.19", + "expo-modules-core": "1.12.20", "fbemitter": "^3.0.0", "whatwg-url-without-unicode": "8.0.0-3" }, @@ -9226,12 +9281,12 @@ } }, "node_modules/expo-dev-client": { - "version": "4.0.20", - "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-4.0.20.tgz", - "integrity": "sha512-lSr5PoJSqXD2srzWyPY3sb8kcwRaLWNCVemdQryW796tglm6sTnSbRhmUGtUPvrm6Bk+rZAmQNFsqKh1sjHfqg==", + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-4.0.21.tgz", + "integrity": "sha512-+zuVsKyp5tXTQUwDnTjtaOLf3TdmZ483Il9slg/LO15EsEFpl0zwI42DrQpzYmv617cgvywmp6iybGXjV3eZbQ==", "dependencies": { - "expo-dev-launcher": "4.0.22", - "expo-dev-menu": "5.0.16", + "expo-dev-launcher": "4.0.23", + "expo-dev-menu": "5.0.17", "expo-dev-menu-interface": "1.8.3", "expo-manifests": "~0.14.0", "expo-updates-interface": "~0.16.2" @@ -9241,12 +9296,12 @@ } }, "node_modules/expo-dev-launcher": { - "version": "4.0.22", - "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-4.0.22.tgz", - "integrity": "sha512-U8SR4MphP+QatjmD+sQ7AWtKwy7faPpW2PcaPBPnfzBiDc3yk8Kc2sf6/JyN7bUmvA6PFqTnsSJMlZEWi917OQ==", + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-4.0.23.tgz", + "integrity": "sha512-XG9VyFUoslBsBpJqtuOsen93u3hEw4rK7VSNqz8g+d8+AmHBv2rSuQheirPfxuSrLqGm49/ybWkHYqfs8CdlQw==", "dependencies": { "ajv": "8.11.0", - "expo-dev-menu": "5.0.16", + "expo-dev-menu": "5.0.17", "expo-manifests": "~0.14.0", "resolve-from": "^5.0.0", "semver": "^7.6.0" @@ -9287,9 +9342,9 @@ } }, "node_modules/expo-dev-menu": { - "version": "5.0.16", - "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-5.0.16.tgz", - "integrity": "sha512-zsUiVCvVWT9ve5EsYEGHGu0dJac13NoEQkmzOjhmvcQXb7+OnKgwtBiNAX6rvponfnx9il506rnyZ+0M9CbwYQ==", + "version": "5.0.17", + "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-5.0.17.tgz", + "integrity": "sha512-BnFSd6PKDaJenRKn2C4X50dWyqvvkVz9pE/6IKuUvGIsshkk9pCoZvsFOlJjM61/ojz1KXyY9O1FUPPI7B1A7w==", "dependencies": { "expo-dev-menu-interface": "1.8.3", "semver": "^7.5.4" @@ -9487,9 +9542,9 @@ } }, "node_modules/expo-modules-core": { - "version": "1.12.19", - "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.12.19.tgz", - "integrity": "sha512-fFsErN4oMsOdStUVYvyLpl6MX/wbD9yJSqy/Lu7ZRLIPzeKDfGS2jNl8RzryPznRpWmy49X8l40R4osRJLizhg==", + "version": "1.12.20", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.12.20.tgz", + "integrity": "sha512-CCXjlgT8lDAufgt912P1W7TwD+KAylfIttc1Doh1a0hAfkdkUsDRmrgthnYrrxEo2ECVpbaB71Epp1bnZ1rRrA==", "dependencies": { "invariant": "^2.2.4" } @@ -9504,6 +9559,18 @@ "resolved": "https://registry.npmjs.org/expo-structured-headers/-/expo-structured-headers-3.8.0.tgz", "integrity": "sha512-R+gFGn0x5CWl4OVlk2j1bJTJIz4KO8mPoCHpRHmfqMjmrMvrOM0qQSY3V5NHXwp1yT/L2v8aUmFQsBRIdvi1XA==" }, + "node_modules/expo-system-ui": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-3.0.7.tgz", + "integrity": "sha512-KAs72F5JKhdIfPR9ZNVlRubTPK9uUuevPy5oYEp12xNEzSQcjZKvypH5NpwJuNWkXzrp3n3vZ+3pXsudA7J3KA==", + "dependencies": { + "@react-native/normalize-colors": "0.74.85", + "debug": "^4.3.2" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-updates": { "version": "0.25.21", "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-0.25.21.tgz", @@ -10905,6 +10972,14 @@ "node": ">=6" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -13532,6 +13607,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -13804,9 +13893,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.40", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", + "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", "funding": [ { "type": "opencollective", @@ -14167,7 +14256,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.3.tgz", "integrity": "sha512-ZnXwLQnGzrDpHBHiC56TXFXvmolPeMjTn1UOm610M4EXGzbEDR7oOIyS2ZiItgbs6eZc4oU/a0hpk8PrcKvv5g==", - "peer": true, "engines": { "node": ">=10" }, @@ -14307,6 +14395,26 @@ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" }, + "node_modules/react-native-reanimated": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.10.1.tgz", + "integrity": "sha512-sfxg6vYphrDc/g4jf/7iJ7NRi+26z2+BszPmvmk0Vnrz6FL7HYljJqTf531F1x6tFmsf+FEAmuCtTUIXFLVo9w==", + "dependencies": { + "@babel/plugin-transform-arrow-functions": "^7.0.0-0", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", + "@babel/plugin-transform-optional-chaining": "^7.0.0-0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", + "@babel/plugin-transform-template-literals": "^7.0.0-0", + "@babel/preset-typescript": "^7.16.7", + "convert-source-map": "^2.0.0", + "invariant": "^2.2.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0", + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-root-siblings": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/react-native-root-siblings/-/react-native-root-siblings-4.1.1.tgz", @@ -14326,20 +14434,18 @@ } }, "node_modules/react-native-safe-area-context": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.7.2.tgz", - "integrity": "sha512-5fy/hRNJ7bI/U2SliOeKf0D80J4lXPc1NsRiNS7Xaz8YTnqlzWib1ViItkwKPfufe54YKzVBMmM32RpdzvO2gg==", - "peer": true, + "version": "4.10.5", + "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.10.5.tgz", + "integrity": "sha512-Wyb0Nqw2XJ6oZxW/cK8k5q7/UAhg/wbEG6UVf89rQqecDZTDA5ic//P9J6VvJRVZerzGmxWQpVuM7f+PRYUM4g==", "peerDependencies": { "react": "*", "react-native": "*" } }, "node_modules/react-native-screens": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.25.0.tgz", - "integrity": "sha512-TSC2Ad0hh763I8QT6XxMsPXAagQ+RawDSdFtKRvIz9fCYr96AjRwwaqmYivbqlDywOgcRBkIVynkFtp0ThmlYw==", - "peer": true, + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.33.0.tgz", + "integrity": "sha512-3bKeT/kS1g/6XqraBqjDtyyci35LDeDIHMoko74o+Z5p1oLEi697GWFVwsG272FF0iuOullUbuRNzCcEfRBASQ==", "dependencies": { "react-freeze": "^1.0.0", "warn-once": "^0.1.0" @@ -14924,6 +15030,7 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dependencies": { "glob": "^7.1.3" }, @@ -14935,6 +15042,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -15854,55 +15962,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tempy/node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/tempy/node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/tempy/node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -15914,35 +15973,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tempy/node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/tempy/node_modules/type-fest": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", @@ -16803,9 +16833,9 @@ } }, "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index 14c2aee..d381463 100644 --- a/package.json +++ b/package.json @@ -10,15 +10,19 @@ "release": "npx -p semantic-release-expo -p semantic-release -p @semantic-release/git -p @semantic-release/changelog -p @semantic-release/exec semantic-release" }, "dependencies": { + "@react-native-async-storage/async-storage": "1.23.1", + "@react-native-community/masked-view": "^0.1.11", "@react-native-community/netinfo": "11.3.1", "@react-navigation/bottom-tabs": "^6.5.8", "@react-navigation/native": "^6.1.7", "casdoor-react-native-sdk": "1.1.0", "eslint-plugin-import": "^2.28.1", - "expo": "~51.0.22", + "expo": "~51.0.24", "expo-camera": "~15.0.14", + "expo-dev-client": "^4.0.21", "expo-image": "^1.12.13", "expo-status-bar": "~1.12.1", + "expo-system-ui": "~3.0.7", "expo-updates": "~0.25.21", "hotp-totp": "^1.0.6", "prop-types": "^15.8.1", @@ -28,7 +32,10 @@ "react-native-countdown-circle-timer": "^3.2.1", "react-native-gesture-handler": "~2.16.1", "react-native-paper": "^5.10.3", + "react-native-reanimated": "~3.10.1", "react-native-root-toast": "^3.6.0", + "react-native-safe-area-context": "4.10.5", + "react-native-screens": "^3.31.1", "react-native-svg": "15.2.0", "react-native-web": "~0.19.6", "react-native-webview": "13.8.6", @@ -85,6 +92,52 @@ ] ] }, + "verifyConditions": [ + "semantic-release-expo", + "@semantic-release/changelog", + "@semantic-release/git" + ], + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "semantic-release-expo", + { + "versions": { + "version": "${next.raw}", + "android": "${code}", + "ios": "${next.raw}" + } + } + ], + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + [ + "@semantic-release/git", + { + "assets": [ + "package.json", + "package-lock.json", + "app.json" + ], + "message": "chore(release): ${nextRelease.version} [skip ci]" + } + ], + [ + "@semantic-release/github", + { + "assets": [ + { + "path": "release/android/*.apk", + "label": "Android" + } + ] + } + ] + ] + }, "devDependencies": { "@babel/core": "^7.24.0", "@babel/eslint-parser": "^7.18.9", diff --git a/useNetworkStatus.js b/useNetworkStatus.js deleted file mode 100644 index 34f9fba..0000000 --- a/useNetworkStatus.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2024 The Casdoor Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import {useEffect, useState} from "react"; -import NetInfo from "@react-native-community/netinfo"; - -const useNetworkStatus = () => { - const [isConnected, setIsConnected] = useState(false); - - useEffect(() => { - const unsubscribe = NetInfo.addEventListener(state => { - setIsConnected(state.isConnected); - }); - return () => unsubscribe(); - }, []); - - return isConnected; -}; - -export default useNetworkStatus; diff --git a/useSync.js b/useSync.js index 49f869c..812869c 100644 --- a/useSync.js +++ b/useSync.js @@ -14,7 +14,7 @@ import {useCallback, useEffect, useState} from "react"; import * as api from "./api"; -import useNetworkStatus from "./useNetworkStatus"; +import {useNetInfo} from "@react-native-community/netinfo"; export const SYNC_STATUS = { ADD: "add", @@ -48,7 +48,7 @@ const applySync = (serverAccountList, toSyncData) => { const useSync = (userInfo, token, casdoorServer) => { const [toSyncData, setToSyncData] = useState([]); const [syncSignal, setSyncSignal] = useState(false); - const isConnected = useNetworkStatus(); + const {isConnected} = useNetInfo(); const [canSync, setCanSync] = useState(false); useEffect(() => {