diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index 0b7fdd6..b8b83c9 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -129,6 +129,7 @@ export default function Layout({ children }: LayoutProps) { const location = useLocation() const { user, logout, isAdmin, isAuthenticated } = useAuthStore() const [mobileMenuOpen, setMobileMenuOpen] = useState(false) + const [isKeyboardOpen, setIsKeyboardOpen] = useState(false) const { toggleTheme, isDark } = useTheme() const [userPhotoUrl, setUserPhotoUrl] = useState(null) const { isFullscreen, safeAreaInset, contentSafeAreaInset } = useTelegramWebApp() @@ -209,6 +210,26 @@ export default function Layout({ children }: LayoutProps) { } }, [mobileMenuOpen]) + // Detect virtual keyboard open/close using visualViewport API + useEffect(() => { + const viewport = window.visualViewport + if (!viewport) return + + const handleResize = () => { + // Keyboard is considered open if viewport height is significantly smaller than window height + const heightDiff = window.innerHeight - viewport.height + setIsKeyboardOpen(heightDiff > 150) + } + + viewport.addEventListener('resize', handleResize) + viewport.addEventListener('scroll', handleResize) + + return () => { + viewport.removeEventListener('resize', handleResize) + viewport.removeEventListener('scroll', handleResize) + } + }, []) + // State to track if logo image has loaded const [logoLoaded, setLogoLoaded] = useState(false) @@ -629,8 +650,8 @@ export default function Layout({ children }: LayoutProps) { - {/* Mobile Bottom Navigation - only core items */} -