From 1fed21fa2fe43beec86bbfa08a06b08305c896d6 Mon Sep 17 00:00:00 2001 From: chenhang Date: Tue, 30 Jun 2026 14:32:58 +0800 Subject: [PATCH] refactor(chat): clean stale mocks and external browser helpers --- src/app/chat/chat-screen.helpers.ts | 52 +----------------- src/app/chat/chat-screen.tsx | 8 +-- .../send-message-daily-limit-blocked.json | 28 ---------- .../send-message-total-limit-blocked.json | 28 ---------- .../unlock-private-quota-exceeded.json | 14 ----- .../chat/websocket-events/ai-sentence.json | 9 ---- .../mock/chat/websocket-events/connected.json | 6 --- .../mock/chat/websocket-events/error.json | 6 --- .../mock/chat/websocket-events/image.json | 9 ---- .../chat/websocket-events/paywall-status.json | 17 ------ src/lib/chat/chat_external_browser.ts | 54 +++++++++++++++++++ 11 files changed, 61 insertions(+), 170 deletions(-) delete mode 100644 src/data/mock/chat/responses/send-message-daily-limit-blocked.json delete mode 100644 src/data/mock/chat/responses/send-message-total-limit-blocked.json delete mode 100644 src/data/mock/chat/responses/unlock-private-quota-exceeded.json delete mode 100644 src/data/mock/chat/websocket-events/ai-sentence.json delete mode 100644 src/data/mock/chat/websocket-events/connected.json delete mode 100644 src/data/mock/chat/websocket-events/error.json delete mode 100644 src/data/mock/chat/websocket-events/image.json delete mode 100644 src/data/mock/chat/websocket-events/paywall-status.json create mode 100644 src/lib/chat/chat_external_browser.ts diff --git a/src/app/chat/chat-screen.helpers.ts b/src/app/chat/chat-screen.helpers.ts index 5bcc942b..b1ad9b24 100644 --- a/src/app/chat/chat-screen.helpers.ts +++ b/src/app/chat/chat-screen.helpers.ts @@ -1,11 +1,8 @@ "use client"; import type { LoginStatus } from "@/data/dto/auth"; -import { AppStorage } from "@/data/storage/app/app_storage"; -import { AuthStorage } from "@/data/storage/auth/auth_storage"; -import { UserStorage } from "@/data/storage/user/user_storage"; -import { ROUTE_BUILDERS, ROUTES } from "@/router/routes"; -import { AppEnvUtil, BrowserDetector, todayString, UrlLauncherUtil } from "@/utils"; +import { ROUTE_BUILDERS } from "@/router/routes"; +import { AppEnvUtil, BrowserDetector } from "@/utils"; export interface ExternalBrowserPromptState { hasInitialized: boolean; @@ -33,51 +30,6 @@ export function shouldStartExternalBrowserPrompt({ ); } -export async function resolveExternalBrowserPromptEligibility(): Promise<{ - canShow: boolean; - today: string; -}> { - const today = todayString(); - const result = await AppStorage.canShowExternalBrowserDialog(today); - return { - canShow: result.success && result.data, - today, - }; -} - -export function recordExternalBrowserPromptShown(today: string): Promise { - return AppStorage.recordExternalBrowserDialogShown(today); -} - -export async function openChatInExternalBrowser(): Promise { - const authStorage = AuthStorage.getInstance(); - const userStorage = UserStorage.getInstance(); - const [deviceIdR, facebookIdR, avatarUrlR] = await Promise.all([ - authStorage.getDeviceId(), - authStorage.getFacebookId(), - userStorage.getAvatarUrl(), - ]); - - const deviceId = deviceIdR.success ? deviceIdR.data : null; - const facebookId = facebookIdR.success ? facebookIdR.data : null; - const avatarUrl = avatarUrlR.success ? avatarUrlR.data : null; - - if (deviceId && facebookId) { - UrlLauncherUtil.openUrlWithExternalBrowser( - ROUTE_BUILDERS.chatDeviceId(deviceId), - { - queryParams: { - fbid: facebookId, - ...(avatarUrl ? { avatarUrl } : {}), - }, - }, - ); - return; - } - - UrlLauncherUtil.openUrlWithExternalBrowser(ROUTES.splash); -} - export function getChatPaywallSubscriptionUrl(): string { return ROUTE_BUILDERS.subscription("vip", { returnTo: "chat", diff --git a/src/app/chat/chat-screen.tsx b/src/app/chat/chat-screen.tsx index 107fe12e..3005ec55 100644 --- a/src/app/chat/chat-screen.tsx +++ b/src/app/chat/chat-screen.tsx @@ -7,6 +7,11 @@ import { useRouter } from "next/navigation"; import { useAuthState } from "@/stores/auth/auth-context"; import { useChatDispatch, useChatState } from "@/stores/chat/chat-context"; import { useUserState } from "@/stores/user/user-context"; +import { + openChatInExternalBrowser, + recordExternalBrowserPromptShown, + resolveExternalBrowserPromptEligibility, +} from "@/lib/chat/chat_external_browser"; import { MobileShell } from "@/app/_components/core"; @@ -25,9 +30,6 @@ import { getChatPaywallNavigationUrl, getInsufficientCreditsSubscriptionType, isChatDevelopmentEnvironment, - openChatInExternalBrowser, - recordExternalBrowserPromptShown, - resolveExternalBrowserPromptEligibility, shouldStartExternalBrowserPrompt, } from "./chat-screen.helpers"; import styles from "./components/chat-screen.module.css"; diff --git a/src/data/mock/chat/responses/send-message-daily-limit-blocked.json b/src/data/mock/chat/responses/send-message-daily-limit-blocked.json deleted file mode 100644 index 7948c06f..00000000 --- a/src/data/mock/chat/responses/send-message-daily-limit-blocked.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "code": 200, - "message": "success", - "success": true, - "data": { - "reply": "", - "audioUrl": "", - "messageId": "msg_blocked_daily_001", - "isGuest": false, - "timestamp": 1782180665000, - "image": { - "type": null, - "url": null - }, - "lockDetail": { - "locked": true, - "showContent": false, - "showUpgrade": true, - "reason": "daily_limit", - "hint": "免费消息额度已用完,开通会员后可以继续聊天。", - "detail": { - "type": "daily_msg_limit", - "usedToday": 20, - "limit": 20 - } - } - } -} diff --git a/src/data/mock/chat/responses/send-message-total-limit-blocked.json b/src/data/mock/chat/responses/send-message-total-limit-blocked.json deleted file mode 100644 index bd1359f0..00000000 --- a/src/data/mock/chat/responses/send-message-total-limit-blocked.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "code": 200, - "message": "success", - "success": true, - "data": { - "reply": "", - "audioUrl": "", - "messageId": "", - "isGuest": true, - "timestamp": 1782197944984, - "image": { - "type": null, - "url": null - }, - "lockDetail": { - "locked": true, - "showContent": false, - "showUpgrade": true, - "reason": "daily_limit", - "hint": "Log in to get more free chat messages.", - "detail": { - "type": "daily_msg_limit", - "usedToday": 5, - "limit": 5 - } - } - } -} diff --git a/src/data/mock/chat/responses/unlock-private-quota-exceeded.json b/src/data/mock/chat/responses/unlock-private-quota-exceeded.json deleted file mode 100644 index 4b4f02b8..00000000 --- a/src/data/mock/chat/responses/unlock-private-quota-exceeded.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "code": 200, - "message": "success", - "success": true, - "data": { - "unlocked": false, - "content": null, - "showUpgrade": true, - "paywallTriggered": true, - "privateFreeLimit": 1, - "privateUsedToday": 1, - "reason": "quota_exceeded" - } -} diff --git a/src/data/mock/chat/websocket-events/ai-sentence.json b/src/data/mock/chat/websocket-events/ai-sentence.json deleted file mode 100644 index 3840b809..00000000 --- a/src/data/mock/chat/websocket-events/ai-sentence.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "sentence", - "data": { - "index": 0, - "text": "I am listening.", - "total": 2, - "done": false - } -} diff --git a/src/data/mock/chat/websocket-events/connected.json b/src/data/mock/chat/websocket-events/connected.json deleted file mode 100644 index 6209fb81..00000000 --- a/src/data/mock/chat/websocket-events/connected.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "connected", - "data": { - "userId": "user_mock_001" - } -} diff --git a/src/data/mock/chat/websocket-events/error.json b/src/data/mock/chat/websocket-events/error.json deleted file mode 100644 index 4dd12a3d..00000000 --- a/src/data/mock/chat/websocket-events/error.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "error", - "data": { - "message": "WebSocket connection interrupted." - } -} diff --git a/src/data/mock/chat/websocket-events/image.json b/src/data/mock/chat/websocket-events/image.json deleted file mode 100644 index 42b393b8..00000000 --- a/src/data/mock/chat/websocket-events/image.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "image", - "data": { - "image": { - "type": "elio_schedule", - "url": "https://cdn.cozsweet.com/mock/chat/elio-schedule-001.jpg" - } - } -} diff --git a/src/data/mock/chat/websocket-events/paywall-status.json b/src/data/mock/chat/websocket-events/paywall-status.json deleted file mode 100644 index f00ce8a2..00000000 --- a/src/data/mock/chat/websocket-events/paywall-status.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "type": "paywall_status", - "data": { - "lockDetail": { - "locked": true, - "showContent": false, - "showUpgrade": true, - "reason": "daily_limit", - "hint": "免费消息额度已用完,开通会员后可以继续聊天。", - "detail": { - "type": "daily_msg_limit", - "usedToday": 20, - "limit": 20 - } - } - } -} diff --git a/src/lib/chat/chat_external_browser.ts b/src/lib/chat/chat_external_browser.ts new file mode 100644 index 00000000..7c0318c9 --- /dev/null +++ b/src/lib/chat/chat_external_browser.ts @@ -0,0 +1,54 @@ +"use client"; + +import { AppStorage } from "@/data/storage/app/app_storage"; +import { AuthStorage } from "@/data/storage/auth/auth_storage"; +import { UserStorage } from "@/data/storage/user/user_storage"; +import { ROUTE_BUILDERS, ROUTES } from "@/router/routes"; +import { todayString, UrlLauncherUtil } from "@/utils"; + +export async function resolveExternalBrowserPromptEligibility(): Promise<{ + canShow: boolean; + today: string; +}> { + const today = todayString(); + const result = await AppStorage.canShowExternalBrowserDialog(today); + return { + canShow: result.success && result.data, + today, + }; +} + +export function recordExternalBrowserPromptShown( + today: string, +): Promise { + return AppStorage.recordExternalBrowserDialogShown(today); +} + +export async function openChatInExternalBrowser(): Promise { + const authStorage = AuthStorage.getInstance(); + const userStorage = UserStorage.getInstance(); + const [deviceIdR, facebookIdR, avatarUrlR] = await Promise.all([ + authStorage.getDeviceId(), + authStorage.getFacebookId(), + userStorage.getAvatarUrl(), + ]); + + const deviceId = deviceIdR.success ? deviceIdR.data : null; + const facebookId = facebookIdR.success ? facebookIdR.data : null; + const avatarUrl = avatarUrlR.success ? avatarUrlR.data : null; + + if (deviceId && facebookId) { + UrlLauncherUtil.openUrlWithExternalBrowser( + ROUTE_BUILDERS.chatDeviceId(deviceId), + { + queryParams: { + fbid: facebookId, + ...(avatarUrl ? { avatarUrl } : {}), + }, + }, + ); + return; + } + + UrlLauncherUtil.openUrlWithExternalBrowser(ROUTES.splash); +}