flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
165.01k stars 27.19k forks source link

go_router browser back button to dismiss dialog #112765

Open radzish opened 1 year ago

radzish commented 1 year ago

See following code:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({super.key});

  late final GoRouter _router = GoRouter(
    routes: [
      GoRoute(
        path: '/',
        builder: (context, state) => MyPage(),
      ),
    ],
  );

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

class MyPage extends StatelessWidget {
  const MyPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: TextButton(
        onPressed: () {
          showDialog(
            context: context,
            builder: (_) {
              return Center(child: Container(width: 300, height: 200, color: Colors.green));
            },
          );
        },
        child: Text('open'),
      ),
    );
  }
}

Steps to reproduce:

  1. Open app link in new browser tab
  2. Press "open" button => dialog is shown
  3. Press browser "Back" button => application is navigated back to "New Tab". Expected behavior: dialog should be closed, application should remain opened.

I made simple example without using go_router and all works as expected.

go_router version: 5.0.1

[✓] Flutter (Channel stable, 3.3.2, on Ubuntu 22.04.1 LTS 5.15.0-48-generic, locale en_US.UTF-8)
    • Flutter version 3.3.2 on channel stable at /home/kernel/work/common/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision e3c29ec00c (3 weeks ago), 2022-09-14 08:46:55 -0500
    • Engine revision a4ff2c53d8
    • Dart version 2.18.1
    • DevTools version 2.15.0

[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
    • Ubuntu clang version 14.0.0-1ubuntu1
    • cmake version 3.22.1
    • ninja version 1.10.1
    • pkg-config version 0.29.2

[!] Android Studio (not installed)
    • Android Studio not found; download from https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions).

[✓] IntelliJ IDEA Ultimate Edition (version 2022.2)
    • IntelliJ at /home/kernel/work/common/idea
    • Flutter plugin version 70.0.5
    • Dart plugin version 222.3739.24

[✓] Connected device (2 available)
    • Linux (desktop) • linux  • linux-x64      • Ubuntu 22.04.1 LTS 5.15.0-48-generic
    • Chrome (web)    • chrome • web-javascript • Google Chrome 106.0.5249.61

[✓] HTTP Host Availability
    • All required HTTP hosts are available
huycozy commented 1 year ago

I made simple example without using go_router and all works as expected.

@radzish Could you provide this sample code so that we may verify this?

radzish commented 1 year ago

@huycozy, see code without go_router below:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyPage(),
    );
  }
}

class MyPage extends StatelessWidget {
  const MyPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: TextButton(
        onPressed: () {
          showDialog(
            context: context,
            builder: (_) {
              return Center(child: Container(width: 300, height: 200, color: Colors.green));
            },
          );
        },
        child: Text('open'),
      ),
    );
  }
}
huycozy commented 1 year ago

@radzish thanks for providing this sample code. This issue is reproducible on the latest stable and master channels with go_router: ^5.0.5.

Demo (with go_router and without go_router) | with go_router | without go_router | | --------------- | --------------- |
flutter doctor -v ```bash [✓] Flutter (Channel stable, 3.3.3, on macOS 12.6 21G115 darwin-x64, locale en-VN) • Flutter version 3.3.3 on channel stable at /Users/huynq/Documents/GitHub/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 18a827f393 (10 hours ago), 2022-09-28 10:03:14 -0700 • Engine revision 5c984c26eb • Dart version 2.18.2 • DevTools version 2.15.0 [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0) • Android SDK at /Users/huynq/Library/Android/sdk • Platform android-33, build-tools 31.0.0 • ANDROID_HOME = /Users/huynq/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 14.0.1) • Xcode at /Applications/Xcode14.0.1.app/Contents/Developer • Build 14A400 • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2021.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840) [✓] IntelliJ IDEA Community Edition (version 2022.2.2) • IntelliJ at /Applications/IntelliJ IDEA CE.app • Flutter plugin version 70.0.5 • Dart plugin version 222.4167.21 [✓] IntelliJ IDEA Community Edition (version 2022.1.1) • IntelliJ at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/IDEA-C/ch-0/221.5591.52/IntelliJ IDEA CE.app • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart [✓] VS Code (version 1.71.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.48.0 [✓] Connected device (4 available) • SM T225 (mobile) • R9JT3004VRJ • android-arm64 • Android 12 (API 31) • iPhone 14 Pro Max (mobile) • 332079AF-E895-4685-910E-7B1E18B0C6B8 • ios • com.apple.CoreSimulator.SimRuntime.iOS-16-0 (simulator) • macOS (desktop) • macos • darwin-x64 • macOS 12.6 21G115 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 105.0.5195.125 [✓] HTTP Host Availability • All required HTTP hosts are available • No issues found! ``` ```bash [✓] Flutter (Channel master, 3.4.0-37.0.pre.14, on macOS 12.6 21G115 darwin-x64, locale en-VN) • Flutter version 3.4.0-37.0.pre.14 on channel master at /Users/huynq/Documents/GitHub/flutter_master • Upstream repository https://github.com/flutter/flutter.git • Framework revision 35afe1bdac (45 minutes ago), 2022-10-03 18:41:23 -0700 • Engine revision 83c68740e3 • Dart version 2.19.0 (build 2.19.0-268.0.dev) • DevTools version 2.17.0 [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0) • Android SDK at /Users/huynq/Library/Android/sdk • Platform android-33, build-tools 31.0.0 • ANDROID_HOME = /Users/huynq/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 14.0.1) • Xcode at /Applications/Xcode14.0.1.app/Contents/Developer • Build 14A400 • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2021.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840) [✓] IntelliJ IDEA Community Edition (version 2022.2.2) • IntelliJ at /Applications/IntelliJ IDEA CE.app • Flutter plugin version 70.0.5 • Dart plugin version 222.4167.21 [✓] IntelliJ IDEA Community Edition (version 2022.1.1) • IntelliJ at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/IDEA-C/ch-0/221.5591.52/IntelliJ IDEA CE.app • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart [✓] VS Code (version 1.71.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.48.0 [✓] Connected device (3 available) • SM T225 (mobile) • R9JT3004VRJ • android-arm64 • Android 12 (API 31) • macOS (desktop) • macos • darwin-x64 • macOS 12.6 21G115 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 105.0.5195.125 [✓] HTTP Host Availability • All required HTTP hosts are available • No issues found! ```

Labeling this issue for further insight from the team!

rurickdev commented 1 year ago

I would like to say that the GoRouter.of(this).pop() can't dismiss a dialog too, in mobile it navigates to the previous page, and if you are in the root route it throws an error saying there are no parent routes to pop to. I believe this is related.

chunhtai commented 1 year ago

the browser backbutton is a deeplink to a sepecific previous url, so I think this is working as Intended, the GoRouter.of(this).pop() is a different story though, that is a bug we should fix

srcker commented 1 year ago

I had the same problem

jesther-ai commented 1 year ago

Same problem here

pradeep-here commented 1 year ago

the browser backbutton is a deeplink to a sepecific previous url, so I think this is working as Intended, the GoRouter.of(this).pop() is a different story though, that is a bug we should fix

Hi, any update please on GoRouter.of(this).pop() Is this being tracked in some other issue.

AtamyratBabayev commented 1 year ago

