Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[file_selector] Add getDirectoryPaths method to the file_selector #6576

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/file_selector/file_selector/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## 0.9.2+2

* Adds `getDirectoryPaths` method.

## 0.9.2+1

* Improves API docs and examples.
* Changes XTypeGroup initialization from final to const.
* Updates minimum Flutter version to 2.10.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

/// Screen that allows the user to select one or more directories using `getDirectoryPaths`,
/// then displays the selected directories in a dialog.
class GetMultipleDirectoriesPage extends StatelessWidget {
/// Default Constructor
const GetMultipleDirectoriesPage({Key? key}) : super(key: key);

Future<void> _getDirectoryPaths(BuildContext context) async {
const String confirmButtonText = 'Choose';
final List<String?>? directoryPaths = await getDirectoryPaths(
confirmButtonText: confirmButtonText,
);
if (directoryPaths == null) {
// Operation was canceled by the user.
return;
}
String paths = '';
for (final String? path in directoryPaths) {
paths += '${path!} \n';
}
await showDialog<void>(
context: context,
builder: (BuildContext context) => TextDisplay(paths),
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Select multiple directories'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
style: ElevatedButton.styleFrom(
// TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724
// ignore: deprecated_member_use
primary: Colors.blue,
// ignore: deprecated_member_use
onPrimary: Colors.white,
),
child: const Text(
'Press to ask user to choose multiple directories'),
onPressed: () => _getDirectoryPaths(context),
),
],
),
),
);
}
}

/// Widget that displays a text file in a dialog.
class TextDisplay extends StatelessWidget {
/// Creates a `TextDisplay`.
const TextDisplay(this.directoriesPaths, {Key? key}) : super(key: key);

/// The path selected in the dialog.
final String directoriesPaths;

@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('Selected Directories'),
content: Scrollbar(
child: SingleChildScrollView(
child: Text(directoriesPaths),
),
),
actions: <Widget>[
TextButton(
child: const Text('Close'),
onPressed: () => Navigator.pop(context),
),
],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ class HomePage extends StatelessWidget {
child: const Text('Open a get directory dialog'),
onPressed: () => Navigator.pushNamed(context, '/directory'),
),
const SizedBox(height: 10),
ElevatedButton(
style: style,
child: const Text('Open a get multi directories dialog'),
onPressed: () =>
Navigator.pushNamed(context, '/multi-directories'),
),
],
),
),
Expand Down
3 changes: 3 additions & 0 deletions packages/file_selector/file_selector/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'package:flutter/material.dart';

