Ramble-FE / app / _layout.tsx
_layout.tsx
Raw
import { SignInModal, TopMenuBar } from "@/components";
import { useAuth } from "@/hooks";
import { Slot, usePathname } from "expo-router";
import { StatusBar } from "expo-status-bar";
import React, { useCallback, useState } from "react";
import { BackHandler, Platform, Pressable, StyleSheet } from "react-native";
import { GestureHandlerRootView } from 'react-native-gesture-handler';

export default function RootLayout() {
    const { isAuthenticated, isLoading, login, loginError } = useAuth();
    const [isHovered, setIsHovered] = useState(false);
    const pathname = usePathname();

    const handleClose = useCallback(() => {
        BackHandler.exitApp();
    }, []);

    const getSignInModalVisibility = useCallback(() => {
        if (isLoading) return false;
        
        return Platform.OS === "web"
            ? !isAuthenticated && pathname === "/"
            : !isAuthenticated;
    }, [isAuthenticated, pathname, isLoading]);

    const getTopMenuBarVisibility = useCallback(() => {
        if (isLoading) return false;
        
        return isHovered || !isAuthenticated || pathname !== "/";
    }, [isHovered, isAuthenticated, pathname, isLoading]);

    return (
        <GestureHandlerRootView style={styles.container}>
            {Platform.OS === "web" && (
                <>
                    <Pressable
                        style={styles.navTrigger}
                        onHoverIn={() => setIsHovered(true)}
                    />
                    {getTopMenuBarVisibility() && (
                        <TopMenuBar onHoverOut={() => setIsHovered(false)} />
                    )}
                </>
            )}
            <StatusBar translucent style="light" />
            <Slot />
            <SignInModal
                visible={getSignInModalVisibility()}
                onSuccess={login}
                onError={loginError}
                onClose={handleClose}
            />
        </GestureHandlerRootView>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    navTrigger: {
        position: "absolute",
        top: 0,
        left: 0,
        right: 0,
        height: 40,
        zIndex: 1,
    },
});