Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 2.7.0

* Adds `canCreateDirectories` parameter to `FileDialogOptions` to control whether directory creation is enabled during path selection.
* Updates minimum supported SDK version to Flutter 3.29/Dart 3.7.

## 2.6.2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,25 +96,50 @@ abstract class FileSelectorPlatform extends PlatformInterface {
/// Opens a file dialog for loading directories and returns a directory path.
///
/// Returns `null` if the user cancels the operation.
// TODO(stuartmorgan): Switch to FileDialogOptions if we ever need to
// duplicate this to add a parameter.
@Deprecated('Use getDirectoryPathWithOptions instead')
Future<String?> getDirectoryPath({
String? initialDirectory,
String? confirmButtonText,
}) {
throw UnimplementedError('getDirectoryPath() has not been implemented.');
}

/// Opens a file dialog for loading directories and returns a directory path.
///
/// The `options` argument controls additional settings that can be passed to
/// file dialog. See [FileDialogOptions] for more details.
///
/// Returns `null` if the user cancels the operation.
Future<String?> getDirectoryPathWithOptions(FileDialogOptions options) {
return getDirectoryPath(
initialDirectory: options.initialDirectory,
confirmButtonText: options.confirmButtonText,
);
}

/// Opens a file dialog for loading directories and returns multiple directory
/// paths.
///
/// Returns an empty list if the user cancels the operation.
// TODO(stuartmorgan): Switch to FileDialogOptions if we ever need to
// duplicate this to add a parameter.
@Deprecated('Use getDirectoryPathsWithOptions instead')
Future<List<String>> getDirectoryPaths({
String? initialDirectory,
String? confirmButtonText,
}) {
throw UnimplementedError('getDirectoryPaths() has not been implemented.');
}

/// Opens a file dialog for loading directories and returns multiple directory
/// paths.
///
/// The `options` argument controls additional settings that can be passed to
/// the file dialog. See [FileDialogOptions] for more details.
///
/// Returns an empty list if the user cancels the operation.
Future<List<String>> getDirectoryPathsWithOptions(FileDialogOptions options) {
return getDirectoryPaths(
initialDirectory: options.initialDirectory,
confirmButtonText: options.confirmButtonText,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@ import 'package:flutter/foundation.dart' show immutable;
@immutable
class FileDialogOptions {
/// Creates a new options set with the given settings.
const FileDialogOptions({this.initialDirectory, this.confirmButtonText});
const FileDialogOptions({
this.initialDirectory,
this.confirmButtonText,
this.canCreateDirectories,
});

/// The initial directory the dialog should open with.
final String? initialDirectory;

/// The label for the button that confirms selection.
final String? confirmButtonText;

/// Whether the user is allowed to create new directories in the dialog.
///
/// If null, the platform will decide the default value.
///
/// May not be supported on all platforms.
final bool? canCreateDirectories;
}

/// Configuration options for a save dialog.
Expand All @@ -24,6 +35,7 @@ class SaveDialogOptions extends FileDialogOptions {
const SaveDialogOptions({
super.initialDirectory,
super.confirmButtonText,
super.canCreateDirectories,
this.suggestedName,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/file_selector
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 2.6.2
version: 2.7.0

environment:
sdk: ^3.7.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@ void main() {
});
});

group('getDirectoryPath', () {
test('Should throw unimplemented exception', () async {
final FileSelectorPlatform fileSelector = ExtendsFileSelectorPlatform();

await expectLater(() async {
return fileSelector.getDirectoryPath();
}, throwsA(isA<UnimplementedError>()));
});
});

group('getDirectoryPathWithOptions', () {
test('Should fall back to getDirectoryPath by default', () async {
final FileSelectorPlatform fileSelector =
OldFileSelectorPlatformImplementation();

final String? result = await fileSelector.getDirectoryPathWithOptions(
const FileDialogOptions(),
);

// Should call the old method and return its result
expect(result, OldFileSelectorPlatformImplementation.directoryPath);
});
});

group('getDirectoryPaths', () {
test('Should throw unimplemented exception', () async {
final FileSelectorPlatform fileSelector = ExtendsFileSelectorPlatform();
Expand All @@ -30,6 +54,21 @@ void main() {
});
});

group('getDirectoryPathsWithOptions', () {
test('Should fall back to getDirectoryPaths by default', () async {
final FileSelectorPlatform fileSelector =
OldFileSelectorPlatformImplementation();

final List<String> result = await fileSelector
.getDirectoryPathsWithOptions(const FileDialogOptions());

// Should call the old method and return its result
expect(result, <String>[
OldFileSelectorPlatformImplementation.directoryPath,
]);
});
});

test('getSaveLocation falls back to getSavePath by default', () async {
final FileSelectorPlatform fileSelector =
OldFileSelectorPlatformImplementation();
Expand All @@ -45,7 +84,8 @@ class ExtendsFileSelectorPlatform extends FileSelectorPlatform {}

class OldFileSelectorPlatformImplementation extends FileSelectorPlatform {
static const String savePath = '/a/path';
// Only implement the deprecated getSavePath.
static const String directoryPath = '/a/directory';

@override
Future<String?> getSavePath({
List<XTypeGroup>? acceptedTypeGroups,
Expand All @@ -55,4 +95,20 @@ class OldFileSelectorPlatformImplementation extends FileSelectorPlatform {
}) async {
return savePath;
}

@override
Future<String?> getDirectoryPath({
String? initialDirectory,
String? confirmButtonText,
}) async {
return directoryPath;
}

@override
Future<List<String>> getDirectoryPaths({
String? initialDirectory,
String? confirmButtonText,
}) async {
return <String>[directoryPath];
}
}