Hi! I faced the same behavior with Drawer. On Android when system back button pressed, GoRouter removes last page from pages stack instead of closing Drawer. Moreover, Navigator.of(ctx).pop() works as expected and closes drawer, but context.pop() - just popping page from the stack. I think this issues are related. Are there any updates? Small update: When Android system back button pressed: If the stack is empty (couldn't pop anymore), then Drawer closes as expected.

LarYoungruu commented 1 year ago

Same issue, context.pop() cant dismiss dialog, only use Navigator.of(context).pop()

xaoo commented 1 year ago

Damn, same issue with my showDialog(useRootNavigator: true), I need useRootNavigator: true because I need the complete screen size, not just the remaining screen where the dialog is a child widget.

vincza commented 1 year ago

Same issue is reproducing for me on a web application.

percula commented 1 year ago

Same issue here. On web, I'd expect it to go to the previous page. On Android, however, I wouldn't consider this "working as intended". Dialogs should always be dismissible on Android with the back button.

xaoo commented 1 year ago

(Flutter WEB) Does anyone have any idea how to fetch the showDialog() pop-up from Navigator/GoRouter, and close it on browser back button press? This issue wont be fixed any time soon, its P5 and there are 5k+ issue in the backlog.

iyar-avital commented 1 year ago

Same issue. Any update please?

AtamyratBabayev commented 1 year ago

(Flutter WEB) Does anyone have any idea how to fetch the showDialog() pop-up from Navigator/GoRouter, and close it on browser back button press? This issue wont be fixed any time soon, its P5 and there are 5k+ issue in the backlog.

Hi @xaoo !

Did you try BackButtonListener with dialog? I used it with Overlay and it works well. In my case Overlay pushes to the next page and I had to check if current page is in focus.

Unfortunately I'm not familiar with browser flutter development. But hope, this will work.

iyar-avital commented 1 year ago

(Flutter WEB) Does anyone have any idea how to fetch the showDialog() pop-up from Navigator/GoRouter, and close it on browser back button press? This issue wont be fixed any time soon, its P5 and there are 5k+ issue in the backlog.

Hi @xaoo !

Did you try BackButtonListener with dialog? I used it with Overlay and it works well. In my case Overlay pushes to the next page and I had to check if current page is in focus.

Unfortunately I'm not familiar with browser flutter development. But hope, this will work.

I tried, it didn’t work. read what is written here: https://github.com/flutter/flutter/issues/71122#issuecomment-733864359

miladrashidizade commented 8 months ago

Hi there, you should opening dialog or bottom sheet with go router, like above code:

/// Call the method GoRouter.of(context).push("dialog");

/// Write in routes part. GoRoute( path: "dialog", builder: (context, state) => DialogPage( child: SampleDialogWidget(), ), ),

/// This is a for Dialog class DialogPage extends Page { final Offset? anchorPoint; final Color? barrierColor; final bool barrierDismissible; final String? barrierLabel; final bool useSafeArea; final CapturedThemes? themes; final Widget child;

const DialogPage({ required this.child, this.anchorPoint, this.barrierColor = Colors.transparent, this.barrierDismissible = true, this.barrierLabel, this.useSafeArea = true, this.themes, super.key, super.name, super.arguments, super.restorationId, });

@override Route createRoute(BuildContext context) => DialogRoute( context: context, settings: this, builder: (context) => child, anchorPoint: anchorPoint, barrierColor: barrierColor, barrierDismissible: barrierDismissible, barrierLabel: barrierLabel, useSafeArea: useSafeArea, themes: themes, ); }

/// This is for BottomSheet class BottomSheet extends Page { final Offset? anchorPoint; final Color? barrierColor; final bool barrierDismissible; final String? barrierLabel; final bool useSafeArea; final CapturedThemes? themes; final bool isScrollControlled; final Widget child;

const BottomSheet({ required this.child, this.anchorPoint, this.barrierColor = Colors.transparent, this.barrierDismissible = true, this.barrierLabel, this.useSafeArea = true, this.isScrollControlled = false, this.themes, super.key, super.name, super.arguments, super.restorationId, });

@override Route createRoute(BuildContext context) => ModalBottomSheetRoute( settings: this, isScrollControlled: isScrollControlled, builder: (context) => child, anchorPoint: anchorPoint, barrierLabel: barrierLabel, useSafeArea: useSafeArea, ); }

WieFel commented 2 months ago

+1