@@ -315,6 +315,41 @@ abstract class _AttachUploadsButton extends StatelessWidget {
315
315
}
316
316
}
317
317
318
+ Future <Iterable <_File >?> _getFilePickerFiles (BuildContext context) async {
319
+ FilePickerResult ? result;
320
+ try {
321
+ result = await FilePicker .platform.pickFiles (allowMultiple: true , withReadStream: true );
322
+ } catch (e) {
323
+ if (e is PlatformException && e.code == 'read_external_storage_denied' ) {
324
+ // Observed on Android. If Android's error message tells us whether the
325
+ // user has checked "Don't ask again", it seems the library doesn't pass
326
+ // that on to us. So just always prompt to check permissions in settings.
327
+ // If the user hasn't checked "Don't ask again", they can always dismiss
328
+ // our prompt and retry, and the permissions request will reappear,
329
+ // letting them grant permissions and complete the upload.
330
+ showSuggestedActionDialog (context: context, // TODO(i18n)
331
+ title: 'Permissions needed' ,
332
+ message: 'To upload an image, please grant Zulip additional permissions in Settings.' ,
333
+ actionButtonText: 'Open settings' ,
334
+ onActionButtonPress: () {
335
+ AppSettings .openAppSettings ();
336
+ });
337
+ } else {
338
+ // TODO(i18n)
339
+ showErrorDialog (context: context, title: 'Error' , message: e.toString ());
340
+ }
341
+ return null ;
342
+ }
343
+ if (result == null ) {
344
+ return null ; // User cancelled; do nothing
345
+ }
346
+
347
+ return result.files.map ((f) {
348
+ assert (f.readStream != null ); // We passed `withReadStream: true` to pickFiles.
349
+ return _File (content: f.readStream! , length: f.size, filename: f.name);
350
+ });
351
+ }
352
+
318
353
class _AttachFileButton extends _AttachUploadsButton {
319
354
const _AttachFileButton ({required super .contentController, required super .contentFocusNode});
320
355
@@ -323,38 +358,21 @@ class _AttachFileButton extends _AttachUploadsButton {
323
358
324
359
@override
325
360
Future <Iterable <_File >?> getFiles (BuildContext context) async {
326
- FilePickerResult ? result;
327
- try {
328
- result = await FilePicker .platform.pickFiles (allowMultiple: true , withReadStream: true );
329
- } catch (e) {
330
- if (e is PlatformException && e.code == 'read_external_storage_denied' ) {
331
- // Observed on Android. If Android's error message tells us whether the
332
- // user has checked "Don't ask again", it seems the library doesn't pass
333
- // that on to us. So just always prompt to check permissions in settings.
334
- // If the user hasn't checked "Don't ask again", they can always dismiss
335
- // our prompt and retry, and the permissions request will reappear,
336
- // letting them grant permissions and complete the upload.
337
- showSuggestedActionDialog (context: context, // TODO(i18n)
338
- title: 'Permissions needed' ,
339
- message: 'To upload an image, please grant Zulip additional permissions in Settings.' ,
340
- actionButtonText: 'Open settings' ,
341
- onActionButtonPress: () {
342
- AppSettings .openAppSettings ();
343
- });
344
- } else {
345
- // TODO(i18n)
346
- showErrorDialog (context: context, title: 'Error' , message: e.toString ());
347
- }
348
- return null ;
349
- }
350
- if (result == null ) {
351
- return null ; // User cancelled; do nothing
352
- }
361
+ return _getFilePickerFiles (context);
362
+ }
363
+ }
353
364
354
- return result.files.map ((f) {
355
- assert (f.readStream != null ); // We passed `withReadStream: true` to pickFiles.
356
- return _File (content: f.readStream! , length: f.size, filename: f.name);
357
- });
365
+ class _AttachMediaButton extends _AttachUploadsButton {
366
+ const _AttachMediaButton ({required super .contentController, required super .contentFocusNode});
367
+
368
+ @override
369
+ IconData get icon => Icons .image;
370
+
371
+ @override
372
+ Future <Iterable <_File >?> getFiles (BuildContext context) async {
373
+ // TODO: This doesn't give quite the right UI on Android.
374
+ // Perhaps try `image_picker`: https://github.com/zulip/zulip-flutter/issues/56#issuecomment-1514001281
375
+ return _getFilePickerFiles (context);
358
376
}
359
377
}
360
378
@@ -556,6 +574,7 @@ class _StreamComposeBoxState extends State<StreamComposeBox> {
556
574
child: Row (
557
575
children: [
558
576
_AttachFileButton (contentController: _contentController, contentFocusNode: _contentFocusNode),
577
+ _AttachMediaButton (contentController: _contentController, contentFocusNode: _contentFocusNode),
559
578
])),
560
579
]))));
561
580
}
0 commit comments