diff --git a/lib/core/components/custom_camera_preview.dart b/lib/core/components/custom_camera_preview.dart index 01354d9..d0a4083 100644 --- a/lib/core/components/custom_camera_preview.dart +++ b/lib/core/components/custom_camera_preview.dart @@ -81,8 +81,6 @@ class _CustomCameraPreviewState extends State { shape: BoxShape.circle), child: GestureDetector( onTap: () { - /// TODO FBE delete image on local storage - fileDelete((widget.photoFiles[index])); setState(() { widget.photoFiles.removeAt(index); }); @@ -103,16 +101,6 @@ class _CustomCameraPreviewState extends State { ); } - Future fileDelete(File file) async { - try { - if (await file.exists()) { - await file.delete(); - } - } catch (e) { - print(e); - } - } - Positioned _rejectButton() { return Positioned( bottom: 5, diff --git a/lib/main.dart b/lib/main.dart index 6dfaa5b..3a6a67f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ // ignore_for_file: prefer_const_constructors import 'dart:ui'; +import 'dart:io'; import 'package:mobdr/config/constant.dart'; @@ -16,6 +17,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:path_provider/path_provider.dart'; import 'objectbox.dart'; import 'package:wakelock/wakelock.dart'; @@ -59,6 +61,8 @@ class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { + initDirectories(); + // Initialize all bloc provider used on this entire application here return MultiBlocProvider( providers: [ @@ -117,4 +121,23 @@ class MyApp extends StatelessWidget { ), ); } + + void initDirectories() async { + // Get the application's document directory + final Directory documentsDir = await getApplicationDocumentsDirectory(); + + // Create a Directory object for the "photos" directory in the documents directory + final Directory photosDir = Directory('${documentsDir.path}/photos'); + + // Check if the "photos" directory exists + if (await photosDir.exists()) { + print( + 'The "photos" directory already exists in the documents directory.'); + } else { + // Create the "photos" directory if it does not exist + await photosDir.create(); + print( + 'The "photos" directory has been created in the documents directory.'); + } + } } diff --git a/lib/objectbox.dart b/lib/objectbox.dart index 89c535a..206db36 100644 --- a/lib/objectbox.dart +++ b/lib/objectbox.dart @@ -68,7 +68,7 @@ class ObjectBox { concurrentBox.removeAll(); visiteBox.removeAll(); visiteTagBox.removeAll(); - photoBox.removeAll(); + //photoBox.removeAll(); //photoTypologyBox.removeAll(); // Add some demo data if the box is empty. diff --git a/lib/ui/home/photo_list.dart b/lib/ui/home/photo_list.dart index 2460675..f184aed 100644 --- a/lib/ui/home/photo_list.dart +++ b/lib/ui/home/photo_list.dart @@ -8,6 +8,8 @@ import 'package:flutter/services.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:image/image.dart' as img; import 'package:path/path.dart' as path; +import 'package:path_provider/path_provider.dart'; +import 'package:flutter/painting.dart' show ImageProvider; import 'package:mobdr/config/constant.dart'; import 'package:mobdr/main.dart'; @@ -16,6 +18,8 @@ import 'package:mobdr/ui/home/photo_camera.dart'; import 'package:mobdr/model/photo_model.dart'; import 'package:mobdr/db/box_photo.dart'; +// TODO Il faut supprimer les possibles photos du répertoire cache ! + extension FileNameExtension on File { String getFileName() { String fileName = path.split('/').last; @@ -138,12 +142,8 @@ class _PhotoListPageState extends State { children: [ ClipRRect( borderRadius: BorderRadius.all(Radius.circular(10)), - child: Image.file( - File(photoData.image), - fit: BoxFit.cover, - height: 100, - width: 150, - ), + child: Image.file(File(photoData.image), + fit: BoxFit.cover, height: 100, width: 150), ), SizedBox( width: 10, @@ -289,8 +289,10 @@ class _PhotoListPageState extends State { behavior: HitTestBehavior.translucent, onTap: () async { await rotateAndReplaceImage( - File(_photoData[index].image)); - setState(() => _listKey = GlobalKey()); + File(_photoData[index].image), 90); + setState(() { + _listKey = GlobalKey(); + }); Fluttertoast.showToast( msg: 'The image has been rotated'); }, @@ -310,8 +312,14 @@ class _PhotoListPageState extends State { ), GestureDetector( behavior: HitTestBehavior.translucent, - onTap: () { - showPopupDeletePhoto(index, boxImageSize); + onTap: () async { + await rotateAndReplaceImage( + File(_photoData[index].image), -90); + setState(() { + _listKey = GlobalKey(); + }); + Fluttertoast.showToast( + msg: 'The image has been rotated'); }, child: Container( padding: EdgeInsets.fromLTRB(5, 0, 5, 0), @@ -345,8 +353,6 @@ class _PhotoListPageState extends State { /// if the user has validated photos if (val == true) { savePhotos(); - } else { - resetPhotos(); } }); }, @@ -384,12 +390,20 @@ class _PhotoListPageState extends State { ); } - void savePhotos() { + Future evictImage(String imageURL) async { + final NetworkImage provider = NetworkImage(imageURL); + return await provider.evict(); + } + + void savePhotos() async { if (photoFiles.length > 0) { final List _listPhotos = []; final List _listPhotosModel = []; - for (var myPhoto in photoFiles) { + for (var myTmpPhoto in photoFiles) { + /// move jpg file to photo directory + final myPhoto = await moveFileFromTempToPhotosDir(myTmpPhoto); + /// database _listPhotos.add(Photo( id_visite: 0, @@ -412,15 +426,9 @@ class _PhotoListPageState extends State { _photoData.insertAll(0, _listPhotosModel); /// refresh widget - setState(() => _listKey = GlobalKey()); - } - } - - void resetPhotos() { - /// for all photos taken - for (var photo in photoFiles) { - /// delete image on local storage - deleteFile(photo); + setState(() { + _listKey = GlobalKey(); + }); } } @@ -447,10 +455,13 @@ class _PhotoListPageState extends State { onPressed: () { int removeIndex = index; var removedItem = _photoData.removeAt(removeIndex); + // delete file on database objectbox.delPhoto(removedItem.image_name); - // delete file on locale storages + + // delete file on local storage deleteFile(new File(removedItem.image)); + // This builder is just so that the animation has something // to work with before it disappears from view since the original // has already been deleted. @@ -494,7 +505,22 @@ class _PhotoListPageState extends State { ); } - Future rotateAndReplaceImage(File imageFile) async { + Future moveFileFromTempToPhotosDir(File tempFile) async { + // Get the application's document directory + final Directory documentsDir = await getApplicationDocumentsDirectory(); + + // Set the new file path with the original file name + final String newPath = + '${documentsDir.path}/photos/${tempFile.path.split('/').last}'; + + // Rename the file to move it to the documents directory + await tempFile.rename(newPath); + + // Create and return a new File object for the new file + return File(newPath); + } + + Future rotateAndReplaceImage(File imageFile, int angle) async { // Read the image file into a Uint8List Uint8List bytes = await imageFile.readAsBytes(); @@ -502,13 +528,15 @@ class _PhotoListPageState extends State { img.Image? image = img.decodeImage(bytes); // Rotate the image clockwise by 90 degrees - img.Image? rotatedImage = img.copyRotate(image!, angle: 10); + img.Image? rotatedImage = img.copyRotate(image!, angle: angle); // Encode the rotated image back into a Uint8List Uint8List rotatedBytes = img.encodePng(rotatedImage); // Overwrite the original file with the rotated image - deleteFile(imageFile); - await imageFile.writeAsBytes(rotatedBytes, flush: true); + await imageFile.writeAsBytes(rotatedBytes); + + // remove the flutter cache image + FileImage(imageFile).evict(); } }