Skip to content

[image_picker][web] cancel cause picker to never return #92176

Description

@aoatmon

Steps to Reproduce

  • clone this repository or use the code sample below
  • run flutter run -d chrome
  • tap the fab
  • when the picker window show up choose cancel

Expected results:

  • should return null

Actual results:

  • never returns
code sample
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

void main() {
  runApp(const PickerFilesProvider(child: MaterialApp(home: MyHomePage())));
}

Future<Iterable<XFile>> pickFiles() async {
  try {
    final maybeFiles = await ImagePicker().pickMultiImage();
    return [if (maybeFiles != null) ...maybeFiles];
  } on Exception catch (e, s) {
    debugPrint('$e, $s');
    return [];
  } on Error catch (e) {
    debugPrint('$e, ${e.stackTrace}');
    return [];
  }
}

extension XfilesNamesX on Iterable<XFile> {
  Iterable<String> get names sync* {
    for (final file in this) {
      yield file.name;
    }
  }
}

class PickerFilesProvider extends StatefulWidget {
  final Widget child;
  const PickerFilesProvider({
    required this.child,
  }) : super(key: const ValueKey('PickerFilesProvider'));

  @override
  State<PickerFilesProvider> createState() => _PickerFilesProviderState();
}

class _PickerFilesProviderState extends State<PickerFilesProvider> {
  late final ValueNotifier<Iterable<String>> _notifier;

  @override
  void initState() {
    super.initState();
    _notifier = ValueNotifier(<String>[]);
  }

  @override
  void dispose() {
    _notifier.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return _PickedFiles(
      child: widget.child,
      notifier: _notifier,
    );
  }
}

class _PickedFiles extends InheritedWidget {
  final ValueNotifier<Iterable<String>> notifier;
  const _PickedFiles({
    required this.notifier,
    required Widget child,
  }) : super(key: const ValueKey('PickedFiles'), child: child);

  static _PickedFiles of(BuildContext context) {
    final _PickedFiles? result =
        context.dependOnInheritedWidgetOfExactType<_PickedFiles>();
    assert(result != null, 'No PickedFiles found in context');
    return result!;
  }

  @override
  // ignore: avoid_renaming_method_parameters
  bool updateShouldNotify(_) => false;
}

extension PickedFilesX on BuildContext {
  ValueNotifier<Iterable<String>> get pickerfiles =>
      _PickedFiles.of(this).notifier;
}

class PickerButton extends StatefulWidget {
  const PickerButton({
    final key = const ValueKey('PickerButton'),
  }) : super(key: key);

  @override
  State<PickerButton> createState() => _PickerWidgetState();
}

class _PickerWidgetState extends State<PickerButton> {
  late final ValueNotifier<bool> _busy;

  @override
  void initState() {
    super.initState();
    _busy = ValueNotifier(false);
  }

  @override
  void dispose() {
    _busy.dispose();
    super.dispose();
  }

  void _pickFiles() async {
    _busy.value = true;
    context.pickerfiles.value = (await pickFiles()).names;
    _busy.value = false;
  }

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      child: ValueListenableBuilder<bool>(
          valueListenable: _busy,
          builder: (context, busy, _) => busy
              ? const CircularProgressIndicator(color: Colors.black)
              : const Icon(Icons.upload)),
      onPressed: _pickFiles,
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({
    final key = const ValueKey('MyHomePage'),
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: PickedFilesListView(),
      floatingActionButton: PickerButton(),
    );
  }
}

class PickedFilesListView extends StatelessWidget {
  const PickedFilesListView({
    final key = const ValueKey('PickedFilesListView'),
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<Iterable<String>>(
      valueListenable: context.pickerfiles,
      builder: (context, names, _) => ListView(children: [
        for (final name in names) Center(child: Text(name)),
      ]),
    );
  }
}
pubspec
environment:
  sdk: '>=2.14.3 <3.0.0'
  flutter: ^2.5.2

dependencies:
  flutter:
    sdk: flutter
  image_picker: ^0.8.4

dev_dependencies:
  flutter_lints: ^1.0.4

flutter:
  uses-material-design: true
doctor
[✓] Flutter (Channel stable, 2.5.3, on macOS 11.6 20G165 darwin-x64, locale en-EE)
    • Flutter version 2.5.3 at /Users/francesco/fvm/versions/stable
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 18116933e7 (5 days ago), 2021-10-15 10:46:35 -0700
    • Engine revision d3ea636dc5
    • Dart version 2.14.4

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Users/francesco/Library/Android/sdk
    • Platform android-30, build-tools 30.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 13.0, Build version 13A233
    • CocoaPods version 1.11.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2020.3)
    • 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.10+0-b96-7281165)

[✓] VS Code (version 1.61.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.27.0

[✓] Connected device (3 available)
    • Pixel 3a (mobile) • 965AY0WP5C • android-arm64  • Android 11 (API 30)
    • macOS (desktop)   • macos      • darwin-x64     • macOS 11.6 20G165 darwin-x64
    • Chrome (web)      • chrome     • web-javascript • Google Chrome 94.0.4606.81

• No issues found!

Activity

  1. darshankawar commented on Oct 21, 2021

    @darshankawar
    Member

    Thanks for the report. Verified this on latest stable and master and see the same behavior, ie, after canceling the window, FAB shows loading indicator and doesn't throw any log in the console:

    Screenshot 2021-10-21 at 1 20 25 PM

    On mobile, carrying out same steps throws flutter: PlatformException(photo_access_denied, The user did not allow photo access., null, null), error as expected.

    stable, master flutter doctor -v
    [✓] Flutter (Channel stable, 2.5.3, on Mac OS X 10.15.4 19E2269 darwin-x64,
        locale en-GB)
        • Flutter version 2.5.3 at /Users/dhs/documents/fluttersdk/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 18116933e7 (2 days ago), 2021-10-15 10:46:35 -0700
        • Engine revision d3ea636dc5
        • Dart version 2.14.4
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 30)
        • Android SDK at /Users/dhs/Library/Android/sdk
        • Platform android-30, build-tools 30.0.3
        • ANDROID_HOME = /Users/dhs/Library/Android/sdk
        • Java binary at: /Users/dhs/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/202.7486908/Android
          Studio.app/Contents/jre/jdk/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
        • All Android licenses accepted.    
    
    [✓] Xcode - develop for iOS and macOS
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Xcode 12.3, Build version 12C33
        • CocoaPods version 1.10.1
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 4.1)
        • Android Studio at /Users/dhs/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/202.7486908/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
          1.8.0_242-release-1644-b3-6915495)        
    
    [✓] VS Code (version 1.57.1)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.21.0
    
    [✓] Connected device (4 available)
        • Darshan's iphone (mobile)  • 21150b119064aecc249dfcfe05e259197461ce23 •
          ios            • iOS 14.4.1 18D61
        • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729     •
          ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
        • macOS (desktop)            • macos                                    •
          darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
        • Chrome (web)               • chrome                                   •
          web-javascript • Google Chrome 93.0.4577.82
    
    
    • No issues found!
    
    [✓] Flutter (Channel master, 2.6.0-12.0.pre.433, on Mac OS X 10.15.4 19E2269
        darwin-x64, locale en-GB)
        • Flutter version 2.6.0-12.0.pre.433 at
          /Users/dhs/documents/fluttersdk/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision be2abc796a (2 hours ago), 2021-10-20 22:53:02 -0400
        • Engine revision 1c173ca64d
        • Dart version 2.15.0 (build 2.15.0-233.0.dev)
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 30)
        • Android SDK at /Users/dhs/Library/Android/sdk
        • Platform android-30, build-tools 30.0.3
        • ANDROID_HOME = /Users/dhs/Library/Android/sdk
        • Java binary at: /Users/dhs/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/202.7486908/Android
          Studio.app/Contents/jre/jdk/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
        • All Android licenses accepted.    
    
    [✓] Xcode - develop for iOS and macOS
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Xcode 12.5.1, Build version 12E507
        • CocoaPods version 1.10.1
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 4.1)
        • Android Studio at /Users/dhs/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/202.7486908/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
          1.8.0_242-release-1644-b3-6915495)        
    
    [✓] VS Code (version 1.57.1)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.21.0
    
    [[✓] Connected device (4 available)
        • Darshan's iphone (mobile)  • 21150b119064aecc249dfcfe05e259197461ce23 •
          ios            • iOS 14.4.1 18D61
        • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729     •
          ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
        • macOS (desktop)            • macos                                    •
          darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
        • Chrome (web)               • chrome                                   •
          web-javascript • Google Chrome 93.0.4577.82
    
    
    • No issues found!
    
    
    
    
    
  2. darshankawar commented on Oct 21, 2021

    @darshankawar
    Member
  3. added
    P2Important issues not at the top of the work list
    on Oct 21, 2021
  4. ditman commented on Oct 21, 2021

    @ditman
    Member

    This is, unfortunately, a limitation of web browsers; they don't fire the "cancel" event (or anything useful) when the user aborts selecting a file.

    (I'm trying to hack something together with "focus", but I'll need to give it a test in Flutter, since focus there is handled differently.)

  5. 25 remaining items

  6. ditman commented on Jul 13, 2023

    @ditman
    Member

    A fix for this is coming:

    (The same fix for file_selector has already landed here: flutter/packages#3683)

  7. added
    r: fixedIssue is closed as already fixed in a newer version
    on Aug 7, 2023
  8. github-actions commented on Aug 21, 2023

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  9. locked as resolved and limited conversation to collaborators on Aug 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listfound in release: 3.10Found to occur in 3.10found in release: 3.11Found to occur in 3.11has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: image_pickerThe Image Picker plugin.packageflutter/packages repository. See also p: labels.platform-webWeb applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-webOwned by Web platform teamtriaged-webTriaged by Web platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions