Browse Source

feat: 添加发布到Google Play Store ci

lwxzks 4 months ago
parent
commit
b50ae014d4
5 changed files with 119 additions and 76 deletions
  1. 6 1
      eas.json
  2. 24 0
      package-lock.json
  3. 72 71
      package.json
  4. 13 0
      service-account-file.json
  5. 4 4
      util/index.ts

+ 6 - 1
eas.json

@@ -33,6 +33,11 @@
         }
     },
     "submit": {
-        "production": {}
+        "production": {
+            "android": {
+                "serviceAccountKeyPath": "./service-account-file.json",
+                "track": "production"
+            }
+        }
     }
 }

+ 24 - 0
package-lock.json

@@ -11,6 +11,7 @@
       "dependencies": {
         "@gorhom/bottom-sheet": "^5.1.8",
         "@react-native-async-storage/async-storage": "2.2.0",
+        "@react-native-clipboard/clipboard": "^1.16.3",
         "@shopify/flash-list": "2.0.2",
         "@tanstack/react-query": "^5.85.0",
         "@types/lodash": "^4.17.20",
@@ -2586,6 +2587,29 @@
         "react-native": "^0.0.0-0 || >=0.65 <1.0"
       }
     },
+    "node_modules/@react-native-clipboard/clipboard": {
+      "version": "1.16.3",
+      "resolved": "https://registry.npmmirror.com/@react-native-clipboard/clipboard/-/clipboard-1.16.3.tgz",
+      "integrity": "sha512-cMIcvoZKIrShzJHEaHbTAp458R9WOv0fB6UyC7Ek4Qk561Ow/DrzmmJmH/rAZg21Z6ixJ4YSdFDC14crqIBmCQ==",
+      "license": "MIT",
+      "workspaces": [
+        "example"
+      ],
+      "peerDependencies": {
+        "react": ">= 16.9.0",
+        "react-native": ">= 0.61.5",
+        "react-native-macos": ">= 0.61.0",
+        "react-native-windows": ">= 0.61.0"
+      },
+      "peerDependenciesMeta": {
+        "react-native-macos": {
+          "optional": true
+        },
+        "react-native-windows": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@react-native/assets-registry": {
       "version": "0.79.5",
       "resolved": "https://registry.npmmirror.com/@react-native/assets-registry/-/assets-registry-0.79.5.tgz",

+ 72 - 71
package.json

@@ -1,73 +1,74 @@
 {
-  "name": "template",
-  "version": "1.0.0",
-  "main": "expo-router/entry",
-  "scripts": {
-    "start": "expo start --dev-client",
-    "android": "expo run:android",
-    "ios": "expo run:ios",
-    "web": "expo start --web",
-    "postinstall": "patch-package"
-  },
-  "dependencies": {
-    "@gorhom/bottom-sheet": "^5.1.8",
-    "@react-native-async-storage/async-storage": "2.2.0",
-    "@shopify/flash-list": "2.0.2",
-    "@tanstack/react-query": "^5.85.0",
-    "@types/lodash": "^4.17.20",
-    "@types/react-native-datepicker": "^1.7.6",
-    "axios": "^1.11.0",
-    "crypto-js": "^4.2.0",
-    "date-fns": "4.1.0",
-    "date-fns-tz": "^3.2.0",
-    "dotenv": "^17.2.1",
-    "expo": "^53.0.0",
-    "expo-camera": "~16.1.11",
-    "expo-checkbox": "~4.1.4",
-    "expo-constants": "~17.1.7",
-    "expo-dev-client": "~5.2.4",
-    "expo-device": "~7.1.4",
-    "expo-env": "^1.1.1",
-    "expo-file-system": "~18.1.11",
-    "expo-image-picker": "~16.1.4",
-    "expo-linking": "~7.1.7",
-    "expo-location": "~18.1.6",
-    "expo-notifications": "~0.31.4",
-    "expo-router": "~5.1.4",
-    "expo-secure-store": "~14.2.3",
-    "expo-status-bar": "~2.2.3",
-    "expo-updates": "~0.28.17",
-    "lodash": "^4.17.21",
-    "nativewind": "^4.1.23",
-    "prettier-plugin-tailwindcss": "^0.6.14",
-    "react": "19.0.0",
-    "react-native": "0.79.5",
-    "react-native-element-dropdown": "^2.12.4",
-    "react-native-gesture-handler": "~2.28.0",
-    "react-native-keyboard-aware-scroll-view": "^0.9.5",
-    "react-native-maps": "1.20.1",
-    "react-native-modal": "14.0.0-rc.1",
-    "react-native-modern-datepicker": "^1.0.0-beta.91",
-    "react-native-pager-view": "^6.9.1",
-    "react-native-reanimated": "~3.17.4",
-    "react-native-responsive-screen": "^1.4.2",
-    "react-native-safe-area-context": "5.6.0",
-    "react-native-screens": "~4.13.1",
-    "react-native-svg": "15.12.1",
-    "react-native-tab-view": "4.1.3",
-    "react-native-webview": "13.15.0",
-    "zustand": "^4.5.2"
-  },
-  "devDependencies": {
-    "@babel/core": "^7.28.0",
-    "@types/crypto-js": "^4.2.2",
-    "@types/react": "~19.0.10",
-    "@types/react-native-modern-datepicker": "^1.0.5",
-    "lightningcss": "^1.30.1",
-    "patch-package": "^8.0.0",
-    "postinstall-postinstall": "^2.1.0",
-    "tailwindcss": "^3.4.17",
-    "typescript": "~5.9.2"
-  },
-  "private": true
+    "name": "template",
+    "version": "1.0.0",
+    "main": "expo-router/entry",
+    "scripts": {
+        "start": "expo start --dev-client",
+        "android": "expo run:android",
+        "ios": "expo run:ios",
+        "web": "expo start --web",
+        "postinstall": "patch-package"
+    },
+    "dependencies": {
+        "@gorhom/bottom-sheet": "^5.1.8",
+        "@react-native-async-storage/async-storage": "2.2.0",
+        "@react-native-clipboard/clipboard": "^1.16.3",
+        "@shopify/flash-list": "2.0.2",
+        "@tanstack/react-query": "^5.85.0",
+        "@types/lodash": "^4.17.20",
+        "@types/react-native-datepicker": "^1.7.6",
+        "axios": "^1.11.0",
+        "crypto-js": "^4.2.0",
+        "date-fns": "4.1.0",
+        "date-fns-tz": "^3.2.0",
+        "dotenv": "^17.2.1",
+        "expo": "^53.0.0",
+        "expo-camera": "~16.1.11",
+        "expo-checkbox": "~4.1.4",
+        "expo-constants": "~17.1.7",
+        "expo-dev-client": "~5.2.4",
+        "expo-device": "~7.1.4",
+        "expo-env": "^1.1.1",
+        "expo-file-system": "~18.1.11",
+        "expo-image-picker": "~16.1.4",
+        "expo-linking": "~7.1.7",
+        "expo-location": "~18.1.6",
+        "expo-notifications": "~0.31.4",
+        "expo-router": "~5.1.4",
+        "expo-secure-store": "~14.2.3",
+        "expo-status-bar": "~2.2.3",
+        "expo-updates": "~0.28.17",
+        "lodash": "^4.17.21",
+        "nativewind": "^4.1.23",
+        "prettier-plugin-tailwindcss": "^0.6.14",
+        "react": "19.0.0",
+        "react-native": "0.79.5",
+        "react-native-element-dropdown": "^2.12.4",
+        "react-native-gesture-handler": "~2.28.0",
+        "react-native-keyboard-aware-scroll-view": "^0.9.5",
+        "react-native-maps": "1.20.1",
+        "react-native-modal": "14.0.0-rc.1",
+        "react-native-modern-datepicker": "^1.0.0-beta.91",
+        "react-native-pager-view": "^6.9.1",
+        "react-native-reanimated": "~3.17.4",
+        "react-native-responsive-screen": "^1.4.2",
+        "react-native-safe-area-context": "5.6.0",
+        "react-native-screens": "~4.13.1",
+        "react-native-svg": "15.12.1",
+        "react-native-tab-view": "4.1.3",
+        "react-native-webview": "13.15.0",
+        "zustand": "^4.5.2"
+    },
+    "devDependencies": {
+        "@babel/core": "^7.28.0",
+        "@types/crypto-js": "^4.2.2",
+        "@types/react": "~19.0.10",
+        "@types/react-native-modern-datepicker": "^1.0.5",
+        "lightningcss": "^1.30.1",
+        "patch-package": "^8.0.0",
+        "postinstall-postinstall": "^2.1.0",
+        "tailwindcss": "^3.4.17",
+        "typescript": "~5.9.2"
+    },
+    "private": true
 }

+ 13 - 0
service-account-file.json

@@ -0,0 +1,13 @@
+{
+    "type": "service_account",
+    "project_id": "crazy-charge-469006",
+    "private_key_id": "619cff535b6096967a5a4b72d7f312a3b1bfc294",
+    "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDDIb+7eMTk3lor\nE9hFHkbFcZQHi5N2Gdfq0L/TPPfo9Jj7N0ZBG5mmGRDglMSV3WQubQWO0BlsAJN6\n3jVmeydirBW92MTKaRWh9F99yxcI5aV0APgdJmhaqP7SSfQkzizAejYVHF1Vu6zq\nXvkgjofXX4cimeGoUdz8wQ5093/2D6wQTw9UgCCRpsS4RsQizKqoVbx+UqbO9XwL\nqimVIoJl7z+rZcHNnrBQCHq7ckCaoCWCYe84kpaYlWE6DjY0x4pUu46BTcX5/rYp\npBw9tKcG9LJm68FzUyGZnh/JdIzbXA+gpY3WKXCvMplM4ZSx82KmjoOPt+qcpcXO\nrzYn+d7zAgMBAAECggEAQ2BS2MOhkLkp/zfR9EO5AhHuoBBUsXHI+R5tLd4eZ8SV\nUiDK1E5YZl6/UhxsKKcSIWmpgp9eN8mXItS5MZKSjeKHe07u3EkenBZKJqBKatsI\nnx56jW4mmC9EFY5Ni6vZDfjk1bM+kwzDbwWuFczBIN+uRIdHwJvLp0Zt3HtdJrO1\npVb27WIH46KZfiGwi+zBQHiEXQKaXW7aNUGGEAAdU9BpugcaRLnnDum/xyd+w9xY\npENl1qIHYxiZjc4JFvuvkzVIah0Vx9CYOXs+3uy9hbGy7LK23Kq49xa6ZLr0Aw7z\n7Rb+M65ifj/sodaE8BeczdE8o40SluV6EIBc6pPo2QKBgQD0toaylvWWn8JM4HsW\nzer2gB+3eOMZ9D2imMzL5AAwVxNxIs/fjY4xJ/M2W0XJzmAxbcPFfgcOtFBzYtQg\nUmr956GgNNzodIwNwCpS36JHKrifrXll21EjiMG3Wae24YWfcOcqcaeQDIMo8uQb\nqkEqSPKPMPRu8r5coZRYjiiJ5wKBgQDMIcnDFZzZ9CB7Ua3NpUd2IDQ+0B5L7dtu\nvnjTEZ6zzW16IlpC6OV/rdZ+xigTV4tkwvjYoERCXG9pvDdfH7PjpmQ6H+VyNUTc\n25s/B/wg0d6ZTGIJySfiMWZ/0Lmst7PmatT8+Bmu/Ls9VTyrVOlzdaBFXJspiEIy\ni95QbXkZFQKBgEFbCihiNt7udfcQMO+LOUhyOYZHq+d/moJ1aqS9lOtUJiYeFQRw\nitxH/iWzRLU7/+bTmOiC2yGrOJ1IdLzZJif/l+Pwmlse3VTC0MrnXTDCkSJcM0Ln\nywjBenMcZ7VpD8XgYmyshALtxI3IKPHWi6beaqGhgnarL/oPUU5BUURbAoGBAMl4\nB5P9PsN2SKCtqqYum+sgObBM47n41fvlDYbz+vhmpchHI2KqTefIAM06cc81NiSK\nsePLudLtPCDVXKkLtxXV4VHkrSYdIQwByqVZEiSqPdJ7Kr+Rw0VhkFJSBQ9Md8fQ\nZMoPa/njAkG0YJ6QvZ/w1e/fSFyjWQJePVqP0VdJAoGBALvA1RdUovGW9HIVNWki\nw1OstXZ7Jk7AWQjbcvFIuusyMl9Yd4j3re1Ykaa/UjCNrLXFEaeF9dnXB0ZQddBq\nMdvF9Q4N0ZAZZgzvgbemkixLcSiPFOITOHGccShCSxa3eN+HoEB8iL79sr7nfjdc\nzpnkwZpeG/ODr8tRFhZyq0x2\n-----END PRIVATE KEY-----\n",
+    "client_email": "ayftech@crazy-charge-469006.iam.gserviceaccount.com",
+    "client_id": "105647661518135606421",
+    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
+    "token_uri": "https://oauth2.googleapis.com/token",
+    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
+    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/ayftech%40crazy-charge-469006.iam.gserviceaccount.com",
+    "universe_domain": "googleapis.com"
+}

+ 4 - 4
util/index.ts

@@ -1,8 +1,8 @@
 import { Linking, Alert } from 'react-native';
-
+import Clipboard from '@react-native-clipboard/clipboard';
 export const handleGoWhatsApp = async () => {
   const phoneWithCountryCode = '85291382139'; // 不带 "+",如 +60 改成 60(马来西亚)
-  const message = null;
+  const message = '';
 
   const whatsappUrl = `whatsapp://send?phone=${phoneWithCountryCode}&text=${encodeURIComponent(message)}`;
   const webWhatsappUrl = `https://wa.me/${phoneWithCountryCode}`;
@@ -20,8 +20,8 @@ export const handleGoWhatsApp = async () => {
     console.error('Error opening WhatsApp:', error);
     // Fallback to showing the number if both methods fail
     Alert.alert('聯絡我們', `請通過WhatsApp聯繫我們:${phoneWithCountryCode}`, [
-        { text: '複製號碼', onPress: () => Clipboard.setString(phoneWithCountryCode) },
-        { text: '取消', style: 'cancel' }
+      { text: '複製號碼', onPress: () => Clipboard.setString(phoneWithCountryCode) },
+      { text: '取消', style: 'cancel' }
     ]);
   }
 };