diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 2a71919..293cc2d 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -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
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index f34142f..52a54f7 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -53,5 +53,7 @@
Cette application a besoin de votre autorisation pour accéder à votre caméra afin que vous puissiez prendre des photos pour votre profil.
NSMicrophoneUsageDescription
Cette application a besoin de votre autorisation pour accéder à votre microphone afin que vous puissiez enregistrer des messages audio pour envoyer à vos amis.
+ NSPhotoLibraryAddUsageDescription
+ Description de l'autorisation pour accéder à la galerie
diff --git a/lib/ui/visit/visit_photo_typology_detail.dart b/lib/ui/visit/visit_photo_typology_detail.dart
index 70c307c..c16f0bc 100644
--- a/lib/ui/visit/visit_photo_typology_detail.dart
+++ b/lib/ui/visit/visit_photo_typology_detail.dart
@@ -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 saveImageToGallery(String imagePath) async {
+ final result = await ImageGallerySaver.saveFile(imagePath);
+ bool isSuccess = result["isSuccess"];
+ return isSuccess;
+ }
+
/// Initializes data when the page loads.
Future loadData(int photoId) async {
String tags = "";
diff --git a/lib/ui/visit/visit_photo_typology_list.dart b/lib/ui/visit/visit_photo_typology_list.dart
index 626065d..f5948b7 100644
--- a/lib/ui/visit/visit_photo_typology_list.dart
+++ b/lib/ui/visit/visit_photo_typology_list.dart
@@ -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();
- });
- } 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();
+ });
+ } 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: [
@@ -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(
- (Set 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),
+ ),
),
- )
- ],
+ ],
+ ),
),
- )
- ],
+ ],
+ ),
),
),
),
diff --git a/pubspec.lock b/pubspec.lock
index 7208f01..9f255af 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -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:
diff --git a/pubspec.yaml b/pubspec.yaml
index ef9bda2..de9ef10 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -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