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

Commit c48a6c6

Browse files
committed
Add get multiple directories functionality in macOS
1 parent 53dbc93 commit c48a6c6

File tree

9 files changed

+176
-5
lines changed

9 files changed

+176
-5
lines changed

packages/file_selector/file_selector_macos/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.9.0+4
2+
3+
* Adds `getDirectoryPaths` implementation.
4+
15
## 0.9.0+3
26

37
* Changes XTypeGroup initialization from final to const.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
6+
import 'package:flutter/material.dart';
7+
8+
/// Screen that allows the user to select one or more directories using `getDirectoryPaths`,
9+
/// then displays the selected directories in a dialog.
10+
class GetMultipleDirectoriesPage extends StatelessWidget {
11+
/// Default Constructor
12+
const GetMultipleDirectoriesPage({Key? key}) : super(key: key);
13+
14+
Future<void> _getDirectoryPaths(BuildContext context) async {
15+
const String confirmButtonText = 'Choose';
16+
final List<String> directoriesPaths =
17+
await FileSelectorPlatform.instance.getDirectoryPaths(
18+
confirmButtonText: confirmButtonText,
19+
);
20+
if (directoriesPaths == null) {
21+
// Operation was canceled by the user.
22+
return;
23+
}
24+
String paths = '';
25+
for (final String? path in directoriesPaths) {
26+
paths += '${path!} \n';
27+
}
28+
await showDialog<void>(
29+
context: context,
30+
builder: (BuildContext context) => TextDisplay(paths),
31+
);
32+
}
33+
34+
@override
35+
Widget build(BuildContext context) {
36+
return Scaffold(
37+
appBar: AppBar(
38+
title: const Text('Select multiple directories'),
39+
),
40+
body: Center(
41+
child: Column(
42+
mainAxisAlignment: MainAxisAlignment.center,
43+
children: <Widget>[
44+
ElevatedButton(
45+
style: ElevatedButton.styleFrom(
46+
// TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724
47+
// ignore: deprecated_member_use
48+
primary: Colors.blue,
49+
// ignore: deprecated_member_use
50+
onPrimary: Colors.white,
51+
),
52+
child: const Text(
53+
'Press to ask user to choose multiple directories'),
54+
onPressed: () => _getDirectoryPaths(context),
55+
),
56+
],
57+
),
58+
),
59+
);
60+
}
61+
}
62+
63+
/// Widget that displays a text file in a dialog.
64+
class TextDisplay extends StatelessWidget {
65+
/// Creates a `TextDisplay`.
66+
const TextDisplay(this.directoryPath, {Key? key}) : super(key: key);
67+
68+
/// The path selected in the dialog.
69+
final String directoryPath;
70+
71+
@override
72+
Widget build(BuildContext context) {
73+
return AlertDialog(
74+
title: const Text('Selected Directories'),
75+
content: Scrollbar(
76+
child: SingleChildScrollView(
77+
child: Text(directoryPath),
78+
),
79+
),
80+
actions: <Widget>[
81+
TextButton(
82+
child: const Text('Close'),
83+
onPressed: () => Navigator.pop(context),
84+
),
85+
],
86+
);
87+
}
88+
}

packages/file_selector/file_selector_macos/example/lib/home_page.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ class HomePage extends StatelessWidget {
5555
child: const Text('Open a get directory dialog'),
5656
onPressed: () => Navigator.pushNamed(context, '/directory'),
5757
),
58+
const SizedBox(height: 10),
59+
ElevatedButton(
60+
style: style,
61+
child: const Text('Open a get multi directories dialog'),
62+
onPressed: () =>
63+
Navigator.pushNamed(context, '/multi-directories'),
64+
),
5865
],
5966
),
6067
),

packages/file_selector/file_selector_macos/example/lib/main.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'package:flutter/material.dart';
66

77
import 'get_directory_page.dart';
8+
import 'get_multiple_directories_page.dart';
89
import 'home_page.dart';
910
import 'open_image_page.dart';
1011
import 'open_multiple_images_page.dart';
@@ -36,6 +37,8 @@ class MyApp extends StatelessWidget {
3637
'/open/text': (BuildContext context) => const OpenTextPage(),
3738
'/save/text': (BuildContext context) => SaveTextPage(),
3839
'/directory': (BuildContext context) => const GetDirectoryPage(),
40+
'/multi-directories': (BuildContext context) =>
41+
const GetMultipleDirectoriesPage(),
3942
},
4043
);
4144
}

