fujidaiti / smooth_sheets

Sheet widgets with smooth motion and great flexibility.
https://pub.dev/packages/smooth_sheets
MIT License
194 stars 19 forks source link

GoRouter context.pop() pops sheet instead of AlertDialog #121

Open bqubique opened 3 months ago

bqubique commented 3 months ago

Using GoRouter and showing a dialog using showDialog(context: context, ...). When popping using context.pop() (of GoRouter) pages from the sheet are popped instead of the dialog.

Using Navigator.of(context).pop() works fine. Please let me know if this is an issue related to GoRouter instead of smooth_sheets so I can file a bug there.

fujidaiti commented 3 months ago

Please post an executable code to reproduce the problem. I can't help without knowing the implementation details.

bqubique commented 3 months ago

Sorry for omitting a code snippet. Here you go:

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:smooth_sheets/smooth_sheets.dart';

void main() {
  runApp(const _AiPlaylistGeneratorExample());
}

class _AiPlaylistGeneratorExample extends StatelessWidget {
  const _AiPlaylistGeneratorExample();

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      debugShowCheckedModeBanner: false,
      routerConfig: router,
    );
  }
}

// ----------------------------------------------------------
// Routes
// ----------------------------------------------------------

final sheetTransitionObserver = NavigationSheetTransitionObserver();

final router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => const _Root(),
      routes: [_sheetShellRoute],
    ),
  ],
);

// A ShellRoute is used to create a new Navigator for nested navigation in the sheet.
final _sheetShellRoute = ShellRoute(
  observers: [sheetTransitionObserver],
  pageBuilder: (context, state, navigator) {
    // Use ModalSheetPage to show a modal sheet.
    return ModalSheetPage(
      child: _SheetShell(
        navigator: navigator,
        transitionObserver: sheetTransitionObserver,
      ),
    );
  },
  routes: [_introRoute],
);

final _introRoute = GoRoute(
  path: 'intro',
  pageBuilder: (context, state) {
    return const DraggableNavigationSheetPage(child: _IntroPage());
  },
  routes: [_genreRoute],
);

final _genreRoute = GoRoute(
  path: 'genre',
  pageBuilder: (context, state) {
    return const DraggableNavigationSheetPage(child: _SelectGenrePage());
  },
);

// ----------------------------------------------------------
// Pages
// ----------------------------------------------------------

class _Root extends StatelessWidget {
  const _Root();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: ElevatedButton(
        onPressed: () => context.go('/intro'),
        child: const Text('Generate Playlist'),
      ),
    ));
  }
}

class _SheetShell extends StatelessWidget {
  const _SheetShell(
      {required this.transitionObserver, required this.navigator});

  final NavigationSheetTransitionObserver transitionObserver;
  final Widget navigator;

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      bottom: false,
      child: SheetDismissible(
        child: NavigationSheet(
          transitionObserver: sheetTransitionObserver,
          child: Material(
            borderRadius: BorderRadius.circular(16),
            clipBehavior: Clip.antiAlias,
            color: Theme.of(context).colorScheme.surface,
            child: navigator,
          ),
        ),
      ),
    );
  }
}

class _IntroPage extends StatelessWidget {
  const _IntroPage();

  @override
  Widget build(BuildContext context) {
    return SheetContentScaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(48.0),
          child: FilledButton(
            onPressed: () => context.go('/intro/genre'),
            child: const Text('Continue'),
          ),
        ),
      ),
    );
  }
}

class _SelectGenrePage extends StatelessWidget {
  const _SelectGenrePage();

  @override
  Widget build(BuildContext context) {
    return SheetContentScaffold(
      body: const SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            SizedBox(height: 48),
            Text("hello"),
            SizedBox(height: 48),
          ],
        ),
      ),
      bottomBar: _BottomActionBar(
        label: 'Next',
        onPressed: () => showDialog(
          context: context,
          builder: (context) => AlertDialog(
            actions: [
              TextButton(
                  onPressed: () {
                    context.pop();
                  },
                  child: const Text('Pop this dialog'))
            ],
          ),
        ),
      ),
    );
  }
}

class _BottomActionBar extends StatelessWidget {
  const _BottomActionBar({
    required this.label,
    required this.onPressed,
  });

  final String label;
  final VoidCallback? onPressed;

  @override
  Widget build(BuildContext context) {
    return StickyBottomBarVisibility(
      child: SafeArea(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            FilledButton(
              onPressed: onPressed,
              child: Text(label),
            ),
          ],
        ),
      ),
    );
  }
}

I tried excluding anything which seemed unnecessary. I'm attaching a video of it as well for reference. 2024-05-11 9 51 47 pm

Edit: Worth mentioning this happens only on the succeeding pages and not the first page of the modal. As you can see from the GIF.