import 'get_directory_page.dart';
import 'get_multiple_directories_page.dart';
import 'home_page.dart';
import 'open_image_page.dart';
import 'open_multiple_images_page.dart';
Expand Down Expand Up @@ -36,6 +37,8 @@ class MyApp extends StatelessWidget {
'/open/text': (BuildContext context) => const OpenTextPage(),
'/save/text': (BuildContext context) => SaveTextPage(),
'/directory': (BuildContext context) => GetDirectoryPage(),
'/multi-directories': (BuildContext context) =>
const GetMultipleDirectoriesPage()
},
);
}
Expand Down
19 changes: 19 additions & 0 deletions packages/file_selector/file_selector/lib/file_selector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,22 @@ Future<String?> getDirectoryPath({
return FileSelectorPlatform.instance.getDirectoryPath(
initialDirectory: initialDirectory, confirmButtonText: confirmButtonText);
}

/// Opens a directory selection dialog and returns a list of the paths chosen by the user.
/// This always returns `null` on the web.
///
/// [initialDirectory] is the full path to the directory that will be displayed
/// when the dialog is opened. When not provided, the platform will pick an
/// initial location.
///
/// [confirmButtonText] is the text in the confirmation button of the dialog.
/// When not provided, the default OS label is used (for example, "Open").
///
/// Returns `null` if the user cancels the operation.
Future<List<String?>?> getDirectoryPaths({
String? initialDirectory,
String? confirmButtonText,
}) async {
return FileSelectorPlatform.instance.getDirectoryPaths(
initialDirectory: initialDirectory, confirmButtonText: confirmButtonText);
}
21 changes: 15 additions & 6 deletions packages/file_selector/file_selector/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ description: Flutter plugin for opening and saving files, or selecting
repository: https://github.com/flutter/plugins/tree/main/packages/file_selector/file_selector
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
version: 0.9.2+2
# TODO(eugerossetto): This should be reverted once file_selector_platform_interface 2.3.0 is published.
publish_to: 'none'

environment:
sdk: ">=2.12.0 <3.0.0"
Expand All @@ -23,13 +25,20 @@ flutter:
windows:
default_package: file_selector_windows

# TODO(eugerossetto): This should be reverted once file_selector_platform_interface 2.3.0 is published.
dependencies:
file_selector_ios: ^0.5.0
file_selector_linux: ^0.9.0
file_selector_macos: ^0.9.0
file_selector_platform_interface: ^2.2.0
file_selector_web: ^0.9.0
file_selector_windows: ^0.9.0
file_selector_ios:
path: ../file_selector_ios
file_selector_linux:
path: ../file_selector_linux
file_selector_macos:
path: ../file_selector_macos
file_selector_platform_interface:
path: ../file_selector_platform_interface
file_selector_web:
path: ../file_selector_web
file_selector_windows:
path: ../file_selector_windows
flutter:
sdk: flutter

Expand Down
65 changes: 65 additions & 0 deletions packages/file_selector/file_selector/test/file_selector_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,55 @@ void main() {
expect(directoryPath, expectedDirectoryPath);
});
});

group('getDirectoryPaths', () {
const List<String> expectedDirectoryPaths = <String>[
'/example/path',
'/example/2/path'
];

test('works', () async {
fakePlatformImplementation
..setExpectations(
initialDirectory: initialDirectory,
confirmButtonText: confirmButtonText)
..setPathsResponse(expectedDirectoryPaths);

final List<String?>? directoryPaths = await getDirectoryPaths(
initialDirectory: initialDirectory,
confirmButtonText: confirmButtonText,
);

expect(directoryPaths, expectedDirectoryPaths);
});

test('works with no arguments', () async {
fakePlatformImplementation.setPathsResponse(expectedDirectoryPaths);

final List<String?>? directoryPaths = await getDirectoryPaths();
expect(directoryPaths, expectedDirectoryPaths);
});

test('sets the initial directory', () async {
fakePlatformImplementation
..setExpectations(initialDirectory: initialDirectory)
..setPathsResponse(expectedDirectoryPaths);

final List<String?>? directoryPaths =
await getDirectoryPaths(initialDirectory: initialDirectory);
expect(directoryPaths, expectedDirectoryPaths);
});

test('sets the button confirmation label', () async {
fakePlatformImplementation
..setExpectations(confirmButtonText: confirmButtonText)
..setPathsResponse(expectedDirectoryPaths);

final List<String?>? directoryPaths =
await getDirectoryPaths(confirmButtonText: confirmButtonText);
expect(directoryPaths, expectedDirectoryPaths);
});
});
}

class FakeFileSelector extends Fake
Expand All @@ -271,6 +320,7 @@ class FakeFileSelector extends Fake
// Return values.
List<XFile>? files;
String? path;
List<String>? paths;

void setExpectations({
List<XTypeGroup> acceptedTypeGroups = const <XTypeGroup>[],
Expand All @@ -294,6 +344,11 @@ class FakeFileSelector extends Fake
this.path = path;
}

// ignore: use_setters_to_change_properties
void setPathsResponse(List<String> paths) {
this.paths = paths;
}

@override
Future<XFile?> openFile({
List<XTypeGroup>? acceptedTypeGroups,
Expand Down Expand Up @@ -341,4 +396,14 @@ class FakeFileSelector extends Fake
expect(confirmButtonText, this.confirmButtonText);
return path;
}

@override
Future<List<String>?> getDirectoryPaths({
String? initialDirectory,
String? confirmButtonText,
}) async {
expect(initialDirectory, this.initialDirectory);
expect(confirmButtonText, this.confirmButtonText);
return paths;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ dependencies:
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ..
file_selector_platform_interface: ^2.2.0
# TODO(eugerossetto): This should be 2.4.0 once it is published.
file_selector_platform_interface:
path: ../../file_selector_platform_interface
flutter:
sdk: flutter

Expand Down
8 changes: 6 additions & 2 deletions packages/file_selector/file_selector_ios/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ description: iOS implementation of the file_selector plugin.
repository: https://github.com/flutter/plugins/tree/main/packages/file_selector/file_selector_ios
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
version: 0.5.0+2
# TODO(eugerossetto): remove this once file_selector_platform_interface version is updated to 2.4.0
publish_to: 'none'

environment:
sdk: ">=2.14.4 <3.0.0"
Expand All @@ -17,7 +19,9 @@ flutter:
pluginClass: FFSFileSelectorPlugin

dependencies:
file_selector_platform_interface: ^2.2.0
# TODO(eugerossetto): This should be 2.4.0 once it is published.
file_selector_platform_interface:
path: ../file_selector_platform_interface
flutter:
sdk: flutter

Expand All @@ -27,4 +31,4 @@ dev_dependencies:
sdk: flutter
mockito: ^5.1.0
pigeon: ^3.2.5

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ environment:
dependencies:
file_selector_linux:
path: ../
file_selector_platform_interface: ^2.2.0
# TODO(eugerossetto): This should be 2.4.0 once it is published.
file_selector_platform_interface:
path: ../../file_selector_platform_interface
flutter:
sdk: flutter

Expand Down
6 changes: 5 additions & 1 deletion packages/file_selector/file_selector_linux/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ description: Liunx implementation of the file_selector plugin.
repository: https://github.com/flutter/plugins/tree/main/packages/file_selector/file_selector_linux
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
version: 0.9.0+1
# TODO(eugerossetto): remove this once file_selector_platform_interface version is updated to 2.4.0
publish_to: 'none'

environment:
sdk: ">=2.12.0 <3.0.0"
Expand All @@ -18,7 +20,9 @@ flutter:

dependencies:
cross_file: ^0.3.1
file_selector_platform_interface: ^2.2.0
# TODO(eugerossetto): This should be 2.4.0 once it is published.
file_selector_platform_interface:
path: ../file_selector_platform_interface
flutter:
sdk: flutter

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ dependencies:
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ..
file_selector_platform_interface: ^2.2.0
# TODO(eugerossetto): This should be 2.4.0 once it is published.
file_selector_platform_interface:
path: ../../file_selector_platform_interface
flutter:
sdk: flutter

Expand Down
6 changes: 5 additions & 1 deletion packages/file_selector/file_selector_macos/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ description: macOS implementation of the file_selector plugin.
repository: https://github.com/flutter/plugins/tree/main/packages/file_selector/file_selector_macos
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
version: 0.9.0+3
# TODO(eugerossetto): remove this once file_selector_platform_interface version is updated to 2.4.0
publish_to: 'none'

environment:
sdk: ">=2.12.0 <3.0.0"
Expand All @@ -18,7 +20,9 @@ flutter:

dependencies:
cross_file: ^0.3.1
file_selector_platform_interface: ^2.2.0
# TODO(eugerossetto): This should be 2.4.0 once it is published.
file_selector_platform_interface:
path: ../file_selector_platform_interface
flutter:
sdk: flutter

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.4.0

* Adds `getDirectoryPaths` method to the interface.

## 2.3.0

* Replaces `macUTIs` with `uniformTypeIdentifiers`. `macUTIs` is available as an alias, but will be deprecated in a future release.
Expand Down
Loading