packages/file_selector/file_selector_macos/example/pubspec.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ dependencies:
1515
# The example app is bundled with the plugin so we use a path dependency on
1616
# the parent directory to use the current plugin's version.
1717
path: ..
18-
file_selector_platform_interface: ^2.2.0
18+
# TODO(VanesaOshiro): This should be 2.3.0 once it is published.
19+
file_selector_platform_interface:
20+
path: ../../file_selector_platform_interface/
1921
flutter:
2022
sdk: flutter
2123

packages/file_selector/file_selector_macos/lib/file_selector_macos.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ class FileSelectorMacOS extends FileSelectorPlatform {
8888
);
8989
}
9090

91+
@override
92+
Future<List<String>> getDirectoryPaths({
93+
String? initialDirectory,
94+
String? confirmButtonText,
95+
}) async {
96+
final List<String>? pathList = await _channel
97+
.invokeListMethod<String>(
98+
'getDirectoryPath',
99+
<String, dynamic>{
100+
'initialDirectory': initialDirectory,
101+
'confirmButtonText': confirmButtonText,
102+
'multiple': true,
103+
},
104+
);
105+
return pathList ?? <String>[];
106+
}
107+
91108
// Converts the type group list into a flat list of all allowed types, since
92109
// macOS doesn't support filter groups.
93110
Map<String, List<String>>? _allowedTypeListFromTypeGroups(

packages/file_selector/file_selector_macos/macos/Classes/FileSelectorPlugin.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ public class FileSelectorPlugin: NSObject, FlutterPlugin {
7171
let choosingDirectory = call.method == openDirectoryMethod
7272
let panel = NSOpenPanel()
7373
configure(panel: panel, with: arguments)
74-
configure(openPanel: panel, with: arguments, choosingDirectory: choosingDirectory)
74+
if (choosingDirectory) { configure(openPanel: panel, with: arguments, choosingDirectory: choosingDirectory) }
7575
panelController.display(panel, for: viewProvider.view?.window) { (selection: [URL]?) in
76-
if (choosingDirectory) {
76+
if (choosingDirectory && panel.allowsMultipleSelection == false) {
7777
result(selection?.first?.path)
7878
} else {
7979
result(selection?.map({ item in item.path }))

packages/file_selector/file_selector_macos/pubspec.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: file_selector_macos
22
description: macOS implementation of the file_selector plugin.
33
repository: https://github.com/flutter/plugins/tree/main/packages/file_selector/file_selector_macos
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
5-
version: 0.9.0+3
5+
version: 0.9.0+4
66

77
environment:
88
sdk: ">=2.12.0 <3.0.0"
@@ -18,7 +18,9 @@ flutter:
1818

1919
dependencies:
2020
cross_file: ^0.3.1
21-
file_selector_platform_interface: ^2.2.0
21+
# TODO(VanesaOshiro): This should be 2.3.0 once it is published.
22+
file_selector_platform_interface:
23+
path: ../file_selector_platform_interface
2224
flutter:
2325
sdk: flutter
2426

packages/file_selector/file_selector_macos/test/file_selector_macos_test.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,4 +355,52 @@ void main() {
355355
],
356356
);
357357
});
358+
359+
group('getDirectoryPaths', () {
360+
test('passes initialDirectory correctly', () async {
361+
await plugin.getDirectoryPaths(initialDirectory: '/example/directory');
362+
363+
expect(
364+
log,
365+
<Matcher>[
366+
isMethodCall('getDirectoryPath', arguments: <String, dynamic>{
367+
'initialDirectory': '/example/directory',
368+
'confirmButtonText': null,
369+
'multiple': true
370+
}),
371+
],
372+
);
373+
});
374+
375+
test('passes confirmButtonText correctly', () async {
376+
await plugin.getDirectoryPaths(confirmButtonText: 'Open Directories');
377+
378+
expect(
379+
log,
380+
<Matcher>[
381+
isMethodCall('getDirectoryPath', arguments: <String, dynamic>{
382+
'initialDirectory': null,
383+
'confirmButtonText': 'Open Directories',
384+
'multiple': true
385+
}),
386+
],
387+
);
388+
});
389+
390+
test('receives argument multiple as true even if the others are null',
391+
() async {
392+
await plugin.getDirectoryPaths();
393+
394+
expect(
395+
log,
396+
<Matcher>[
397+
isMethodCall('getDirectoryPath', arguments: <String, dynamic>{
398+
'initialDirectory': null,
399+
'confirmButtonText': null,
400+
'multiple': true
401+
}),
402+
],
403+
);
404+
});
405+
});
358406
}

0 commit comments

Comments
 (0)