feat: copy to gallery

release/mobdr-v0.0.1
Frédérik Benoist 2023-06-03 23:23:52 +02:00
parent b27126cac2
commit ee68dd4f98
6 changed files with 154 additions and 192 deletions

View File

@ -13,6 +13,8 @@ PODS:
- FMDB (2.7.5): - FMDB (2.7.5):
- FMDB/standard (= 2.7.5) - FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5) - FMDB/standard (2.7.5)
- image_gallery_saver (2.0.1):
- Flutter
- image_picker_ios (0.0.1): - image_picker_ios (0.0.1):
- Flutter - Flutter
- ObjectBox (1.8.1) - ObjectBox (1.8.1)
@ -45,6 +47,7 @@ DEPENDENCIES:
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- objectbox_flutter_libs (from `.symlinks/plugins/objectbox_flutter_libs/ios`) - objectbox_flutter_libs (from `.symlinks/plugins/objectbox_flutter_libs/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
@ -73,6 +76,8 @@ EXTERNAL SOURCES:
:path: Flutter :path: Flutter
fluttertoast: fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios" :path: ".symlinks/plugins/fluttertoast/ios"
image_gallery_saver:
:path: ".symlinks/plugins/image_gallery_saver/ios"
image_picker_ios: image_picker_ios:
:path: ".symlinks/plugins/image_picker_ios/ios" :path: ".symlinks/plugins/image_picker_ios/ios"
objectbox_flutter_libs: objectbox_flutter_libs:
@ -99,6 +104,7 @@ SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
image_gallery_saver: 6eb11e5a866e9ac2c8a98c74ef99a04fc62878b2
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5 image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
ObjectBox: a7900d5335218cd437cbc080b7ccc38a5211f7b4 ObjectBox: a7900d5335218cd437cbc080b7ccc38a5211f7b4
objectbox_flutter_libs: 61d74196d924fbc773da5f5757d1e9fab7b3cc78 objectbox_flutter_libs: 61d74196d924fbc773da5f5757d1e9fab7b3cc78

View File

@ -53,5 +53,7 @@
<string>Cette application a besoin de votre autorisation pour accéder à votre caméra afin que vous puissiez prendre des photos pour votre profil.</string> <string>Cette application a besoin de votre autorisation pour accéder à votre caméra afin que vous puissiez prendre des photos pour votre profil.</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>Cette application a besoin de votre autorisation pour accéder à votre microphone afin que vous puissiez enregistrer des messages audio pour envoyer à vos amis.</string> <string>Cette application a besoin de votre autorisation pour accéder à votre microphone afin que vous puissiez enregistrer des messages audio pour envoyer à vos amis.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Description de l'autorisation pour accéder à la galerie</string>
</dict> </dict>
</plist> </plist>

View File

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:mobdr/config/constant.dart'; import 'package:mobdr/config/constant.dart';
import 'package:mobdr/config/global_style.dart'; import 'package:mobdr/config/global_style.dart';
@ -150,32 +151,23 @@ class _VisitPhotoTypologyDetailPageState
), ),
child: Row( child: Row(
children: [ children: [
Container(
child: GestureDetector(
onTap: () {
// TODO icone rond a coté copier galerie a supprimer on Tap c'est chatus()
},
child: ClipOval(
child: Container(
color: SOFT_BLUE,
padding: EdgeInsets.all(9),
child: Icon(Icons.chat,
color: Colors.white, size: 16)),
),
),
),
SizedBox( SizedBox(
width: 10, width: 8,
), ),
Expanded( Expanded(
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () async {
setState(() { bool isSaved =
//_shoppingCartCount++; await saveImageToGallery(widget.pp_image);
}); if (isSaved) {
Fluttertoast.showToast( Fluttertoast.showToast(
msg: 'Item has been added to Shopping Card', msg: 'Photo has been added to gallery',
toastLength: Toast.LENGTH_LONG); toastLength: Toast.LENGTH_LONG);
} else {
Fluttertoast.showToast(
msg: 'Error while copying!',
toastLength: Toast.LENGTH_LONG);
}
}, },
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
@ -511,6 +503,12 @@ class _VisitPhotoTypologyDetailPageState
}); });
} }
Future<bool> saveImageToGallery(String imagePath) async {
final result = await ImageGallerySaver.saveFile(imagePath);
bool isSuccess = result["isSuccess"];
return isSuccess;
}
/// Initializes data when the page loads. /// Initializes data when the page loads.
Future<void> loadData(int photoId) async { Future<void> loadData(int photoId) async {
String tags = ""; String tags = "";

View File

@ -191,47 +191,47 @@ class _VisitPhotoTypologyListPageState
VisitPhoto photoData, boxImageSize, animation, index) { VisitPhoto photoData, boxImageSize, animation, index) {
return SizeTransition( return SizeTransition(
sizeFactor: animation, sizeFactor: animation,
child: Container( child: GestureDetector(
margin: EdgeInsets.fromLTRB(12, 6, 12, 0), onTap: () {
child: Card( Route route = MaterialPageRoute(
shape: RoundedRectangleBorder( builder: (context) => VisitPhotoTypologyDetailPage(
borderRadius: BorderRadius.circular(10), pp_imageId: _visitPhotoData[index].id,
), pp_visitModel: widget.pp_visitModel,
elevation: 2, pp_image: _visitPhotoData[index].getImage(),
color: Colors.white, pp_id_typologie: widget.pp_id_typologie,
child: Container( ),
margin: EdgeInsets.all(8), );
child: Column(
children: [
GestureDetector(
onTap: () {
Route route = MaterialPageRoute(
builder: (context) => VisitPhotoTypologyDetailPage(
pp_imageId: _visitPhotoData[index].id,
pp_visitModel: widget.pp_visitModel,
pp_image: _visitPhotoData[index].getImage(),
pp_id_typologie: widget.pp_id_typologie,
));
Navigator.push(context, route).then((result) { Navigator.push(context, route).then((result) {
if (result['change_typologie']) { if (result['change_typologie']) {
// the photo must be removed // the photo must be removed
setState(() { setState(() {
_visitPhotoData.removeAt(index); _visitPhotoData.removeAt(index);
_listKey = GlobalKey<AnimatedListState>(); _listKey = GlobalKey<AnimatedListState>();
}); });
} else { } else {
setState(() { setState(() {
_visitPhotoData[index].tags = result['tags']; _visitPhotoData[index].tags = result['tags'];
_visitPhotoData[index].photo_principale = _visitPhotoData[index].photo_principale =
result['photo_principale']; result['photo_principale'];
_visitPhotoData[index].photo_privee = _visitPhotoData[index].photo_privee = result['photo_privee'];
result['photo_privee']; });
}); }
} });
}); },
}, child: Container(
child: Row( margin: EdgeInsets.fromLTRB(12, 6, 12, 0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 2,
color: Colors.white,
child: Container(
margin: EdgeInsets.all(8),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
@ -252,10 +252,11 @@ class _VisitPhotoTypologyListPageState
child: Row( child: Row(
children: [ children: [
Text( Text(
DateFormat('dd/MM/yyyy HH:mm:ss') DateFormat('dd/MM/yyyy HH:mm:ss')
.format(photoData.date_photo), .format(photoData.date_photo),
style: TextStyle( style: TextStyle(
fontSize: 11, color: SOFT_GREY)) fontSize: 11, color: SOFT_GREY),
),
], ],
), ),
), ),
@ -269,148 +270,92 @@ class _VisitPhotoTypologyListPageState
Container( Container(
margin: EdgeInsets.only(top: 5), margin: EdgeInsets.only(top: 5),
child: Text( child: Text(
'${photoData.tags.isNotEmpty ? (photoData.tags.length > 53 ? '${photoData.tags.substring(0, 50)}...' : photoData.tags) : "notag"}', '${photoData.tags.isNotEmpty ? (photoData.tags.length > 53 ? '${photoData.tags.substring(0, 50)}...' : photoData.tags) : "notag"}',
style: TextStyle( style: TextStyle(
fontSize: 13, fontSize: 13, fontWeight: FontWeight.bold),
fontWeight: FontWeight.bold)), ),
), ),
Container(height: 8), Container(height: 8),
], ],
), ),
) ),
], ],
), ),
), Container(
Container( margin: EdgeInsets.only(top: 12),
margin: EdgeInsets.only(top: 12), child: Row(
child: Row( children: [
children: [ GestureDetector(
GestureDetector( behavior: HitTestBehavior.translucent,
behavior: HitTestBehavior.translucent, onTap: () {
onTap: () { showPopupDeletePhoto(index, boxImageSize);
showPopupDeletePhoto(index, boxImageSize); },
}, child: Container(
child: Container( padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
padding: EdgeInsets.fromLTRB(5, 0, 5, 0), height: 30,
height: 30, decoration: BoxDecoration(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
border: Border.all( border: Border.all(
width: 1, color: Colors.grey[300]!)), width: 1, color: Colors.grey[300]!),
child: Icon(Icons.delete, color: _color1, size: 20), ),
child: Icon(Icons.delete, color: _color1, size: 20),
),
), ),
), Spacer(),
SizedBox( GestureDetector(
width: 8, behavior: HitTestBehavior.translucent,
), onTap: () async {
Expanded( await rotateAndReplaceImage(
child: (1 == 0) // (productData.stock == 0) File(_visitPhotoData[index].getImage()), 90);
? TextButton( setState(() {
style: ButtonStyle( _listKey = GlobalKey();
minimumSize: });
MaterialStateProperty.all(Size(0, 30)), Fluttertoast.showToast(
backgroundColor: msg: 'The image has been rotated');
MaterialStateProperty.resolveWith<Color>( },
(Set<MaterialState> states) => child: Container(
Colors.grey[300]!, padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
), height: 30,
overlayColor: MaterialStateProperty.all( decoration: BoxDecoration(
Colors.transparent),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
)),
),
onPressed: null,
child: Text(
'Out of Stock',
style: TextStyle(
color: Colors.grey[600],
fontWeight: FontWeight.bold,
fontSize: 13),
textAlign: TextAlign.center,
))
: OutlinedButton(
onPressed: () {
Fluttertoast.showToast(
msg:
'Item has been added to Shopping Cart');
},
style: ButtonStyle(
minimumSize:
MaterialStateProperty.all(Size(0, 30)),
overlayColor: MaterialStateProperty.all(
Colors.transparent),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
)),
side: MaterialStateProperty.all(
BorderSide(color: SOFT_GREY, width: 1.0),
)),
child: Text(
'Copier dans galerie',
style: TextStyle(
color: SOFT_GREY,
fontWeight: FontWeight.bold,
fontSize: 13),
textAlign: TextAlign.center,
)),
),
SizedBox(
width: 8,
),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () async {
await rotateAndReplaceImage(
File(_visitPhotoData[index].getImage()), 90);
setState(() {
_listKey = GlobalKey();
});
Fluttertoast.showToast(
msg: 'The image has been rotated');
},
child: Container(
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
border: Border.all( border: Border.all(
width: 1, color: Colors.grey[300]!)), width: 1, color: Colors.grey[300]!),
child: Icon(Icons.rotate_right_rounded, ),
color: _color1, size: 20), child: Icon(Icons.rotate_right_rounded,
color: _color1, size: 20),
),
), ),
), SizedBox(
SizedBox( width: 8,
width: 8, ),
), GestureDetector(
GestureDetector( behavior: HitTestBehavior.translucent,
behavior: HitTestBehavior.translucent, onTap: () async {
onTap: () async { await rotateAndReplaceImage(
await rotateAndReplaceImage( File(_visitPhotoData[index].getImage()), -90);
File(_visitPhotoData[index].getImage()), -90); setState(() {
setState(() { _listKey = GlobalKey();
_listKey = GlobalKey(); });
}); Fluttertoast.showToast(
Fluttertoast.showToast( msg: 'The image has been rotated');
msg: 'The image has been rotated'); },
}, child: Container(
child: Container( padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
padding: EdgeInsets.fromLTRB(5, 0, 5, 0), height: 30,
height: 30, decoration: BoxDecoration(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
border: Border.all( border: Border.all(
width: 1, color: Colors.grey[300]!)), width: 1, color: Colors.grey[300]!),
child: Icon(Icons.rotate_left_rounded, ),
color: _color1, size: 20), child: Icon(Icons.rotate_left_rounded,
color: _color1, size: 20),
),
), ),
) ],
], ),
), ),
) ],
], ),
), ),
), ),
), ),

View File

@ -549,6 +549,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.15" version: "4.0.15"
image_gallery_saver:
dependency: "direct main"
description:
name: image_gallery_saver
sha256: "009b7722cd8507fd72c7f2cb7cbc46d6e15ad0895469cfcc39a10f86e3556979"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
image_picker: image_picker:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -108,6 +108,9 @@ dependencies:
# https://pub.dev/packages/logger # https://pub.dev/packages/logger
logger: ^1.3.0 logger: ^1.3.0
# https://pub.dev/packages/image_gallery_saver
image_gallery_saver: ^2.0.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter