ARTICLE AD BOX
In my app, I am using TopAppBar that has a humburger icon and NavigationView (ModalNavigationDrawer + ModalDrawerSheet) , the probelm is when I click twice in nav icon or when I click on the navigation icon in the settings screen, then click again on the navigation icon of home. Strange behavior occurs when the app is showig white screen, like freezing, and I got no error or exception
Here's a GIF showing the problem
My code:
MainAppNavGraph
@Composable fun MainAppNavGraph( currentUser: FirebaseUser?, onLogout: () -> Unit, networkStatus: NetworkStatus, snackbarHostState: SnackbarHostState ) { val navController = rememberNavController() val drawerState = rememberDrawerState(DrawerValue.Closed) val scope = rememberCoroutineScope() val context = LocalContext.current val currentBackStack by navController.currentBackStackEntryAsState() val currentRoute = currentBackStack?.destination?.route val drawerItems = listOf( DrawerItem("home", "Home", Icons.Default.Home, route = Routes.HomeScreen.route), DrawerItem("profile", "Profile", Icons.Default.Person, route = Routes.ProfileScreen.route), DrawerItem( "leader_board", "Leader Board", Icons.Default.Leaderboard, route = Routes.LeaderboardScreen.route ), DrawerItem( "remove_ads_for_30_mins", "Remove Ads?", iconRes = R.drawable.ad_blocker, route = null ), DrawerItem( id = "settings", title = "Settings", iconImageVector = Icons.Default.Settings, route = Routes.SettingsScreen.route ) ) val authViewModel = hiltViewModel<AuthViewModel>() val userState by authViewModel.userData.collectAsState() val quizViewModel = hiltViewModel<QuizViewModel>() var drawerGesturesEnabled by remember { mutableStateOf(true) } LaunchedEffect(currentUser?.uid) { currentUser?.uid?.let { authViewModel.loadUserData(it) } } LaunchedEffect(currentRoute) { drawerGesturesEnabled = (currentRoute != Routes.PrivacyPolicyScreen.route && currentRoute != Routes.TermsAndConditionsScreen.route) if (currentRoute == Routes.PrivacyPolicyScreen.route || currentRoute == Routes.TermsAndConditionsScreen.route ) { scope.launch { drawerState.close() } } } val userName = (userState as? Resource.Success<User>)?.data?.userName ?: "No User Logged" val userEmail = (userState as? Resource.Success)?.data?.email ?: "No Email" ModalNavigationDrawer( drawerState = drawerState, gesturesEnabled = drawerGesturesEnabled, drawerContent = { ModalDrawerSheet( windowInsets = WindowInsets(0, 0, 0, 0), drawerContainerColor = MaterialTheme.colorScheme.surface, ) { AppDrawer( currentRoute = currentRoute ?: Routes.HomeScreen.route, userName = userName, // ← من ViewModel لاحقاً userEmail = userEmail, drawerItems = drawerItems, onItemClick = { item -> item.route?.let { navController.navigate(it) { popUpTo(Routes.HomeScreen.route) { saveState = true } launchSingleTop = true restoreState = true } } }, onLogoutClick = { scope.launch { drawerState.close() } authViewModel.logout() onLogout() }, onCloseDrawer = { scope.launch { drawerState.close() } }, onRemoveAdsClick = { if (AdManager.areAdsDisabled()) { Toast.makeText( context, "Ads disabled — ${AdManager.getRemainingMinutes()} minutes remaining", Toast.LENGTH_SHORT ).show() } else if (AdManager.isRewardedReady()) { AdManager.showRewardedAd( activity = context as Activity, onSessionActivated = { remaining -> Toast.makeText( context, "🎉 Ads disabled for $remaining minutes!", Toast.LENGTH_LONG ).show() }, onNotReady = { Toast.makeText( context, "Ad not ready, try again", Toast.LENGTH_SHORT ).show() AdManager.loadRewardedAd(context) } ) } else { Toast.makeText(context, "Loading ad, try again", Toast.LENGTH_SHORT) .show() AdManager.loadRewardedAd(context) } } ) } } ) { NavHost( navController = navController, startDestination = Routes.HomeScreen.route ) { composable(route = Routes.HomeScreen.route) { val homeScreenViewModel = hiltViewModel<HomeScreenViewModel>() val state by homeScreenViewModel.homeState.collectAsState() var isDrawerOpening by remember { mutableStateOf(false) } HomeScreen( stateHomeScreen = state, event = homeScreenViewModel::onEvent, navController = navController, onMenuClick = { if (!isDrawerOpening && !drawerState.isOpen) { isDrawerOpening = true scope.launch { drawerState.open() isDrawerOpening = false } } }, networkStatus = networkStatus, snackbarHostState = snackbarHostState ) } composable( route = Routes.QuizScreen.route, arguments = listOf( navArgument(ARG_KEY_QUIZ_NUMBER) { type = NavType.IntType }, navArgument(ARG_KEY_QUIZ_CATEGORY) { type = NavType.StringType }, navArgument(ARG_KEY_QUIZ_DIFFICULTY) { type = NavType.StringType }, navArgument(ARG_KEY_QUIZ_TYPE) { type = NavType.StringType }, ) ) { val state by quizViewModel.quizList.collectAsState() QuizScreen( numberOfQuizzes = it.arguments?.getInt(ARG_KEY_QUIZ_NUMBER)!!, quizCategory = it.arguments?.getString(ARG_KEY_QUIZ_CATEGORY)!!, quizDifficulty = it.arguments?.getString(ARG_KEY_QUIZ_DIFFICULTY)!!, quizType = it.arguments?.getString(ARG_KEY_QUIZ_TYPE)!!, event = quizViewModel::onEvent, state = state, navController = navController ) } composable( route = Routes.ScoreScreen.route, arguments = listOf( navArgument(NOQ_KEY) { type = NavType.IntType }, navArgument(CORRECT_ANSWERS_KEY) { type = NavType.IntType } ) ) { ScoreScreen( numberOfQuestions = it.arguments?.getInt(NOQ_KEY)!!, numberOfCorrectAnswers = it.arguments?.getInt(CORRECT_ANSWERS_KEY)!!, onClose = { navController.navigate(Routes.HomeScreen.route) { popUpTo(Routes.HomeScreen.route) { inclusive = true } } }, quizStates = quizViewModel.quizList.collectAsState().value.quizState, onReviewAnswers = { navController.navigate(Routes.ReviewAnswersScreen.route) } ) } composable(route = Routes.LeaderboardScreen.route) { LeaderboardScreen() } composable(route = Routes.SettingsScreen.route) { SettingsScreen( onBackClick = { navController.popBackStack() }, onPrivacyPolicyClick = { navController.navigate(Routes.PrivacyPolicyScreen.route) }, onTermsClick = { navController.navigate(Routes.TermsAndConditionsScreen.route) } ) } composable(route = Routes.ProfileScreen.route) { ProfileScreen( userName = userName, userEmail = userEmail, onLogoutClick = { scope.launch { drawerState.close() } authViewModel.logout() onLogout() } ) } composable(route = Routes.ReviewAnswersScreen.route) { val state by quizViewModel.quizList.collectAsState() // instance ReviewAnswersScreen( quizStates = state.quizState, onBack = { navController.popBackStack() } ) } composable(route = Routes.PrivacyPolicyScreen.route) { PrivacyPolicyScreen { navController.popBackStack() } } composable(route = Routes.TermsAndConditionsScreen.route) { TermsAndConditionsScreen { navController.popBackStack() } } } } }HomeHeader
@OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeHeader( onMenuClicked: () -> Unit = {}, onSettingsClicked: () -> Unit = {} ) { TopAppBar( title = { Text( modifier = Modifier.fillMaxWidth(), text = "Quizzy", fontSize = HeroTextSize, fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.secondary, textAlign = TextAlign.Center ) }, navigationIcon = { IconButton( onClick = onMenuClicked, modifier = Modifier .size(40.dp) .padding(start = 8.dp), ) { Icon( imageVector = Icons.Default.Menu, contentDescription = "Menu", tint = MaterialTheme.colorScheme.secondary, ) } }, actions = { IconButton(onClick = onSettingsClicked) { Icon( contentDescription = "Settings", tint = colorResource(R.color.colorSecondary), imageVector = Icons.Default.Settings, ) } }, colors = TopAppBarDefaults.topAppBarColors( containerColor = colorResource(R.color.colorPrimaryVariant) ), modifier = Modifier.clip( RoundedCornerShape( bottomStart = Dimens.LargeCornerRadius, bottomEnd = Dimens.LargeCornerRadius ) ) ) }