Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EPIC] Feat: Dynamic Navigation Menu #4

Closed
10 tasks done
nelsonic opened this issue Apr 24, 2023 · 19 comments · Fixed by #5
Closed
10 tasks done

[EPIC] Feat: Dynamic Navigation Menu #4

nelsonic opened this issue Apr 24, 2023 · 19 comments · Fixed by #5
Assignees
Labels
discuss Share your constructive thoughts on how to make progress with this issue enhancement New feature or enhancement of existing functionality flutter Flutter related issues help wanted If you can help make progress with this issue, please comment! priority-1 Highest priority issue. This is costing us money every minute that passes.

Comments

@nelsonic
Copy link
Member

nelsonic commented Apr 24, 2023

To facilitate having an arbitrary number of lists,
we need to investigate how to dynamically update the Navigation Menu in a Flutter App.

Requirements / Roadmap:

  • MUST allow new menu items to be added/removed by the person
  • MUST NOT require re-compiling/re-releasing the Flutter App.
  • SHOULD allow the person to re-order the Nav Menu Items manually.
  • SHOULD support emoji, icons or images (GIF, JPEG, PNG & SVG up to 64x64px)
  • SHOULD allow selection of text color
  • SHOULD allow for sub-menus up to 3 levels. e.g:
Menu Item                |  Level
________________________________
People.                      0
|__ Online Now               1
    |__ Family               2
    |__ Friends              2
        |__ Sports Team      3 
        |__ Gamerz           3
    |__ Work                 2
|__ Everyone                 1

Todo

The first thing we need to is:

  • Investigate [and this should be time-boxed to T4h] if Nav Menu be dynamically generated 🔍
    e.g: based on JSON returned by a server response (and cached on the device).
    • Write-up your findings as comments in this issue and if you can get something working on localhost, 🧑‍💻
    • Create a PR extending this demo to include dynamic menu items. 🚀

Note: my initial T5m Googling for "flutter navigation drawer dynamic" returned the following:

@nelsonic nelsonic added enhancement New feature or enhancement of existing functionality help wanted If you can help make progress with this issue, please comment! priority-1 Highest priority issue. This is costing us money every minute that passes. flutter Flutter related issues discuss Share your constructive thoughts on how to make progress with this issue labels Apr 24, 2023
@nelsonic nelsonic moved this to 🔖 Ready for Development in dwyl app kanban Apr 24, 2023
@LuchoTurtle
Copy link
Member

LuchoTurtle commented Apr 24, 2023

Alright. After I finish the work done in dwyl/calendar#25, I'll pick this up.
After having an initial read, although I understand the question, could you clarify how we will handle offline usage of the app? Assuming we are showing lists within the navigation menu, this assumes the user person needs to have an online connection to fetch the lists so they are displayed in the menu.

So if there's no internet, will the user not be able to use the navigation menu? What caching strategy would you recommend? I know this is forward-looking but I'm just hoping to clarify this beforehand.

@nelsonic
Copy link
Member Author

Thanks for confirming there is enough info in here to get going. 👌

For now, we just need to confirm that it's possible for the items in the Flutter Navigation Drawer
to updated dynamically based on input by the person using the App. 📱

I'm always glad to see proactive questions. 🎉
Hopefully this is addressed in: dwyl/mvp#363
In the MVP and eventually the App, the Nav Menu will actually be a specific of list
That way we can take advantage of the list re-ordering work you have already done
to allow people to customise/personalise their Menu to their needs/tastes. ✨

But again, for now, we just want to confirm that we can dynamically create the Navigation Drawer. 👌
The complexity/detail of how the rest will work will be fleshed out in subsequent issues. 💭

@LuchoTurtle LuchoTurtle moved this from 🔖 Ready for Development to 🏗 In progress in dwyl app kanban Apr 26, 2023
@LuchoTurtle
Copy link
Member

LuchoTurtle commented Apr 26, 2023

