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

[Breaking Change] Refactor page navigation in page list, remove pageIndexNotifier and pageListBuilderNotifier #182

Closed
wants to merge 2 commits into from

Conversation

ulusoyca
Copy link
Collaborator

Overview

This pull request introduces breaking and major changes to the in-modal navigation system of the WoltModalSheet. The changes are aimed at increasing flexibility and improving the developer experience by allowing dynamic navigation updates, multiple page management, and a more intuitive interaction model for in-modal navigation.

Key Changes

  1. Dynamic Page Addition and Management:
    • addPagesToStack and its overload addPageToStack: These methods facilitate the addition of one or multiple pages to the navigation stack without altering while staying at current page. This is particularly useful for preloading pages in scenarios where the user might need to interact with multiple subsequent screens.
addAndReplace.mov
  • pushPages and its overload pushPage: Extended to allow pushing a list of pages onto the navigation stack, making the first of these new pages the currently visible one. This is crucial for workflows where a sequence of new pages needs to be added and immediately accessed.
push.mov
  1. Page Replacement Enhancements:

    • addOrReplacePages and addOrReplacePage: Updated methods to dynamically append new pages or replace existing pages beyond the current one in the navigation stack. This feature supports dynamic user journeys where decisions on earlier pages might change the subsequent path.
    • replaceCurrentPage: A new method that replaces the current page in the stack without disturbing other pages, ensuring a smooth transition and immediate update of content without full navigation stack refresh.
    • replaceAllPages: Replaces all pages in the stack while attempting to maintain the relative position of the current page, thus ensuring continuity in the user's navigation context.
  2. Navigation Control Improvements:

    • showNext and showPrevious: Methods to navigate forward or backward in the modal sheet stack, enhanced to handle edge cases and ensure that navigation commands respect the bounds of the page list.
  3. State Management and Error Handling:

    • Enhanced state management to ensure robust handling of navigation state across asynchronous operations. This includes checks to ensure operations are only performed when the widget context is active, preventing errors related to accessing deactivated widget ancestors.

Migration Notes

  • TODO

Testing

  • TODO

Future Work

  • TODO

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.

  • My PR includes tests for all changed/updated/fixed behaviors.

  • All existing and new tests are passing.

  • I updated/added relevant documentation (doc comments with ///).

  • The analyzer (melos run analyze) does not report any problems on my PR.

  • The package compiles with the minimum Flutter version stated in the pubspec.yaml

Breaking Change

Does your PR require plugin users to manually update their apps to accommodate your change?

  • Yes, this is a breaking change.
  • No, this is not a breaking change.

Copy link

github-actions bot commented Apr 19, 2024

Visit the preview URL for this PR (updated for commit d2b02bb):

(expires Fri, 26 Apr 2024 16:47:34 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: 906758393beb0353b979d020649d6a1efc40fb5b

@ulusoyca ulusoyca force-pushed the introduce-imperative-navigation branch from 14ee6fe to d2b02bb Compare April 19, 2024 16:44
Copy link
Collaborator

@TahaTesser TahaTesser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

/// This method can be expensive (it walks the element tree).
static WoltModalSheetState of(BuildContext context) {
// Handles the case where the input context is a navigator element.
WoltModalSheetState? wms;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't public but i suggest to use words as they're readable and searchable if needed.

Suggested change
WoltModalSheetState? wms;
WoltModalSheetState? woltModalSheetState;

// Handles the case where the input context is a navigator element.
WoltModalSheetState? wms;
if (context is StatefulElement && context.state is WoltModalSheetState) {
wms = context.state as WoltModalSheetState;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wms = context.state as WoltModalSheetState;
woltModalSheetState = context.state as WoltModalSheetState;

if (context is StatefulElement && context.state is WoltModalSheetState) {
wms = context.state as WoltModalSheetState;
}
wms ??= context.findAncestorStateOfType<WoltModalSheetState>();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wms ??= context.findAncestorStateOfType<WoltModalSheetState>();
woltModalSheetState ??= context.findAncestorStateOfType<WoltModalSheetState>();

wms ??= context.findAncestorStateOfType<WoltModalSheetState>();

assert(() {
if (wms == null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (wms == null) {
if (woltModalSheetState == null) {

}
return true;
}());
return wms!;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return wms!;
return woltModalSheetState!;

Comment on lines +667 to +675
bool found = false;
final List<SliverWoltModalSheetPage> newPages = _pages.map((p) {
if (p.id == id) {
found = true;
return page;
}
return p;
}).toList();
if (!found) return false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool found = false;
final List<SliverWoltModalSheetPage> newPages = _pages.map((p) {
if (p.id == id) {
found = true;
return page;
}
return p;
}).toList();
if (!found) return false;
final List<SliverWoltModalSheetPage> newPages = _pages.where((SliverWoltModalSheetPage sheetPage) {
return sheetPage.id == id;
}).toList();
if (newPages.isEmpty) {
return false;
}

This could where and avoid using inline veriables. I haven't tested the code so please verify it works.

Comment on lines +609 to +610
void pushPages(List<SliverWoltModalSheetPage> pages) {
setState(() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void pushPages(List<SliverWoltModalSheetPage> pages) {
setState(() {
void pushPages(List<SliverWoltModalSheetPage> pages) {
if (pages.isEmpty) {
return;
}
setState(() {

if pages is empty, avoid calling setState.

///
/// Returns:
/// None.
void replaceAllPages(List<SliverWoltModalSheetPage> newPages) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void replaceAllPages(List<SliverWoltModalSheetPage> newPages) {
void replaceAllPages(List<SliverWoltModalSheetPage> newPages) {
if (newPages.isEmpty) {
return;
}

Comment on lines +612 to +615
if (pages.isNotEmpty) {
_selectedPageIndex =
_pages.length - pages.length; // Set to the first of the newly added pages.
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (pages.isNotEmpty) {
_selectedPageIndex =
_pages.length - pages.length; // Set to the first of the newly added pages.
}
_selectedPageIndex =
_pages.length - pages.length; // Set to the first of the newly added pages.

if we're checking pages isn't empty above, we can feel confident page is not empty and update this.

/// navigating to a specific page or popping a page.
final Object? id;


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

@ulusoyca
Copy link
Collaborator Author

Closing this because a new PR will be opened.

@ulusoyca ulusoyca closed this Apr 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants