From 4a0dc4425179b6a38406aad082daf71b05aa1443 Mon Sep 17 00:00:00 2001 From: Gauvain Date: Sun, 28 Jun 2026 01:22:29 +0200 Subject: [PATCH] fix(home): defer first-launch intro until the save-account sheet is dismissed On first login with "save account" checked, the intro sheet's 1s timer fired while the post-login save-account bottom sheet was still up and stole its presentation (both are gorhom modals), closing it. Gate the intro on pendingAccountSaveAtom so it only schedules once no account save is pending: before the sheet opens, or after it is dismissed. --- components/home/Home.tsx | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/components/home/Home.tsx b/components/home/Home.tsx index 060dafed..f0534e7f 100644 --- a/components/home/Home.tsx +++ b/components/home/Home.tsx @@ -39,7 +39,11 @@ import { useRefreshLibraryOnFocus } from "@/hooks/useRefreshLibraryOnFocus"; import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache"; import { useDownload } from "@/providers/DownloadProvider"; import { useIntroSheet } from "@/providers/IntroSheetProvider"; -import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; +import { + apiAtom, + pendingAccountSaveAtom, + userAtom, +} from "@/providers/JellyfinProvider"; import { SortByOption, SortOrderOption } from "@/utils/atoms/filters"; import { useSettings } from "@/utils/atoms/settings"; import { eventBus } from "@/utils/eventBus"; @@ -89,6 +93,9 @@ const HomeMobile = () => { const invalidateCache = useInvalidatePlaybackProgressCache(); const [loadedSections, setLoadedSections] = useState>(new Set()); const { showIntro } = useIntroSheet(); + // Gate the intro so it can't steal presentation from the post-login + // save-account sheet (both are BottomSheetModals): wait until no save is pending. + const pendingAccountSave = useAtomValue(pendingAccountSaveAtom); // Fallback refresh for newly added content when returning to the home screen // (primary path is the LibraryChanged WebSocket event). @@ -97,7 +104,9 @@ const HomeMobile = () => { // Show intro modal on first launch useEffect(() => { const hasShownIntro = storage.getBoolean("hasShownIntro"); - if (!hasShownIntro) { + // Defer while the save-account sheet is up; this effect re-runs and schedules + // the intro once the sheet is dismissed (pendingAccountSaveAtom cleared). + if (!hasShownIntro && !pendingAccountSave) { const timer = setTimeout(() => { showIntro(); }, 1000); @@ -106,7 +115,7 @@ const HomeMobile = () => { clearTimeout(timer); }; } - }, [showIntro]); + }, [showIntro, pendingAccountSave]); useEffect(() => { if (isConnected && !prevIsConnected.current) {