diff --git a/src/app/chat/chat-screen.tsx b/src/app/chat/chat-screen.tsx index 06fa7182..e010fac4 100644 --- a/src/app/chat/chat-screen.tsx +++ b/src/app/chat/chat-screen.tsx @@ -7,10 +7,11 @@ import Image from "next/image"; import { useAuthState } from "@/stores/auth/auth-context"; 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 { useChatState } from "@/stores/chat/chat-context"; -import { AppEnvUtil, BrowserDetector, UrlLauncherUtil } from "@/utils"; +import { AppEnvUtil, BrowserDetector, todayString, UrlLauncherUtil } from "@/utils"; import { ROUTE_BUILDERS, ROUTES } from "@/router/routes"; import { MobileShell } from "@/app/_components/core"; @@ -56,16 +57,36 @@ export function ChatScreen() { useEffect(() => { if (!authState.hasInitialized || authState.isLoading) return; - if (authState.loginStatus !== "facebook") return; - if (externalBrowserPromptShownRef.current) return; - if (!BrowserDetector.isInAppBrowser()) return; + const isDev = AppEnvUtil.isDevelopment(); + const canTriggerPrompt = + isDev || + (authState.loginStatus === "facebook" && BrowserDetector.isInAppBrowser()); + if (!canTriggerPrompt) return; - externalBrowserPromptShownRef.current = true; - const timer = window.setTimeout(() => { - setShowExternalBrowserDialog(true); - }, 3000); + let mounted = true; + let timer: number | undefined; - return () => window.clearTimeout(timer); + const init = async () => { + if (externalBrowserPromptShownRef.current) return; + + const today = todayString(); + const canShowResult = await AppStorage.canShowExternalBrowserDialog(today); + if (!mounted || !canShowResult.success || !canShowResult.data) return; + + externalBrowserPromptShownRef.current = true; + timer = window.setTimeout(() => { + if (!mounted) return; + setShowExternalBrowserDialog(true); + void AppStorage.recordExternalBrowserDialogShown(today); + }, 3000); + }; + + void init(); + + return () => { + mounted = false; + if (timer !== undefined) window.clearTimeout(timer); + }; }, [ authState.hasInitialized, authState.isLoading, diff --git a/src/data/storage/app/app_storage.ts b/src/data/storage/app/app_storage.ts index 5adf64e4..979c52bc 100644 --- a/src/data/storage/app/app_storage.ts +++ b/src/data/storage/app/app_storage.ts @@ -30,6 +30,26 @@ export class AppStorage { return SpAsyncUtil.setString(StorageKeys.lastPwaDialogShown, todayString); } + // ---- external browser dialog ---- + + static async canShowExternalBrowserDialog( + todayString: string, + ): Promise> { + return AppStorage.canReportKey( + StorageKeys.lastExternalBrowserDialogShown, + todayString, + ); + } + + static recordExternalBrowserDialogShown( + todayString: string, + ): Promise> { + return SpAsyncUtil.setString( + StorageKeys.lastExternalBrowserDialogShown, + todayString, + ); + } + // ---- PWA event reporting ---- static canReportPwaEvent(todayString: string): Promise> { diff --git a/src/data/storage/storage_keys.ts b/src/data/storage/storage_keys.ts index c633fa55..f5cfb04e 100644 --- a/src/data/storage/storage_keys.ts +++ b/src/data/storage/storage_keys.ts @@ -26,6 +26,7 @@ export const StorageKeys = { // pwa / app info lastPwaDialogShown: "last_pwa_dialog_shown", + lastExternalBrowserDialogShown: "last_external_browser_dialog_shown", lastPwaEventReported: "last_pwa_event_reported", lastAppInfoReported: "last_app_info_reported", } as const;