Browse Source

feat: 下载按钮响应

BaiLuoYan 1 tháng trước cách đây
mục cha
commit
7f434fdfa1
4 tập tin đã thay đổi với 69 bổ sung27 xóa
  1. 4 0
      .env
  2. 47 11
      src/hooks/useAppUrls.ts
  3. 5 16
      src/pages/home/components/ChoosePlatform.tsx
  4. 13 0
      types/vite-env.d.ts

+ 4 - 0
.env

@@ -32,6 +32,10 @@ VITE_APP_GOOGLE_STORE_URL="https://chatgpt.com/"
 VITE_APP_APPLE_STORE_URL="https://chatgpt.com/"
 # APK 下载地址
 VITE_APP_APK_URL="https://chatgpt.com/"
+# Mac OS 下载地址
+VITE_APP_MACOS_URL="https://chatgpt.com/"
+# Windows 下载地址
+VITE_APP_WINDOWS_URL="https://chatgpt.com/"
 
 # deeplink 链接地址
 VITE_APP_DEEPLINK_URL="nomo://launch"

+ 47 - 11
src/hooks/useAppUrls.ts

@@ -2,17 +2,16 @@ import { useMemo } from 'react';
 
 import { useSearchParams } from 'react-router-dom';
 
-const env = typeof import.meta !== 'undefined' ? (import.meta as any).env : undefined;
+const env: ImportMetaEnv =
+    typeof import.meta !== 'undefined' ? (import.meta as any).env : undefined;
 
 const GOOGLE_STORE_URL = env?.VITE_APP_GOOGLE_STORE_URL ?? '';
-console.log('🚀 ~ useAppUrls.ts:8 ~ GOOGLE_STORE_URL:', GOOGLE_STORE_URL);
 const APPLE_STORE_URL = env?.VITE_APP_APPLE_STORE_URL ?? '';
-console.log('🚀 ~ useAppUrls.ts:10 ~ APPLE_STORE_URL:', APPLE_STORE_URL);
 const APK_URL = env?.VITE_APP_APK_URL ?? '';
-console.log('🚀 ~ useAppUrls.ts:12 ~ APK_URL:', APK_URL);
+const MACOS_URL = env?.VITE_APP_MACOS_URL ?? '';
+const WINDOWS_URL = env?.VITE_APP_WINDOWS_URL ?? '';
 
 const DEEPLINK_URL = env?.VITE_APP_DEEPLINK_URL ?? '';
-console.log('🚀 ~ useAppUrls.ts:15 ~ DEEPLINK_URL:', DEEPLINK_URL);
 
 const REFERRER_PARAM = 'referrer';
 
@@ -20,17 +19,24 @@ function getDownloadUrlByPlatform(
     google: string,
     apple: string,
     apk: string,
+    macos: string,
+    windows: string,
     fallback: string
 ): string {
     if (typeof navigator === 'undefined' || !navigator.userAgent)
-        return fallback || apk || google || apple;
+        return fallback || windows || apk || google || apple || macos;
     const ua = navigator.userAgent;
-    const isIos = /iPad|iPhone|iPod/.test(ua);
+    const isIos =
+        /iPad|iPhone|iPod/.test(ua) ||
+        (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
     const isAndroid = /Android/.test(ua);
+    const isMac = !isIos && /Macintosh|Mac OS X/.test(ua);
+    const isWindows = /Windows/.test(ua);
     if (isIos && apple) return apple;
-    if (isAndroid && google) return google;
-    if (isAndroid && apk) return apk;
-    return fallback || apk || google || apple;
+    if (isAndroid) return google || apk;
+    if (isMac && macos) return macos;
+    if (isWindows && windows) return windows;
+    return fallback || windows || apk || google || apple || macos;
 }
 
 export interface AppUrls {
@@ -42,7 +48,11 @@ export interface AppUrls {
     appleStoreUrl: string;
     /** APK 直链地址,未配置时为空 */
     apkUrl: string;
-    /** 根据当前用户平台自动选择的下载地址:iOS→Apple 商店,Android→Google 商店或 APK,其他→fallback/APK/Google/Apple */
+    /** macOS 客户端下载地址,未配置时为空 */
+    macosUrl: string;
+    /** Windows 客户端下载地址,未配置时为空 */
+    windowsUrl: string;
+    /** 根据当前用户平台自动选择的下载地址 */
     downloadUrlByPlatform: string;
 }
 
@@ -90,15 +100,41 @@ export function useAppUrls(): AppUrls {
             }
         })();
 
+        const macosUrl = (() => {
+            if (!MACOS_URL) return '';
+            if (!referrerEnc) return MACOS_URL;
+            try {
+                const sep = MACOS_URL.includes('?') ? '&' : '?';
+                return `${MACOS_URL}${sep}${REFERRER_PARAM}=${referrerEnc}`;
+            } catch {
+                return MACOS_URL;
+            }
+        })();
+
+        const windowsUrl = (() => {
+            if (!WINDOWS_URL) return '';
+            if (!referrerEnc) return WINDOWS_URL;
+            try {
+                const sep = WINDOWS_URL.includes('?') ? '&' : '?';
+                return `${WINDOWS_URL}${sep}${REFERRER_PARAM}=${referrerEnc}`;
+            } catch {
+                return WINDOWS_URL;
+            }
+        })();
+
         return {
             deeplinkUrl,
             googleStoreUrl,
             appleStoreUrl: APPLE_STORE_URL,
             apkUrl,
+            macosUrl,
+            windowsUrl,
             downloadUrlByPlatform: getDownloadUrlByPlatform(
                 googleStoreUrl,
                 APPLE_STORE_URL,
                 apkUrl,
+                macosUrl,
+                windowsUrl,
                 ''
             ),
         };

+ 5 - 16
src/pages/home/components/ChoosePlatform.tsx

@@ -6,27 +6,24 @@ import btnGooglePlay from '@/assets/images/home/btn-google-play.svg';
 import btnMacos from '@/assets/images/home/btn-macos.svg';
 import btnWindows from '@/assets/images/home/btn-windows.svg';
 import devicesMockup from '@/assets/images/home/devices-mockup.png';
-import { useAppUrls } from '@/hooks/useAppUrls';
+import { useAppUrls, type AppUrls } from '@/hooks/useAppUrls';
 
 import Wrapper from './Wrapper';
 
 interface PlatformButton {
     image: string;
     alt: string;
-    urlKey: 'appleStoreUrl' | 'googleStoreUrl' | 'downloadUrlByPlatform';
+    urlKey: keyof AppUrls;
 }
 
 const STORE_BUTTONS: PlatformButton[] = [
     { image: btnAppStore, alt: 'App Store', urlKey: 'appleStoreUrl' },
     { image: btnGooglePlay, alt: 'Google Play', urlKey: 'googleStoreUrl' },
+    { image: btnAndroid, alt: 'Android', urlKey: 'apkUrl' },
+    { image: btnWindows, alt: 'Windows', urlKey: 'windowsUrl' },
+    { image: btnMacos, alt: 'Mac OS', urlKey: 'macosUrl' },
 ];
 
-const PLATFORM_ICONS = [
-    { image: btnAndroid, alt: 'Android' },
-    { image: btnWindows, alt: 'Windows' },
-    { image: btnMacos, alt: 'Mac OS' },
-] as const;
-
 export function ChoosePlatform() {
     const { t } = useTranslation();
     const urls = useAppUrls();
@@ -64,14 +61,6 @@ export function ChoosePlatform() {
                                 </a>
                             );
                         })}
-                        {PLATFORM_ICONS.map(({ image, alt }) => (
-                            <img
-                                key={alt}
-                                src={image}
-                                alt={alt}
-                                className="h-[50px] w-full object-contain sm:w-auto"
-                            />
-                        ))}
                     </div>
                 </div>
 

+ 13 - 0
types/vite-env.d.ts

@@ -72,6 +72,19 @@ interface ImportMetaEnv {
 
     /**API基础URL */
     VITE_API_BASE_URL?: string;
+
+    /**Google Play 商店地址,未配置时为空 */
+    VITE_APP_GOOGLE_STORE_URL?: string;
+    /**Apple App Store 地址,未配置时为空 */
+    VITE_APP_APPLE_STORE_URL?: string;
+    /**APK 直链地址,未配置时为空 */
+    VITE_APP_APK_URL?: string;
+    /**macOS 客户端下载地址,未配置时为空 */
+    VITE_APP_MACOS_URL?: string;
+    /**Windows 客户端下载地址,未配置时为空 */
+    VITE_APP_WINDOWS_URL?: string;
+    /**deeplink 地址,未配置时为空 */
+    VITE_APP_DEEPLINK_URL?: string;
 }
 
 interface ImportMeta {