[PR #3459] [MERGED] feat: go_router refactor and bottom navigation bar in mobile #5731

Closed
opened 2026-03-23 22:20:03 +00:00 by mirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/AppFlowy-IO/AppFlowy/pull/3459
Author: @hyj1204
Created: 9/19/2023
Status: Merged
Merged: 9/28/2023
Merged by: @LucasXu0

Base: mainHead: feat/navigation_refactor


📝 Commits (10+)

  • 5b58f5b refactor: refactor navigator in auth pages to go_router
  • 0111bc3 feat: add bottom navigation bar as StatefulShellRoute
  • 0a184b4 chore: remove unused import files
  • e760e71 feat: add mobile icons and improve appbar in home page
  • 75f0a01 chore: clean code and remove unused import files
  • d72f54e fix: flutter analyze
  • 9783708 chore: make arguments name as const
  • 67deb2c chore: extract routes methods
  • 6caa061 chore: add comments and delete unnecessary key
  • 76f0279 chore: update key value to const

📊 Changes

38 files changed (+894 additions, -277 deletions)

View changed files

📝 frontend/appflowy_flutter/lib/mobile/application/mobile_theme_data.dart (+14 -2)
frontend/appflowy_flutter/lib/mobile/presentation/details_placeholder_page.dart (+99 -0)
frontend/appflowy_flutter/lib/mobile/presentation/home/home.dart (+1 -0)
frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart (+80 -0)
frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart (+94 -0)
frontend/appflowy_flutter/lib/mobile/presentation/mobile_home_page.dart (+0 -47)
frontend/appflowy_flutter/lib/mobile/presentation/presentation.dart (+4 -0)
frontend/appflowy_flutter/lib/mobile/presentation/root_placeholder_page.dart (+54 -0)
📝 frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart (+28 -10)
frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart (+296 -0)
📝 frontend/appflowy_flutter/lib/startup/tasks/prelude.dart (+1 -0)
📝 frontend/appflowy_flutter/lib/user/presentation/helpers/handle_user_profile_result.dart (+8 -8)
📝 frontend/appflowy_flutter/lib/user/presentation/helpers/helpers.dart (+1 -1)
📝 frontend/appflowy_flutter/lib/user/presentation/router.dart (+48 -114)
📝 frontend/appflowy_flutter/lib/user/presentation/screens/encrypt_secret_screen.dart (+5 -1)
📝 frontend/appflowy_flutter/lib/user/presentation/screens/screens.dart (+1 -0)
📝 frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/sign_in_screen.dart (+5 -3)
📝 frontend/appflowy_flutter/lib/user/presentation/screens/skip_log_in_screen.dart (+2 -6)
📝 frontend/appflowy_flutter/lib/user/presentation/screens/splash_screen.dart (+11 -10)
📝 frontend/appflowy_flutter/lib/user/presentation/screens/workspace_error_screen.dart (+4 -0)

...and 18 more files

📄 Description

Feature Preview

  1. Refactor all the auth pages' routes by the go_router package:
  • Currently, I only did some basic refactoring on the pages related to authentication, other parts still have Navigator.push. I use go_router package mainly for navigation on mobile. The authentication workflow is still the same as the previous code, the only difference is I add context.go to replace the previous page(same as Navigator.pushReplacement), so the splash screen will be replaced by home page after the user login. On the home page, if the user clicks 'back' (android back button), the app will quit instead of back to login/skipLoginPage.
  • Remove the routeName of SplashScreen. Due to it is the root page of the app, I set '/' as its routeName.
  • All the routes(using go_router) are registed in appflowy_flutter/lib/startup/tasks/generate_router.dart
  1. Add bottom navigation bar on mobile.
    I utilized the StatefulShellRoute.indexedStack to build the bottom navigation bar. This approach enables each tab to retain its own state, as demonstrated in the following video.
    Currently, every tab page is just some example code and I will implement them in the future.

https://github.com/AppFlowy-IO/AppFlowy/assets/14248245/26aef070-ca76-4f7e-9b9d-633df8163ad4

  1. For the icons used on mobile, I name them starting with m, because some icons look different as the desktop even though their purpose/name is similar.

go_router note:
When it comes to passing the arguments between the pages. I set extra to a Map<String, dynamic> to carry all the arguments, then get it from the state in pageBuilder.

  • Pass arguments:
    Set argument names as constant(start with arg) on the screen page, then use them as the key in the Map<String, dynamic>.
    Pass this Map<String, dynamic> as extra to GoRoute.
    context.go(
            DesktopHomeScreen.routeName,
            extra: {
              DesktopHomeScreen.argKey: ValueKey(userProfile.id),
              DesktopHomeScreen.argUserProfile: userProfile,
              DesktopHomeScreen.argWorkspaceSetting: workspaceSetting,
            },
          );

Head part and constructor of DesktopHomeScreen

class DesktopHomeScreen extends StatefulWidget {
  static const routeName = '/DesktopHomeScreen';
  // arguments names to used in GoRouter
  static const argUserProfile = 'userProfile';
  static const argWorkspaceSetting = 'workspaceSetting';
  static const argKey = 'key';

  final UserProfilePB userProfile;
  final WorkspaceSettingPB workspaceSetting;
  const DesktopHomeScreen({
    super.key,
    required this.userProfile,
    required this.workspaceSetting,
  });
  • Receive arguments in pageBuilder
GoRoute(
    path: DesktopHomeScreen.routeName,
    pageBuilder: (context, state) {
      final args = state.extra as Map<String, dynamic>;
      return CustomTransitionPage(
        child: DesktopHomeScreen(
          key: args[DesktopHomeScreen.argKey],
          userProfile: args[DesktopHomeScreen.argUserProfile],
          workspaceSetting: args[DesktopHomeScreen.argWorkspaceSetting],
        ),
        transitionsBuilder: _buildFadeTransition,
        transitionDuration: _slowDuration,
      );
    },
  );

This is my first time using the "go_router" package in the project. Please let me know if there are any issues or a better way to implement it.


PR Checklist

  • My code adheres to the AppFlowy Style Guide
  • I've listed at least one issue that this PR fixes in the description above.
  • I've added a test(s) to validate changes in this PR, or this PR only contains semantic changes.
  • All existing tests are passing.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/AppFlowy-IO/AppFlowy/pull/3459 **Author:** [@hyj1204](https://github.com/hyj1204) **Created:** 9/19/2023 **Status:** ✅ Merged **Merged:** 9/28/2023 **Merged by:** [@LucasXu0](https://github.com/LucasXu0) **Base:** `main` ← **Head:** `feat/navigation_refactor` --- ### 📝 Commits (10+) - [`5b58f5b`](https://github.com/AppFlowy-IO/AppFlowy/commit/5b58f5bffefd55140b7678540b541f951c91a0b4) refactor: refactor navigator in auth pages to go_router - [`0111bc3`](https://github.com/AppFlowy-IO/AppFlowy/commit/0111bc387b636f329deb756e2c15418dd361c889) feat: add bottom navigation bar as StatefulShellRoute - [`0a184b4`](https://github.com/AppFlowy-IO/AppFlowy/commit/0a184b4233b004e602d8698a3512163bccee551d) chore: remove unused import files - [`e760e71`](https://github.com/AppFlowy-IO/AppFlowy/commit/e760e71f84cc5e0f64e922d87dee26b831ba1126) feat: add mobile icons and improve appbar in home page - [`75f0a01`](https://github.com/AppFlowy-IO/AppFlowy/commit/75f0a011dd31c77e077bfdcb0ce9d32f5e910995) chore: clean code and remove unused import files - [`d72f54e`](https://github.com/AppFlowy-IO/AppFlowy/commit/d72f54eff8831801005c02104821ec61d822cfa4) fix: flutter analyze - [`9783708`](https://github.com/AppFlowy-IO/AppFlowy/commit/9783708e8aa0b2cfdcbca308cad3139d7bfd2ebe) chore: make arguments name as const - [`67deb2c`](https://github.com/AppFlowy-IO/AppFlowy/commit/67deb2cfe87f3bf704f196008f8ac5fe9b6d2a20) chore: extract routes methods - [`6caa061`](https://github.com/AppFlowy-IO/AppFlowy/commit/6caa061695350b4716a93a264ea4472a1646f55d) chore: add comments and delete unnecessary key - [`76f0279`](https://github.com/AppFlowy-IO/AppFlowy/commit/76f02795ec3a786126fdd6c951e23a2b15f471fe) chore: update key value to const ### 📊 Changes **38 files changed** (+894 additions, -277 deletions) <details> <summary>View changed files</summary> 📝 `frontend/appflowy_flutter/lib/mobile/application/mobile_theme_data.dart` (+14 -2) ➕ `frontend/appflowy_flutter/lib/mobile/presentation/details_placeholder_page.dart` (+99 -0) ➕ `frontend/appflowy_flutter/lib/mobile/presentation/home/home.dart` (+1 -0) ➕ `frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart` (+80 -0) ➕ `frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart` (+94 -0) ➖ `frontend/appflowy_flutter/lib/mobile/presentation/mobile_home_page.dart` (+0 -47) ➕ `frontend/appflowy_flutter/lib/mobile/presentation/presentation.dart` (+4 -0) ➕ `frontend/appflowy_flutter/lib/mobile/presentation/root_placeholder_page.dart` (+54 -0) 📝 `frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart` (+28 -10) ➕ `frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart` (+296 -0) 📝 `frontend/appflowy_flutter/lib/startup/tasks/prelude.dart` (+1 -0) 📝 `frontend/appflowy_flutter/lib/user/presentation/helpers/handle_user_profile_result.dart` (+8 -8) 📝 `frontend/appflowy_flutter/lib/user/presentation/helpers/helpers.dart` (+1 -1) 📝 `frontend/appflowy_flutter/lib/user/presentation/router.dart` (+48 -114) 📝 `frontend/appflowy_flutter/lib/user/presentation/screens/encrypt_secret_screen.dart` (+5 -1) 📝 `frontend/appflowy_flutter/lib/user/presentation/screens/screens.dart` (+1 -0) 📝 `frontend/appflowy_flutter/lib/user/presentation/screens/sign_in_screen/sign_in_screen.dart` (+5 -3) 📝 `frontend/appflowy_flutter/lib/user/presentation/screens/skip_log_in_screen.dart` (+2 -6) 📝 `frontend/appflowy_flutter/lib/user/presentation/screens/splash_screen.dart` (+11 -10) 📝 `frontend/appflowy_flutter/lib/user/presentation/screens/workspace_error_screen.dart` (+4 -0) _...and 18 more files_ </details> ### 📄 Description <!--- Thank you for submitting a pull request to AppFlowy. The team will dedicate their best efforts to reviewing and approving your pull request. If you have any questions about the project or feedback for us, please join our [Discord](https://discord.gg/wdjWUXXhtw). --> <!--- If your pull request adds a new feature, please drag and drop a video into this section to showcase what you've done! If not, you may delete this section. --> ### Feature Preview 1. Refactor all the auth pages' routes by the [go_router](https://pub.dev/packages/go_router) package: - Currently, I only did some basic refactoring on the pages related to authentication, other parts still have `Navigator.push`. I use `go_router` package mainly for navigation on mobile. The authentication workflow is still the same as the previous code, the only difference is I add `context.go` to replace the previous page(same as `Navigator.pushReplacement`), so the splash screen will be replaced by home page after the user login. On the home page, if the user clicks 'back' (android back button), the app will quit instead of back to login/skipLoginPage. - Remove the routeName of `SplashScreen`. Due to it is the root page of the app, I set `'/'` as its routeName. - All the routes(using `go_router`) are registed in `appflowy_flutter/lib/startup/tasks/generate_router.dart` 2. Add bottom navigation bar on mobile. I utilized the [StatefulShellRoute.indexedStack](https://pub.dev/documentation/go_router/latest/go_router/StatefulShellRoute/StatefulShellRoute.indexedStack.html) to build the bottom navigation bar. This approach enables each tab to retain its own state, as demonstrated in the following video. Currently, every tab page is just some [example code](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/stateful_shell_route.dart) and I will implement them in the future. https://github.com/AppFlowy-IO/AppFlowy/assets/14248245/26aef070-ca76-4f7e-9b9d-633df8163ad4 3. For the icons used on mobile, I name them starting with **m**, because some icons look different as the desktop even though their purpose/name is similar. **go_router note:** When it comes to passing the arguments between the pages. I set `extra` to a `Map<String, dynamic>` to carry all the arguments, then get it from the `state` in `pageBuilder`. - Pass arguments: Set argument names as constant(start with arg) on the screen page, then use them as the key in the `Map<String, dynamic>`. Pass this `Map<String, dynamic>` as `extra` to GoRoute. ``` context.go( DesktopHomeScreen.routeName, extra: { DesktopHomeScreen.argKey: ValueKey(userProfile.id), DesktopHomeScreen.argUserProfile: userProfile, DesktopHomeScreen.argWorkspaceSetting: workspaceSetting, }, ); ``` Head part and constructor of `DesktopHomeScreen` ``` class DesktopHomeScreen extends StatefulWidget { static const routeName = '/DesktopHomeScreen'; // arguments names to used in GoRouter static const argUserProfile = 'userProfile'; static const argWorkspaceSetting = 'workspaceSetting'; static const argKey = 'key'; final UserProfilePB userProfile; final WorkspaceSettingPB workspaceSetting; const DesktopHomeScreen({ super.key, required this.userProfile, required this.workspaceSetting, }); ``` - Receive arguments in `pageBuilder` ``` GoRoute( path: DesktopHomeScreen.routeName, pageBuilder: (context, state) { final args = state.extra as Map<String, dynamic>; return CustomTransitionPage( child: DesktopHomeScreen( key: args[DesktopHomeScreen.argKey], userProfile: args[DesktopHomeScreen.argUserProfile], workspaceSetting: args[DesktopHomeScreen.argWorkspaceSetting], ), transitionsBuilder: _buildFadeTransition, transitionDuration: _slowDuration, ); }, ); ``` This is my first time using the "go_router" package in the project. Please let me know if there are any issues or a better way to implement it. <!--- List at least one issue here that this PR addresses. If it fixes the issue, please use the [fixes](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests) keyword to close the issue. For example: fixes https://github.com/AppFlowy-IO/AppFlowy/pull/2106 --> --- <!--- Before you mark this PR ready for review, run through this checklist! --> #### PR Checklist - [X] My code adheres to the [AppFlowy Style Guide](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/style-guides) - [X] I've listed at least one issue that this PR fixes in the description above. - [X] I've added a test(s) to validate changes in this PR, or this PR only contains semantic changes. - [X] All existing tests are passing. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
mirror 2026-03-23 22:20:03 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
AppFlowy-IO/AppFlowy#5731
No description provided.