diff --git a/CHANGELOG.md b/CHANGELOG.md index 603b867..d193019 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,3 +40,11 @@ # 3.0.0 - February 22nd 2024 - Removed customButton from ImagePicker. + +# 4.0.0 +* Added title options to theme. +* updated iconica_analysis dependency. +* Updated default theme. + +# 4.1.0 +* Added support for handling errors when calling `pickImage`. diff --git a/example/lib/main.dart b/example/lib/main.dart index 856f360..90f6f73 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -11,7 +11,9 @@ void main() { } class ImagePickerExample extends StatelessWidget { - const ImagePickerExample({Key? key}) : super(key: key); + const ImagePickerExample({ + super.key, + }); @override Widget build(BuildContext context) { @@ -27,8 +29,10 @@ class ImagePickerExample extends StatelessWidget { } class ImagePickerExampleHomePage extends StatefulWidget { - const ImagePickerExampleHomePage({Key? key, required this.title}) - : super(key: key); + const ImagePickerExampleHomePage({ + required this.title, + super.key, + }); final String title; @@ -112,7 +116,13 @@ class ImagePickerExampleHomePageState Uint8List? imageInBytes = await showModalBottomSheet( context: context, backgroundColor: Colors.white, - builder: (BuildContext context) => const ImagePicker()); + builder: (BuildContext context) => ImagePicker( + onError: (error) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(error.message ?? "An error occurred")), + ); + }, + )); if (imageInBytes != null) { if (!listEquals(uploadedImage, imageInBytes)) { setState(() { diff --git a/lib/flutter_image_picker.dart b/lib/flutter_image_picker.dart index ac4d95d..de1cc98 100644 --- a/lib/flutter_image_picker.dart +++ b/lib/flutter_image_picker.dart @@ -4,7 +4,7 @@ /// library flutter_image_picker; -export 'src/models/image_picker_config.dart'; -export 'src/models/image_picker_theme.dart'; -export 'src/services/image_picker_service.dart'; -export 'src/ui/image_picker.dart'; +export "src/models/image_picker_config.dart"; +export "src/models/image_picker_theme.dart"; +export "src/services/image_picker_service.dart"; +export "src/ui/image_picker.dart"; diff --git a/lib/src/models/image_picker_theme.dart b/lib/src/models/image_picker_theme.dart index dfa843d..1d19082 100644 --- a/lib/src/models/image_picker_theme.dart +++ b/lib/src/models/image_picker_theme.dart @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: BSD-3-Clause -import 'package:flutter/material.dart'; +import "package:flutter/material.dart"; class ImagePickerTheme { /// The [ImagePickerTheme] is used to style the [ImagePicker]. @@ -12,11 +12,14 @@ class ImagePickerTheme { this.iconSize = 125, this.spaceBetweenIcons = 30, this.makePhotoIcon, - this.makePhotoText = 'Take a Picture', + this.makePhotoText = "TAKE PICTURE", this.selectImageIcon, - this.selectImageText = 'Select File', + this.selectImageText = "UPLOAD FILE", this.iconTextStyle, this.closeButtonBuilder, + this.title = "Do you want to upload a file or take a picture?", + this.titleStyle, + this.titleAlignment = TextAlign.center, }); /// The color of the icons @@ -45,5 +48,11 @@ class ImagePickerTheme { final TextStyle? iconTextStyle; - final Widget Function(Function onTap)? closeButtonBuilder; + final Widget Function(Function() onTap)? closeButtonBuilder; + + final String title; + + final TextStyle? titleStyle; + + final TextAlign titleAlignment; } diff --git a/lib/src/services/image_picker_service.dart b/lib/src/services/image_picker_service.dart index 93ebc8b..9483013 100644 --- a/lib/src/services/image_picker_service.dart +++ b/lib/src/services/image_picker_service.dart @@ -2,9 +2,9 @@ // // SPDX-License-Identifier: BSD-3-Clause -import 'dart:typed_data'; -import 'package:flutter_image_picker/src/models/image_picker_config.dart'; -import 'package:image_picker/image_picker.dart'; +import "dart:typed_data"; +import "package:flutter_image_picker/src/models/image_picker_config.dart"; +import "package:image_picker/image_picker.dart"; /// The Image Picker Service class is the functionality of the Image Picker /// package which uses the Image Picker package to choose an image. diff --git a/lib/src/ui/image_picker.dart b/lib/src/ui/image_picker.dart index 102d4ad..63a8a9e 100644 --- a/lib/src/ui/image_picker.dart +++ b/lib/src/ui/image_picker.dart @@ -2,9 +2,10 @@ // // SPDX-License-Identifier: BSD-3-Clause -import 'package:flutter/material.dart'; -import 'package:flutter_image_picker/flutter_image_picker.dart'; -import 'package:image_picker/image_picker.dart'; +import "package:flutter/material.dart"; +import "package:flutter/services.dart"; +import "package:flutter_image_picker/flutter_image_picker.dart"; +import "package:image_picker/image_picker.dart"; /// The Image Picker class generates the Image Picker Widget which can be /// displayed in your application. If you call the class you can give it 4 @@ -21,6 +22,7 @@ class ImagePicker extends StatelessWidget { this.theme = const ImagePickerTheme(), this.config = const ImagePickerConfig(), this.service, + this.onError, super.key, }); @@ -36,10 +38,20 @@ class ImagePicker extends StatelessWidget { /// add more features. If null the current implementation will be used. final ImagePickerService? service; + final Function(PlatformException error)? onError; + @override Widget build(BuildContext context) => SingleChildScrollView( child: Column( children: [ + ListTile( + title: Text( + theme.title, + style: + theme.titleStyle ?? Theme.of(context).textTheme.titleMedium, + textAlign: theme.titleAlignment, + ), + ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -50,6 +62,7 @@ class ImagePicker extends StatelessWidget { Icons.image, ImageSource.gallery, theme.selectImageText, + onError, ), if (config.cameraOption ?? true) ...[ SizedBox( @@ -62,6 +75,7 @@ class ImagePicker extends StatelessWidget { Icons.camera_alt_rounded, ImageSource.camera, theme.makePhotoText, + onError, ), ], ], @@ -82,7 +96,7 @@ class ImagePicker extends StatelessWidget { ), onPressed: () => Navigator.of(context).pop(), child: const Text( - 'Close', + "Close", style: TextStyle( fontSize: 15, color: Colors.white, @@ -117,6 +131,7 @@ class ImagePicker extends StatelessWidget { IconData icon, ImageSource imageSource, String bottomText, + Function(PlatformException error)? onError, ) => Column( mainAxisSize: MainAxisSize.min, @@ -125,8 +140,14 @@ class ImagePicker extends StatelessWidget { key: Key(bottomText), onTap: () async { var navigator = Navigator.of(context); - var image = await (service ?? ImagePickerServiceDefault()) - .pickImage(imageSource, config: config); + Uint8List? image; + try { + image = await (service ?? ImagePickerServiceDefault()) + .pickImage(imageSource, config: config); + } on PlatformException catch (e) { + debugPrint("image_picker_error: $e"); + onError?.call(e); + } navigator.pop(image); }, child: customIcon ?? diff --git a/pubspec.yaml b/pubspec.yaml index 09c7d40..50fb559 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_image_picker description: A Flutter Image Picking package. -version: 3.0.0 +version: 4.1.0 repository: https://github.com/Iconica-Development/flutter_image_picker publish_to: https://forgejo.internal.iconica.nl/api/packages/internal/pub @@ -12,7 +12,7 @@ environment: dependencies: flutter: sdk: flutter - image_picker: ^1.0.7 + image_picker: ^1.1.2 dev_dependencies: flutter_test: @@ -21,6 +21,4 @@ dev_dependencies: flutter_iconica_analysis: git: url: https://github.com/Iconica-Development/flutter_iconica_analysis - ref: 6.0.0 - -flutter: + ref: 7.0.0 diff --git a/test/image_picker_ui_test.dart b/test/image_picker_ui_test.dart index 098dc3b..363db2b 100644 --- a/test/image_picker_ui_test.dart +++ b/test/image_picker_ui_test.dart @@ -2,22 +2,22 @@ // // SPDX-License-Identifier: BSD-3-Clause -import 'dart:typed_data'; +import "dart:typed_data"; -import 'package:flutter/material.dart'; -import 'package:flutter_image_picker/flutter_image_picker.dart' +import "package:flutter/material.dart"; +import "package:flutter_image_picker/flutter_image_picker.dart" as iconica_image_picker; -import 'package:flutter_test/flutter_test.dart'; -import 'package:image_picker/image_picker.dart' as image_picker; -import 'package:mocktail/mocktail.dart'; +import "package:flutter_test/flutter_test.dart"; +import "package:image_picker/image_picker.dart" as image_picker; +import "package:mocktail/mocktail.dart"; -import 'mocks/image_picker_service_mock.dart'; +import "mocks/image_picker_service_mock.dart"; void main() { var cameraImage = Uint8List(10); var galleryImage = Uint8List(44); - testWidgets('Image Picker Shows With Normal Theme', (tester) async { + testWidgets("Image Picker Shows With Normal Theme", (tester) async { await tester.pumpWidget( const MaterialApp( home: Material( @@ -32,7 +32,7 @@ void main() { var selectImageIconFinder = find.byIcon(Icons.image); var selectImageTextFinder = find .text(const iconica_image_picker.ImagePickerTheme().selectImageText); - var closebuttonTextFinder = find.text('Close'); + var closebuttonTextFinder = find.text("Close"); expect(makePhotoIconFinder, findsOneWidget); expect(makePhotoTextFinder, findsOneWidget); @@ -42,7 +42,7 @@ void main() { }); testWidgets( - 'Image Picker Calls Function Correctly When ImageSource Is Gallery', + "Image Picker Calls Function Correctly When ImageSource Is Gallery", (tester) async { var serviceMock = ImagePickerServiceMock(); @@ -70,7 +70,7 @@ void main() { }); testWidgets( - 'Image Picker Calls Function Correctly When ImageSource Is Camera', + "Image Picker Calls Function Correctly When ImageSource Is Camera", (tester) async { var serviceMock = ImagePickerServiceMock(); @@ -97,20 +97,20 @@ void main() { .called(1); }); - testWidgets('Image Picker Shows With Custom Theme', (tester) async { + testWidgets("Image Picker Shows With Custom Theme", (tester) async { Widget makePhotoIcon = Container( height: 125, width: 125, color: Colors.red, ); - var makePhotoText = 'taaaake image'; + var makePhotoText = "taaaake image"; Widget selectImageIcon = Container( height: 125, width: 125, color: Colors.blue, ); - var selectImageText = 'seleeeeect image'; - var closeButtonText = 'Close'; + var selectImageText = "seleeeeect image"; + var closeButtonText = "Close"; await tester.pumpWidget( MaterialApp( diff --git a/test/mocks/image_picker_service_mock.dart b/test/mocks/image_picker_service_mock.dart index 1f16e5c..2ac8aa9 100644 --- a/test/mocks/image_picker_service_mock.dart +++ b/test/mocks/image_picker_service_mock.dart @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: BSD-3-Clause -import 'package:flutter_image_picker/src/services/image_picker_service.dart'; -import 'package:mocktail/mocktail.dart'; +import "package:flutter_image_picker/src/services/image_picker_service.dart"; +import "package:mocktail/mocktail.dart"; class ImagePickerServiceMock extends Mock implements ImagePickerService {}