diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1c27db2..81d2263 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -26,6 +26,10 @@ + { final _formKey = GlobalKey(); late TextEditingController _nameController; late TextEditingController _bioController; - late String? profileImageUrl; - File? _profileImage; + String? profileImageUrl; + io.File? _profileImage; @override void initState() { @@ -35,12 +38,60 @@ class EditProfilePageState extends State { } Future _pickImage() async { + if (kIsWeb) { + showMsg(context, 'Limitation of the web version', + 'Due to limitations of the component used in the web version, setting a profile picture is currently available only on Android and iOS.'); + return; + } + final pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery); + if (pickedFile != null) { - setState(() { - _profileImage = File(pickedFile.path); - }); + CroppedFile? croppedFile = await ImageCropper().cropImage( + sourcePath: pickedFile.path, + //compressFormat: ImageCompressFormat.jpg, + //compressQuality: 100, + aspectRatioPresets: [ + CropAspectRatioPreset.square, + CropAspectRatioPreset.ratio3x2, + CropAspectRatioPreset.original, + CropAspectRatioPreset.ratio4x3, + CropAspectRatioPreset.ratio16x9 + ], + uiSettings: [ + AndroidUiSettings( + toolbarTitle: 'Cropper', + toolbarColor: Colors.deepOrange, + toolbarWidgetColor: Colors.white, + initAspectRatio: CropAspectRatioPreset.original, + lockAspectRatio: false, + ), + IOSUiSettings( + title: 'Cropper', + minimumAspectRatio: 1.0, + ), +/* WebUiSettings( + context: context, + presentStyle: CropperPresentStyle.page, + boundary: const CroppieBoundary( + width: 400, + height: 400, + ), + viewPort: + const CroppieViewPort(width: 360, height: 360, type: 'circle'), + enableExif: true, + enableZoom: true, + showZoomer: true, + ),*/ + ], + ); + + if (croppedFile != null) { + setState(() { + _profileImage = io.File(croppedFile.path); // convert cropped file + }); + } } } @@ -64,8 +115,11 @@ class EditProfilePageState extends State { .ref() .child(Constants.dbStoragePathProfiles) .child(uid); // filename = userid - await storageRef.putFile(_profileImage!); - profileImageUrl = await storageRef.getDownloadURL(); + + if (!kIsWeb) { + await storageRef.putFile(_profileImage!); + profileImageUrl = await storageRef.getDownloadURL(); + } } Map resultValues = { @@ -167,7 +221,8 @@ class EditProfilePageState extends State { radius: 50, backgroundImage: _profileImage != null ? FileImage(_profileImage!) as ImageProvider - : (widget.userData.profilePictureUrl != null + : ((widget.userData.profilePictureUrl != null && + widget.userData.profilePictureUrl!.isNotEmpty) ? NetworkImage(widget.userData.profilePictureUrl!) as ImageProvider : null), @@ -179,15 +234,14 @@ class EditProfilePageState extends State { width: 100, height: 100, child: _profileImage != null - ? Image.file( - _profileImage!, - fit: BoxFit.cover, - ) - : (widget.userData.profilePictureUrl != null + ? (kIsWeb + ? Image.network(_profileImage!.path) + : Image.file(_profileImage!, fit: BoxFit.cover)) + : ((widget.userData.profilePictureUrl != null && + widget.userData.profilePictureUrl!.isNotEmpty) ? Image.network( widget.userData.profilePictureUrl!, - fit: BoxFit.cover, - ) + fit: BoxFit.cover) : null), ), ), @@ -197,11 +251,12 @@ class EditProfilePageState extends State { right: 0, child: IconButton( icon: Ink( - decoration: ShapeDecoration( - color: Theme.of(context).colorScheme.primary, - shape: const CircleBorder(), - ), - child: const Icon(Icons.edit)), + decoration: ShapeDecoration( + color: Theme.of(context).colorScheme.primary, + shape: const CircleBorder(), + ), + child: const Icon(Icons.edit), + ), onPressed: _pickImage, ), ), diff --git a/lib/pages/user_profile_page.dart b/lib/pages/user_profile_page.dart index f5b0b5a..7da0dde 100644 --- a/lib/pages/user_profile_page.dart +++ b/lib/pages/user_profile_page.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; @@ -609,11 +610,13 @@ class _UserProfilePageState extends State { ), CircleAvatar( radius: 50, - backgroundImage: - profileImageUrl != null ? NetworkImage(profileImageUrl!) : null, - child: profileImageUrl == null - ? const Icon(Icons.person, size: 50) + backgroundImage: (!kIsWeb && + (profileImageUrl != null && profileImageUrl!.isNotEmpty)) + ? NetworkImage(profileImageUrl!) : null, + child: (profileImageUrl == null || profileImageUrl!.isEmpty) + ? const Icon(Icons.person, size: 50) + : (kIsWeb ? const Icon(Icons.broken_image, size: 50) : null), ), const SizedBox(height: 16), Text(myData.name, style: const TextStyle(fontSize: 24)), diff --git a/pubspec.lock b/pubspec.lock index 65259f1..9e97bac 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -360,6 +360,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image_cropper: + dependency: "direct main" + description: + name: image_cropper + sha256: db779a8b620cd509874cb0e2a8bdc8649177f8f5ca46c13273ceaffe071e3f4a + url: "https://pub.dev" + source: hosted + version: "6.0.0" + image_cropper_for_web: + dependency: transitive + description: + name: image_cropper_for_web + sha256: ba67de40a98b3294084eed0b025b557cb594356e1171c9a830b340527dbd5e5f + url: "https://pub.dev" + source: hosted + version: "4.0.0" + image_cropper_platform_interface: + dependency: transitive + description: + name: image_cropper_platform_interface + sha256: ee160d686422272aa306125f3b6fb1c1894d9b87a5e20ed33fa008e7285da11e + url: "https://pub.dev" + source: hosted + version: "5.0.0" image_picker: dependency: "direct main" description: @@ -424,6 +448,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.1+1" + js: + dependency: transitive + description: + name: js + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + url: "https://pub.dev" + source: hosted + version: "0.7.1" leak_tracker: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b1d779b..0e29a02 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,6 +46,7 @@ dependencies: swipable_stack: ^2.0.0 image_picker: ^1.1.1 firebase_storage: ^11.7.7 + image_cropper: ^6.0.0 dev_dependencies: flutter_test: diff --git a/web/index.html b/web/index.html index d02105a..f05ce2b 100644 --- a/web/index.html +++ b/web/index.html @@ -32,6 +32,11 @@ cofounderella + + + + +