As I'm reading through this, I need some clarifications on some points because I feel like the original description lacks specificity and there aren't any Figma wireframes to go for:

  • what exactly do menu items pertain to? Do they refer to pages inside the app? Do they refer to a way for a person to organize their lists?
  • assuming "menu items" are pages, are app pages going to be created ad-hoc? Can pages even be created on the fly inside the app? And what kind of pages?
  • are prolonged taps/drag n drop good ways of reordering the nav menu items?
  • how should the user customize the text color? Should there be a dedicated page for editing the menu item?

I've taken a look at https://github.com/nickyrabit/NavigationDrawer-with-Dynamic-Menu-and-Submenu-using-Flutter-Pageview and although it certainly is useful, it's just conditional rendering based on the person's permissions. That is, it just shows and hides specific page routes according to what a user can or cannot do.

What you seem to be asking is to create new pages on the fly (for this we would need a template - but even then, what are these new pages pertaining to? Seems a lot like Notion). But I'm not sure if that's even possible. The only thing remotely close I found was https://stackoverflow.com/questions/63857496/how-to-add-tabs-dynamically-to-tabbar-in-flutter but it just pertains to Tabs, not Navigation Routes of the app.

MaterialApp (which is used at the root of the project) does have a field to handle dynamic routing: https://stackoverflow.com/questions/49065668/dynamic-navigation-routes. In here, we can handle routes even if they are not statically defined...

I know we can pop and push named routes like we do with pushNavigator (like we're currently doing) -> https://stackoverflow.com/questions/71471867/how-to-implement-arguments-to-dynamic-routing. But the problem of what screen/widget should be rendered?

Perhaps I'm overcomplicating things... or outright interpreting what you're saying wrong 😅

@LuchoTurtle
Copy link
Member

Stumbled upon https://stackoverflow.com/questions/75234251/how-to-implement-a-flutter-drawer-menu-submenu-feature-where-menu-submenu-render but it's a dead-end. Just for future notice.

@nelsonic
Copy link
Member Author

@LuchoTurtle thank you for seeking further clarification. 🎉
(it saves time in the long run to ask as many questions as possible up-front 👌)

You are definitely over-complicating things.
We want a Nav Menu that is generated from a .json file dynamically. That's it.
Right now that's all we need to test. If that step is possible then we can try the more advanced part.
Which, yes, is routing to a specific screen. But we definitely aren't creating "new pages on the fly".
The screens will already exist.

Here is a good example of a Dynamic Nav Drawer in a Native iOS App:

image

The question you are trying to answer is: How do they achieve this?

@nelsonic
Copy link
Member Author

In the Gmail Scenario, I created a new label on my Desktop (using the GMail Web interface in Google Chrome)
and it immediately appeared in my GMail Native iOS App on my Phone.
This is Dyanmic Nav. No re-compilation. No "screens on the fly".
Clearly they rendering the LABELS section of the Nav based on an API request.
That is what we are trying to figure out right now. 🙏

@LuchoTurtle
Copy link
Member

Thank you for replying.
I might be over-complicating things (and definitely not using the best words when asking my questions) but the concept of a menu item seems to be a bit abstract to me of what they exactly pertain to.

Hence why I was wondering about "creating pages on the fly" - what pages are they redirecting to? I'm using page and screen interchangeably. In Flutter I would need to know where I'm navigating into. But, as you've said, that's Level 2.

The example you've shown with Gmail is simply filtering e-mails by the label. I understand what you've said that you want to create new menu items and render them accordingly and be shown on all devices - no recompilation needed. I was just looking into more clarification of what these menu items referred to and their purpose.

Nonetheless, I'm now more certain about what I need to work out. The rest of the requirements (for example, changing text colour) can be fleshed out at a later stage.

Thanks 👍

@LuchoTurtle
Copy link
Member

I've been and am currently working on getting nested tiles with TileView working on different levels and will try to create them from a json file, as you've stated.

@nelsonic
Copy link
Member Author

When I edit the label on the GMail Web Interface:

image

image

It changes on the Web:
image

But most importantly it's instantly reflected in the iOS App:

ios-gmail-nav-menu-dynamic

Zero lag/latency. It's just there. 🎉

@LuchoTurtle
Copy link
Member

Modals 🤢

@nelsonic
Copy link
Member Author

Yeah, Modals are evil. and they're everywhere. 🙄

@nelsonic
Copy link
Member Author

As for where the menu items in the Nav will "link to" they will simply take the person to another screen.
For now we don't need to know what that screen is.
But for testing purposes you can just create a screen that renders the text of the menu item.

LuchoTurtle added a commit that referenced this issue May 9, 2023
@nelsonic
Copy link
Member Author

@LuchoTurtle as discussed in our in-person standup today,
our objective with the i18n in the menu is to stick to the default way it's done in Flutter as much as possible.
That means having a separate language file for each new language we want to add to the App.
Please see: dwyl/learn-flutter#90 🙏

@LuchoTurtle
Copy link
Member

Understood.
For those that are unaware, I initially thought we wanted to have each label in the menu item coming from the API/JSON file and allow the user to i18nize their own menu items in different languages.

If you want such implementation, you can visit the state of the repo on the commit https://github.com/dwyl/flutter-navigation-menu-demo/tree/d1383a5e1e3271de6f409f844fe34f33cb9f3685.

However, similarly to what happens with Gmail, user labels do not get translated. What we want is:

  • follow the regular structure of i18n in Flutter apps - having key-value files for each language (e.g. en.json and pt.json) where each widget text has its own translation.
  • and have a dictionary that will check if any of the words from the dynamic menu item are translatable. For example, if a menu item has an "Início" label, we'll have a simple map that will translate pt to en (with key-value like `"Início": "Home"). So it's a simple lookup and update the widget accordingly.

@LuchoTurtle
Copy link
Member

Having a bit of trouble getting the tests to run correctly after making changes with i18n (different from the previous approach).
It seems that running each test individually works and all pass. But if I run flutter test --coverage, the second test widget test breaks.
I've narrowed down to the line inside app_localization.dart...

  Future loadLanguage() async {
    final path = 'assets/i18n/${_locale.languageCode}.json';
    String jsonStringValues = await rootBundle.loadString(path);   // breaks here

Apparently, there are constraints accessing rootBundle during tests (as seen in https://stackoverflow.com/questions/72015892/how-to-get-result-of-rootbundle-loadstringkey-during-flutter-widget-test).

Adding TestWidgetsFlutterBinding.ensureInitialized(); on top of each test doesn't seem to be working either. 😕

@LuchoTurtle
Copy link
Member

After reading https://stackoverflow.com/questions/60079645/flutter-how-to-mock-a-call-to-rootbundle-loadstring-then-reset-the-mocked, it seems that almost all tests pass...

By setting String jsonStringValues = await rootBundle.loadString(path, cache: false); (rootBundle is not cached), all but one test pass. I'll investigate what's going on with the last one

LuchoTurtle added a commit that referenced this issue May 10, 2023
…8n in their dynamic menu items. #4"

This reverts commit d1383a5.
LuchoTurtle added a commit that referenced this issue May 10, 2023
LuchoTurtle added a commit that referenced this issue May 10, 2023
Person can't make switches yet.
LuchoTurtle added a commit that referenced this issue May 10, 2023
LuchoTurtle added a commit that referenced this issue May 10, 2023
LuchoTurtle added a commit that referenced this issue May 11, 2023
LuchoTurtle added a commit that referenced this issue May 12, 2023
LuchoTurtle added a commit that referenced this issue May 12, 2023
LuchoTurtle added a commit that referenced this issue May 12, 2023
@nelsonic nelsonic moved this from 🏗 In progress to ⏳Awaiting Review in dwyl app kanban May 19, 2023
@github-project-automation github-project-automation bot moved this from ⏳Awaiting Review to ✅ Done in dwyl app kanban Jun 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discuss Share your constructive thoughts on how to make progress with this issue enhancement New feature or enhancement of existing functionality flutter Flutter related issues help wanted If you can help make progress with this issue, please comment! priority-1 Highest priority issue. This is costing us money every minute that passes.
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants