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/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- image_gallery_saver (2.0.1):
- Flutter
- image_picker_ios (0.0.1):
- Flutter
- ObjectBox (1.8.1)
@ -45,6 +47,7 @@ DEPENDENCIES:
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- Flutter (from `Flutter`)
- 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`)
- objectbox_flutter_libs (from `.symlinks/plugins/objectbox_flutter_libs/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
@ -73,6 +76,8 @@ EXTERNAL SOURCES:
:path: Flutter
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
image_gallery_saver:
:path: ".symlinks/plugins/image_gallery_saver/ios"
image_picker_ios:
:path: ".symlinks/plugins/image_picker_ios/ios"
objectbox_flutter_libs:
@ -99,6 +104,7 @@ SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
image_gallery_saver: 6eb11e5a866e9ac2c8a98c74ef99a04fc62878b2
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
ObjectBox: a7900d5335218cd437cbc080b7ccc38a5211f7b4
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>
<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>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Description de l'autorisation pour accéder à la galerie</string>
</dict>
</plist>

View File

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.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/global_style.dart';
@ -150,32 +151,23 @@ class _VisitPhotoTypologyDetailPageState
),
child: Row(
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(
width: 10,
width: 8,
),
Expanded(
child: GestureDetector(
onTap: () {
setState(() {
//_shoppingCartCount++;
});
Fluttertoast.showToast(
msg: 'Item has been added to Shopping Card',
toastLength: Toast.LENGTH_LONG);
onTap: () async {
bool isSaved =
await saveImageToGallery(widget.pp_image);
if (isSaved) {
Fluttertoast.showToast(
msg: 'Photo has been added to gallery',
toastLength: Toast.LENGTH_LONG);
} else {
Fluttertoast.showToast(
msg: 'Error while copying!',
toastLength: Toast.LENGTH_LONG);
}
},
child: Container(
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.
Future<void> loadData(int photoId) async {
String tags = "";

View File

@ -191,47 +191,47 @@ class _VisitPhotoTypologyListPageState
VisitPhoto photoData, boxImageSize, animation, index) {
return SizeTransition(
sizeFactor: animation,
child: Container(
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: [
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,
));
child: 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) {
if (result['change_typologie']) {
// the photo must be removed
setState(() {
_visitPhotoData.removeAt(index);
_listKey = GlobalKey<AnimatedListState>();
});
} else {
setState(() {
_visitPhotoData[index].tags = result['tags'];
_visitPhotoData[index].photo_principale =
result['photo_principale'];
_visitPhotoData[index].photo_privee =
result['photo_privee'];
});
}
});
},
child: Row(
Navigator.push(context, route).then((result) {
if (result['change_typologie']) {
// the photo must be removed
setState(() {
_visitPhotoData.removeAt(index);
_listKey = GlobalKey<AnimatedListState>();
});
} else {
setState(() {
_visitPhotoData[index].tags = result['tags'];
_visitPhotoData[index].photo_principale =
result['photo_principale'];
_visitPhotoData[index].photo_privee = result['photo_privee'];
});
}
});
},
child: Container(
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,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
@ -252,10 +252,11 @@ class _VisitPhotoTypologyListPageState
child: Row(
children: [
Text(
DateFormat('dd/MM/yyyy HH:mm:ss')
.format(photoData.date_photo),
style: TextStyle(
fontSize: 11, color: SOFT_GREY))
DateFormat('dd/MM/yyyy HH:mm:ss')
.format(photoData.date_photo),
style: TextStyle(
fontSize: 11, color: SOFT_GREY),
),
],
),
),
@ -269,148 +270,92 @@ class _VisitPhotoTypologyListPageState
Container(
margin: EdgeInsets.only(top: 5),
child: Text(
'${photoData.tags.isNotEmpty ? (photoData.tags.length > 53 ? '${photoData.tags.substring(0, 50)}...' : photoData.tags) : "notag"}',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold)),
'${photoData.tags.isNotEmpty ? (photoData.tags.length > 53 ? '${photoData.tags.substring(0, 50)}...' : photoData.tags) : "notag"}',
style: TextStyle(
fontSize: 13, fontWeight: FontWeight.bold),
),
),
Container(height: 8),
],
),
)
),
],
),
),
Container(
margin: EdgeInsets.only(top: 12),
child: Row(
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showPopupDeletePhoto(index, boxImageSize);
},
child: Container(
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
height: 30,
decoration: BoxDecoration(
Container(
margin: EdgeInsets.only(top: 12),
child: Row(
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showPopupDeletePhoto(index, boxImageSize);
},
child: Container(
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
width: 1, color: Colors.grey[300]!)),
child: Icon(Icons.delete, color: _color1, size: 20),
width: 1, color: Colors.grey[300]!),
),
child: Icon(Icons.delete, color: _color1, size: 20),
),
),
),
SizedBox(
width: 8,
),
Expanded(
child: (1 == 0) // (productData.stock == 0)
? TextButton(
style: ButtonStyle(
minimumSize:
MaterialStateProperty.all(Size(0, 30)),
backgroundColor:
MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) =>
Colors.grey[300]!,
),
overlayColor: MaterialStateProperty.all(
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(
Spacer(),
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),
border: Border.all(
width: 1, color: Colors.grey[300]!)),
child: Icon(Icons.rotate_right_rounded,
color: _color1, size: 20),
width: 1, color: Colors.grey[300]!),
),
child: Icon(Icons.rotate_right_rounded,
color: _color1, size: 20),
),
),
),
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(
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),
border: Border.all(
width: 1, color: Colors.grey[300]!)),
child: Icon(Icons.rotate_left_rounded,
color: _color1, size: 20),
width: 1, color: Colors.grey[300]!),
),
child: Icon(Icons.rotate_left_rounded,
color: _color1, size: 20),
),
),
)
],
],
),
),
)
],
],
),
),
),
),

View File

@ -549,6 +549,14 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: "direct main"
description:

View File

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