Milad-Akarie / auto_route_library

Flutter route generator
MIT License
1.59k stars 405 forks source link

PopTop all Tabs Manually #1702

Open norutplz opened 1 year ago

norutplz commented 1 year ago

How can all the tabs from the BottomNavigationBar be returned to the initial screen? For example, so that when the user logs in, all screens roll back to the first screen (that is, tabsRouter.popTop is executed for all screens)

norutplz commented 1 year ago

Or how i can get list of tabs?

Milad-Akarie commented 1 year ago

@HornyPony easiest way to do this

  for (var i = 0; i < context.tabsRouter.pageCount; i++) {
        context.tabsRouter.stackRouterOfIndex(i)?.popUntilRoot();
      }
norutplz commented 1 year ago

@Milad-Akarie Thanks a lot!

Changed that way:

for (var i = 0; i < context.tabsRouter.pageCount; i++) {
        await context.tabsRouter.stackRouterOfIndex(i)?.popTop();
 }
Milad-Akarie commented 1 year ago

@HornyPony know that popTop will only pop one route where popUntil root will pop all routes but the root one.

norutplz commented 1 year ago

@Milad-Akarie Thank you, then yes, I need to use popUntilRoot(), but I'm wondering what to do if I have a guard on my root screen? When I use popUntilRoot, I expect that the screen with guard will also be re-created and disappears in the authorized user state. Or maybe there is another way to monitor in the guard whether the user is authorized or not (even when the screen with the guard is visible to the user)

My router.dart looks like this. I want forumGuard to disappear for the forum if the user has logged in

AutoRoute(path: '/', page: HomeRoute.page, children: [
      AutoRoute(path: 'screener', page: ScreenerEmptyRoute.page, children: [
        AutoRoute(
            path: '',
            page: ScreenerRoute.page,
            meta: const {'noResizeToAvoidBottomInset': true}),
        AutoRoute(path: 'filter', page: FilterRoute.page),    
      ]),
      AutoRoute(path: 'favourite', page: FavouriteEmptyRoute.page, children: [
        AutoRoute(
            path: '',
            page: FavouriteRoute.page,
            meta: const {'noResizeToAvoidBottomInset': true}),
        AutoRoute(path: 'analyseCompany', page: AnalyzeSingleRoute.page),     
      ]),
      AutoRoute(
          path: 'forum',
          page: ForumEmptyRoute.page,
          children: [
            AutoRoute(path: '', page: ForumRoute.page, guards: [ForumGuard()]),
            AutoRoute(
                path: 'blogEntry',
                page: ForumSingleRoute.page,
                guards: [ForumGuard()],
                meta: const {'hideBottomNav': true}),         
          ]),

Thanks!

norutplz commented 1 year ago

Also i try this way, but it return blank screen. I don't know how I can get path that i need

for (var i = 0; i < context.tabsRouter.pageCount; i++) {
        String initScreenPath =
            context.tabsRouter.stackRouterOfIndex(i)?.routeData.path ?? '';

        context.tabsRouter
            .stackRouterOfIndex(i)
            ?.popUntilRouteWithPath('/#/$initScreenPath');
      }
norutplz commented 1 year ago

So far I've only thought of using popUntilRoot() and then popTop() at the same time But 1) I still haven't figured out how to check if there is a need for popTop() - I haven't found the right bool value 2) this removes the guard if it was already open (when the user logs in), but does not open the desired guard after logging out - The desired result is that the Guard on the forum screen disappears after authorization and appears when logging out

if(context != null && context.mounted){
      for (var i = 0; i < context.tabsRouter.pageCount; i++) {

          context.tabsRouter.stackRouterOfIndex(i)?.popUntilRoot();
          context.tabsRouter.stackRouterOfIndex(i)?.popTop();
          //print(context.tabsRouter.stackRouterOfIndex(i)?.);
         //print(context.tabsRouter.stackRouterOfIndex(i)?.topRoute.name);
      }
    }
Milad-Akarie commented 1 year ago

@HornyPony This's to much to take in :D do you want the root route of a sub-router to be evaluated by the guard?

norutplz commented 1 year ago

I want the ForumRoute screen to check whether the user is logged in or not every time when logging in or logging out. If the user has logged in on the Profile tab, ForumGuard should skip the user to ForumRoute, but if the user has logged out, ForumGuard should meet him on the forum tab (although earlier on this tab the user was on a page with ForumRoute)

AutoRoute(path: '/', page: HomeRoute.page, children: [
      AutoRoute(
          path: 'forum',
          page: ForumEmptyRoute.page,
          children: [
            AutoRoute(path: '', page: ForumRoute.page, guards: [ForumGuard()]),
            AutoRoute(
                path: 'blogEntry',
                page: ForumSingleRoute.page,
                guards: [ForumGuard()],
                meta: const {'hideBottomNav': true}),         
          ]),
norutplz commented 1 year ago

@Milad-Akarie Please help me

I have a HomeRoute() that contains 4 tabs for the bottom Navigation Bar. One of the tabs is forum. (Screen 1)

I need that if the user is not authorized, he is redirected to the Sign In screen (screen 2) - I implemented this through ForumGuard(). Everything is fine with this

But I need this SignInRoute() to go away and the ForumRoute() screen appears instead when the user is logged in. This can even happen from another tab (for example, from a profile tab). But when logging in, ForumRoute() does not appear, but SignInRoute() remains. I made the return of all tabs to route with the code on (screen 3). But it doesn't work because the canPop() method returns false even though the path is there /forum/signIn/

telegram-cloud-photo-size-2-5474259908850470511-y telegram-cloud-photo-size-2-5474259908850470512-y telegram-cloud-photo-size-2-5474259908850470513-y

github-actions[bot] commented 3 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions