Skip to content

Commit 65abfb4

Browse files
chrisbobbegnprice
authored andcommitted
binding: Add pickImage, wrapping image_picker.pickImage
1 parent 0fa5453 commit 65abfb4

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

lib/model/binding.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:firebase_core/firebase_core.dart' as firebase_core;
44
import 'package:firebase_messaging/firebase_messaging.dart' as firebase_messaging;
55
import 'package:flutter/foundation.dart';
66
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
7+
import 'package:image_picker/image_picker.dart' as image_picker;
78
import 'package:package_info_plus/package_info_plus.dart' as package_info_plus;
89
import 'package:url_launcher/url_launcher.dart' as url_launcher;
910

@@ -13,6 +14,7 @@ import '../widgets/store.dart';
1314
import 'store.dart';
1415

1516
export 'package:file_picker/file_picker.dart' show FilePickerResult, FileType, PlatformFile;
17+
export 'package:image_picker/image_picker.dart' show ImageSource, XFile;
1618

1719
/// Alias for [url_launcher.LaunchMode].
1820
typedef UrlLaunchMode = url_launcher.LaunchMode;
@@ -164,6 +166,14 @@ abstract class ZulipBinding {
164166
bool withReadStream,
165167
file_picker.FileType type,
166168
});
169+
170+
/// Pick files from the camera or media library, via package:image_picker.
171+
///
172+
/// This wraps [image_picker.pickImage].
173+
Future<image_picker.XFile?> pickImage({
174+
required image_picker.ImageSource source,
175+
bool requestFullMetadata,
176+
});
167177
}
168178

169179
/// Like [device_info_plus.BaseDeviceInfo], but without things we don't use.
@@ -414,4 +424,13 @@ class LiveZulipBinding extends ZulipBinding {
414424
type: type,
415425
);
416426
}
427+
428+
@override
429+
Future<image_picker.XFile?> pickImage({
430+
required image_picker.ImageSource source,
431+
bool requestFullMetadata = true,
432+
}) async {
433+
return image_picker.ImagePicker()
434+
.pickImage(source: source, requestFullMetadata: requestFullMetadata);
435+
}
417436
}

lib/widgets/compose_box.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import 'package:app_settings/app_settings.dart';
22
import 'package:flutter/material.dart';
33
import 'package:flutter/services.dart';
44
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
5-
import 'package:image_picker/image_picker.dart';
65

76
import '../api/exception.dart';
87
import '../api/model/model.dart';
@@ -624,15 +623,15 @@ class _AttachFromCameraButton extends _AttachUploadsButton {
624623
@override
625624
Future<Iterable<_File>> getFiles(BuildContext context) async {
626625
final zulipLocalizations = ZulipLocalizations.of(context);
627-
final picker = ImagePicker();
628626
final XFile? result;
629627
try {
630628
// Ideally we'd open a platform interface that lets you choose between
631629
// taking a photo and a video. `image_picker` doesn't yet have that
632630
// option: https://github.com/flutter/flutter/issues/89159
633631
// so just stick with images for now. We could add another button for
634632
// videos, but we don't want too many buttons.
635-
result = await picker.pickImage(source: ImageSource.camera, requestFullMetadata: false);
633+
result = await ZulipBinding.instance.pickImage(
634+
source: ImageSource.camera, requestFullMetadata: false);
636635
} catch (e) {
637636
if (!context.mounted) return [];
638637
if (e is PlatformException && e.code == 'camera_access_denied') {

test/model/binding.dart

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class TestZulipBinding extends ZulipBinding {
7474
_resetFirebase();
7575
_resetNotifications();
7676
_resetPickFiles();
77+
_resetPickImage();
7778
}
7879

7980
/// The current global store offered to a [GlobalStoreWidget].
@@ -328,6 +329,45 @@ class TestZulipBinding extends ZulipBinding {
328329
(_pickFilesCalls ??= []).add((allowMultiple: allowMultiple, withReadStream: withReadStream, type: type));
329330
return pickFilesResult;
330331
}
332+
333+
/// The value that `ZulipBinding.instance.pickImage()` should return.
334+
///
335+
/// See also [takePickImageCalls].
336+
XFile? pickImageResult;
337+
338+
void _resetPickImage() {
339+
pickImageResult = null;
340+
_pickImageCalls = null;
341+
}
342+
343+
/// Consume the log of calls made to `ZulipBinding.instance.pickImage()`.
344+
///
345+
/// This returns a list of the arguments to all calls made
346+
/// to `ZulipBinding.instance.pickImage()` since the last call to
347+
/// either this method or [reset].
348+
///
349+
/// See also [pickImageResult].
350+
List<({
351+
ImageSource source,
352+
bool requestFullMetadata,
353+
})> takePickImageCalls() {
354+
final result = _pickImageCalls;
355+
_pickImageCalls = null;
356+
return result ?? [];
357+
}
358+
List<({
359+
ImageSource source,
360+
bool requestFullMetadata,
361+
})>? _pickImageCalls;
362+
363+
@override
364+
Future<XFile?> pickImage({
365+
required ImageSource source,
366+
bool requestFullMetadata = true,
367+
}) async {
368+
(_pickImageCalls ??= []).add((source: source, requestFullMetadata: requestFullMetadata));
369+
return pickImageResult;
370+
}
331371
}
332372

333373
class FakeFirebaseMessaging extends Fake implements FirebaseMessaging {

0 commit comments

Comments
 (0)