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

How to conditionally control modal closure (using Riverpod)? #342

Open
aleksimatias opened this issue Nov 13, 2024 · 4 comments
Open

How to conditionally control modal closure (using Riverpod)? #342

aleksimatias opened this issue Nov 13, 2024 · 4 comments
Assignees
Labels
question Further information is requested

Comments

@aleksimatias
Copy link

aleksimatias commented Nov 13, 2024

Question on how to correctly handle enableDrag, barrierDismissable and system pop.

Consider the following example:

  • The first WoltModalSheetPage contains a counter
  • Counter value is stored inside a Riverpod provider
  • When counter reaches a max value given to it, the modal sheet navigates to the second page
  • If counter is at its maximum, I would like to guard enableDrag, barrierDismissable by disabling them.

Below is an example of how I currently have WoltModalSheet.show setup. I was able to conditionally hide the trailing widget using pageContentDecorator, but have been unsuccessful with enableDrag and barrierDismissable.

Considering my current setup, what's the best way to conditionalize enableDrag and barrierDismissable?
What is the best way to guard system pop (by displaying _showDismissConfirmationDialog)?

  Future<void> showBottomSheet() async {
    final isCounterMax = ref.read(modalSheetProvider).isCounterMax;

    WoltModalSheet.show<void>(
        context: context,
        pageListBuilder: (modalSheetContext) {
          final pages = _buildPages(modalSheetContext);
          return pages;
        },
        pageContentDecorator: (child) {
          return ProviderScope(
            overrides: [
              modalSheetProvider.overrideWith(() => ModalSheetStateNotifier()),
            ],
            child: child,
          );
        },
        modalTypeBuilder: (modalContext) => WoltModalType.bottomSheet(),
        onModalDismissedWithBarrierTap: isCounterMax
                ? _showDismissConfirmationDialog
                : closeBottomSheet,
        onModalDismissedWithDrag: closeBottomSheet,
        barrierDismissible: !isCounterMax,
        enableDrag: !isCounterMax
        );
  }
@aleksimatias
Copy link
Author

Follow-up question related to Riverpod usage (sorry, out of scope for the original question, can create a new issue if needed)

Example, page 1: Adding items, page 2: Deleting items
Child widgets of pages listen to state through ref.watch(provider).
If items are deleted on page 2, the deletion is successful, but UI doesn't update.

UI updates are functional if used inside a normal showModalBottomSheet, so their logic should be sound.

@aleksimatias aleksimatias changed the title How to conditionally control modal closure? How to conditionally control modal closure (using Riverpod)? Nov 15, 2024
@ulusoyca
Copy link
Collaborator

ulusoyca commented Nov 15, 2024

Hi There!

ref.watch(provider) and context.watch means that you want to watch the entire modal content. Please create your provider using the modalDecorator (using the latest release with hotfix). See this section in the ReadMe.

WoltModalSheet.show(
  context: context,
  pageContentDecorator: (widget) => Align(
      alignment: Alignment.bottomCenter,
      child: ClipRRect(
        ..., // Your clipRRect properties
        child: BackdropFilter(
          ..., // Your backdrop filter properties
          child: widget,
        ),
    ),
  ),
  modalDecorator: (child) {
    // Wrap the modal with `ChangeNotifierProvider` to manage the state of 
    // the entire pages in the modal.
    return ChangeNotifierProvider<StoreOnlineViewModel>(
      builder: (_, __) => StoreOnlineViewModel(),
      child: child,
    );
  },
  pageListBuilder: (context) {
    final viewModel = context.read<StoreOnlineViewModel>();
    return [
      WoltModalSheetPage(
        child: FirstPageContent(viewModel.data),
        pageTitle: Text('First Page Title'),
        // Other properties...
      ),
      WoltModalSheetPage(
        child: SecondPageContent(viewModel.data),
        pageTitle: Text('Second Page Title'),
        // Other properties...
      ),
    ];
  },
);

When it comes to conditional displaying the content; please refer to this example:

the source code

Screen.Recording.2024-11-15.at.13.29.18.mov

@ulusoyca ulusoyca self-assigned this Nov 15, 2024
@ulusoyca ulusoyca added the question Further information is requested label Nov 15, 2024
@aleksimatias
Copy link
Author

Thanks for the response.

You mentioned the use of modalContentProvider - was this a typo or should this be available in the latest version?
Using version 0.9.4 - no sign of it

@ulusoyca
Copy link
Collaborator

Ups, I edited my answer. modalDecorator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants