feat: image rotation
parent
235e285020
commit
d063256dce
|
|
@ -81,6 +81,8 @@ class _CustomCameraPreviewState extends State<CustomCameraPreview> {
|
||||||
shape: BoxShape.circle),
|
shape: BoxShape.circle),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
/// TODO FBE delete image on local storage
|
||||||
|
fileDelete((widget.photoFiles[index]));
|
||||||
setState(() {
|
setState(() {
|
||||||
widget.photoFiles.removeAt(index);
|
widget.photoFiles.removeAt(index);
|
||||||
});
|
});
|
||||||
|
|
@ -101,6 +103,16 @@ class _CustomCameraPreviewState extends State<CustomCameraPreview> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> fileDelete(File file) async {
|
||||||
|
try {
|
||||||
|
if (await file.exists()) {
|
||||||
|
await file.delete();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Positioned _rejectButton() {
|
Positioned _rejectButton() {
|
||||||
return Positioned(
|
return Positioned(
|
||||||
bottom: 5,
|
bottom: 5,
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ class Photo {
|
||||||
int id_visite;
|
int id_visite;
|
||||||
int id_photo_typologie;
|
int id_photo_typologie;
|
||||||
String image;
|
String image;
|
||||||
|
String image_name;
|
||||||
DateTime date_photo;
|
DateTime date_photo;
|
||||||
int id_photo_mp4;
|
int id_photo_mp4;
|
||||||
int photo_privee;
|
int photo_privee;
|
||||||
|
|
@ -29,6 +30,7 @@ class Photo {
|
||||||
required this.id_visite,
|
required this.id_visite,
|
||||||
required this.id_photo_typologie,
|
required this.id_photo_typologie,
|
||||||
required this.image,
|
required this.image,
|
||||||
|
required this.image_name,
|
||||||
this.id_photo = 0,
|
this.id_photo = 0,
|
||||||
this.id_photo_mp4 = 0,
|
this.id_photo_mp4 = 0,
|
||||||
this.photo_privee = 0,
|
this.photo_privee = 0,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
class PhotoModel {
|
class PhotoModel {
|
||||||
late int id;
|
|
||||||
late int id_visite;
|
late int id_visite;
|
||||||
late int id_photo_typologie;
|
late int id_photo_typologie;
|
||||||
late String image;
|
late String image;
|
||||||
|
late String image_name;
|
||||||
|
|
||||||
PhotoModel(
|
PhotoModel(
|
||||||
{required this.id,
|
{required this.id_visite,
|
||||||
required this.id_visite,
|
|
||||||
required this.id_photo_typologie,
|
required this.id_photo_typologie,
|
||||||
required this.image});
|
required this.image,
|
||||||
|
required this.image_name});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -283,7 +283,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "9:6788844671665652158",
|
"id": "9:6788844671665652158",
|
||||||
"lastPropertyId": "15:1865824860595482227",
|
"lastPropertyId": "16:539065583624712715",
|
||||||
"name": "Photo",
|
"name": "Photo",
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
|
|
@ -356,6 +356,11 @@
|
||||||
"id": "15:1865824860595482227",
|
"id": "15:1865824860595482227",
|
||||||
"name": "image",
|
"name": "image",
|
||||||
"type": 9
|
"type": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "16:539065583624712715",
|
||||||
|
"name": "image_name",
|
||||||
|
"type": 9
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
|
|
|
||||||
|
|
@ -343,17 +343,19 @@ class ObjectBox {
|
||||||
/// PHOTO --------------------------------------------------------------------
|
/// PHOTO --------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
void addPhotos(List<Photo> _listPhotos) {
|
void addPhotos(List<Photo> _listPhotos) {
|
||||||
store.box<Photo>().putMany(_listPhotos);
|
store.box<Photo>().putManyAsync(_listPhotos);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addPhoto(int id_visite, int id_photo_typologie, String image) =>
|
Future<void> addPhoto(int id_visite, int id_photo_typologie, String image,
|
||||||
|
String image_name) =>
|
||||||
store.runInTransactionAsync(
|
store.runInTransactionAsync(
|
||||||
TxMode.write,
|
TxMode.write,
|
||||||
_addPhotoInTx,
|
_addPhotoInTx,
|
||||||
Photo(
|
Photo(
|
||||||
id_visite: id_visite,
|
id_visite: id_visite,
|
||||||
id_photo_typologie: id_photo_typologie,
|
id_photo_typologie: id_photo_typologie,
|
||||||
image: image));
|
image: image,
|
||||||
|
image_name: image_name));
|
||||||
|
|
||||||
static void _addPhotoInTx(Store store, _Photo) {
|
static void _addPhotoInTx(Store store, _Photo) {
|
||||||
// Perform ObjectBox operations that take longer than a few milliseconds
|
// Perform ObjectBox operations that take longer than a few milliseconds
|
||||||
|
|
@ -384,6 +386,15 @@ class ObjectBox {
|
||||||
.map((query) => query.find());
|
.map((query) => query.find());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void delPhoto(String _name) {
|
||||||
|
final query = photoBox.query(Photo_.image_name.equals(_name)).build();
|
||||||
|
final results = query.find();
|
||||||
|
if (results.isNotEmpty) {
|
||||||
|
final photoToDelete = results.first;
|
||||||
|
photoBox.removeAsync(photoToDelete.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int getVisitPhotoCount(int _id_visite, int _id_Photo_typologie) {
|
int getVisitPhotoCount(int _id_visite, int _id_Photo_typologie) {
|
||||||
final builder = photoBox
|
final builder = photoBox
|
||||||
.query(Photo_.id_visite.equals(_id_visite) &
|
.query(Photo_.id_visite.equals(_id_visite) &
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,7 @@ final _entities = <ModelEntity>[
|
||||||
ModelEntity(
|
ModelEntity(
|
||||||
id: const IdUid(9, 6788844671665652158),
|
id: const IdUid(9, 6788844671665652158),
|
||||||
name: 'Photo',
|
name: 'Photo',
|
||||||
lastPropertyId: const IdUid(15, 1865824860595482227),
|
lastPropertyId: const IdUid(16, 539065583624712715),
|
||||||
flags: 0,
|
flags: 0,
|
||||||
properties: <ModelProperty>[
|
properties: <ModelProperty>[
|
||||||
ModelProperty(
|
ModelProperty(
|
||||||
|
|
@ -380,6 +380,11 @@ final _entities = <ModelEntity>[
|
||||||
id: const IdUid(15, 1865824860595482227),
|
id: const IdUid(15, 1865824860595482227),
|
||||||
name: 'image',
|
name: 'image',
|
||||||
type: 9,
|
type: 9,
|
||||||
|
flags: 0),
|
||||||
|
ModelProperty(
|
||||||
|
id: const IdUid(16, 539065583624712715),
|
||||||
|
name: 'image_name',
|
||||||
|
type: 9,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <ModelRelation>[],
|
relations: <ModelRelation>[],
|
||||||
|
|
@ -760,7 +765,8 @@ ModelDefinition getObjectBoxModel() {
|
||||||
final photo_tag3Offset = fbb.writeString(object.photo_tag3);
|
final photo_tag3Offset = fbb.writeString(object.photo_tag3);
|
||||||
final photo_tag4Offset = fbb.writeString(object.photo_tag4);
|
final photo_tag4Offset = fbb.writeString(object.photo_tag4);
|
||||||
final imageOffset = fbb.writeString(object.image);
|
final imageOffset = fbb.writeString(object.image);
|
||||||
fbb.startTable(16);
|
final image_nameOffset = fbb.writeString(object.image_name);
|
||||||
|
fbb.startTable(17);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addInt64(1, object.id_photo);
|
fbb.addInt64(1, object.id_photo);
|
||||||
fbb.addInt64(2, object.id_visite);
|
fbb.addInt64(2, object.id_visite);
|
||||||
|
|
@ -775,6 +781,7 @@ ModelDefinition getObjectBoxModel() {
|
||||||
fbb.addOffset(12, photo_tag4Offset);
|
fbb.addOffset(12, photo_tag4Offset);
|
||||||
fbb.addInt64(13, object.uploaded);
|
fbb.addInt64(13, object.uploaded);
|
||||||
fbb.addOffset(14, imageOffset);
|
fbb.addOffset(14, imageOffset);
|
||||||
|
fbb.addOffset(15, image_nameOffset);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
|
|
@ -790,6 +797,8 @@ ModelDefinition getObjectBoxModel() {
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0),
|
||||||
image: const fb.StringReader(asciiOptimization: true)
|
image: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGet(buffer, rootOffset, 32, ''),
|
.vTableGet(buffer, rootOffset, 32, ''),
|
||||||
|
image_name: const fb.StringReader(asciiOptimization: true)
|
||||||
|
.vTableGet(buffer, rootOffset, 34, ''),
|
||||||
id_photo:
|
id_photo:
|
||||||
const fb.Int64Reader().vTableGet(buffer, rootOffset, 6, 0),
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 6, 0),
|
||||||
id_photo_mp4:
|
id_photo_mp4:
|
||||||
|
|
@ -802,10 +811,9 @@ ModelDefinition getObjectBoxModel() {
|
||||||
.vTableGet(buffer, rootOffset, 22, ''),
|
.vTableGet(buffer, rootOffset, 22, ''),
|
||||||
photo_tag2: const fb.StringReader(asciiOptimization: true)
|
photo_tag2: const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGet(buffer, rootOffset, 24, ''),
|
.vTableGet(buffer, rootOffset, 24, ''),
|
||||||
photo_tag3: const fb.StringReader(asciiOptimization: true)
|
photo_tag3:
|
||||||
.vTableGet(buffer, rootOffset, 26, ''),
|
const fb.StringReader(asciiOptimization: true).vTableGet(buffer, rootOffset, 26, ''),
|
||||||
photo_tag4: const fb.StringReader(asciiOptimization: true)
|
photo_tag4: const fb.StringReader(asciiOptimization: true).vTableGet(buffer, rootOffset, 28, ''),
|
||||||
.vTableGet(buffer, rootOffset, 28, ''),
|
|
||||||
date_photo: DateTime.fromMillisecondsSinceEpoch(const fb.Int64Reader().vTableGet(buffer, rootOffset, 14, 0)),
|
date_photo: DateTime.fromMillisecondsSinceEpoch(const fb.Int64Reader().vTableGet(buffer, rootOffset, 14, 0)),
|
||||||
uploaded: const fb.Int64Reader().vTableGet(buffer, rootOffset, 30, 0));
|
uploaded: const fb.Int64Reader().vTableGet(buffer, rootOffset, 30, 0));
|
||||||
|
|
||||||
|
|
@ -1072,6 +1080,10 @@ class Photo_ {
|
||||||
|
|
||||||
/// see [Photo.image]
|
/// see [Photo.image]
|
||||||
static final image = QueryStringProperty<Photo>(_entities[7].properties[13]);
|
static final image = QueryStringProperty<Photo>(_entities[7].properties[13]);
|
||||||
|
|
||||||
|
/// see [Photo.image_name]
|
||||||
|
static final image_name =
|
||||||
|
QueryStringProperty<Photo>(_entities[7].properties[14]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [PhotoTypology] entity fields to define ObjectBox queries.
|
/// [PhotoTypology] entity fields to define ObjectBox queries.
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,28 @@
|
||||||
|
import 'dart:developer' as developer;
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:mobdr/config/constant.dart';
|
|
||||||
import 'package:mobdr/main.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
import 'package:image/image.dart' as img;
|
||||||
import 'package:mobdr/model/photo_model.dart';
|
import 'package:path/path.dart' as path;
|
||||||
import 'package:mobdr/ui/reusable/cache_image_network.dart';
|
|
||||||
|
import 'package:mobdr/config/constant.dart';
|
||||||
|
import 'package:mobdr/main.dart';
|
||||||
import 'package:mobdr/ui/reusable/global_widget.dart';
|
import 'package:mobdr/ui/reusable/global_widget.dart';
|
||||||
import 'package:mobdr/ui/home/photo_camera.dart';
|
import 'package:mobdr/ui/home/photo_camera.dart';
|
||||||
import 'package:mobdr/objectbox.dart';
|
import 'package:mobdr/model/photo_model.dart';
|
||||||
import 'package:mobdr/db/box_photo.dart';
|
import 'package:mobdr/db/box_photo.dart';
|
||||||
|
|
||||||
|
extension FileNameExtension on File {
|
||||||
|
String getFileName() {
|
||||||
|
String fileName = path.split('/').last;
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class PhotoListPage extends StatefulWidget {
|
class PhotoListPage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
_PhotoListPageState createState() => _PhotoListPageState();
|
_PhotoListPageState createState() => _PhotoListPageState();
|
||||||
|
|
@ -46,10 +55,10 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
void _loadData() {
|
void _loadData() {
|
||||||
for (Photo myPhoto in objectbox.getPhotos2()) {
|
for (Photo myPhoto in objectbox.getPhotos2()) {
|
||||||
_photoData.add(PhotoModel(
|
_photoData.add(PhotoModel(
|
||||||
id: myPhoto.id,
|
|
||||||
id_visite: myPhoto.id_visite,
|
id_visite: myPhoto.id_visite,
|
||||||
id_photo_typologie: myPhoto.id_photo_typologie,
|
id_photo_typologie: myPhoto.id_photo_typologie,
|
||||||
image: myPhoto.image));
|
image: myPhoto.image,
|
||||||
|
image_name: myPhoto.image_name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,9 +98,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: RefreshIndicator(
|
body: AnimatedList(
|
||||||
onRefresh: refreshData,
|
|
||||||
child: AnimatedList(
|
|
||||||
key: _listKey,
|
key: _listKey,
|
||||||
initialItemCount: _photoData.length,
|
initialItemCount: _photoData.length,
|
||||||
physics: AlwaysScrollableScrollPhysics(),
|
physics: AlwaysScrollableScrollPhysics(),
|
||||||
|
|
@ -100,7 +107,6 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
_photoData[index], boxImageSize, animation, index);
|
_photoData[index], boxImageSize, animation, index);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
|
||||||
floatingActionButton: fabCart(context));
|
floatingActionButton: fabCart(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,10 +171,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.location_on,
|
Icon(Icons.location_on,
|
||||||
color: SOFT_GREY, size: 12),
|
color: SOFT_GREY, size: 12),
|
||||||
Text(
|
Text(' ' + photoData.image_name,
|
||||||
' ' +
|
|
||||||
photoData.id_photo_typologie
|
|
||||||
.toString(),
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11, color: SOFT_GREY))
|
fontSize: 11, color: SOFT_GREY))
|
||||||
],
|
],
|
||||||
|
|
@ -210,7 +213,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showPopupDeleteFavorite(index, boxImageSize);
|
showPopupDeletePhoto(index, boxImageSize);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
|
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
|
||||||
|
|
@ -284,8 +287,12 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
showPopupDeleteFavorite(index, boxImageSize);
|
await rotateAndReplaceImage(
|
||||||
|
File(_photoData[index].image));
|
||||||
|
setState(() => _listKey = GlobalKey());
|
||||||
|
Fluttertoast.showToast(
|
||||||
|
msg: 'The image has been rotated');
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
|
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
|
||||||
|
|
@ -304,7 +311,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showPopupDeleteFavorite(index, boxImageSize);
|
showPopupDeletePhoto(index, boxImageSize);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
|
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
|
||||||
|
|
@ -331,6 +338,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
Widget fabCart(context) {
|
Widget fabCart(context) {
|
||||||
return FloatingActionButton(
|
return FloatingActionButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
photoFiles.clear();
|
||||||
Route route = MaterialPageRoute(
|
Route route = MaterialPageRoute(
|
||||||
builder: (context) => CameraPage(photoFiles: photoFiles));
|
builder: (context) => CameraPage(photoFiles: photoFiles));
|
||||||
Navigator.push(context, route).then((val) {
|
Navigator.push(context, route).then((val) {
|
||||||
|
|
@ -338,7 +346,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
if (val == true) {
|
if (val == true) {
|
||||||
savePhotos();
|
savePhotos();
|
||||||
} else {
|
} else {
|
||||||
deletePhotos();
|
resetPhotos();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -377,34 +385,58 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void savePhotos() {
|
void savePhotos() {
|
||||||
print("Save PHOTOS ----:" + photoFiles.length.toString());
|
|
||||||
|
|
||||||
if (photoFiles.length > 0) {
|
if (photoFiles.length > 0) {
|
||||||
final List<Photo> _listPhotos = [];
|
final List<Photo> _listPhotos = [];
|
||||||
|
final List<PhotoModel> _listPhotosModel = [];
|
||||||
|
|
||||||
for (var photo in photoFiles) {
|
for (var myPhoto in photoFiles) {
|
||||||
_listPhotos
|
/// database
|
||||||
.add(Photo(id_visite: 0, id_photo_typologie: 0, image: photo.path));
|
_listPhotos.add(Photo(
|
||||||
|
id_visite: 0,
|
||||||
|
id_photo_typologie: 0,
|
||||||
|
image: myPhoto.path,
|
||||||
|
image_name: myPhoto.path.split('/').last));
|
||||||
|
|
||||||
|
/// widget
|
||||||
|
_listPhotosModel.add(PhotoModel(
|
||||||
|
id_visite: 0,
|
||||||
|
id_photo_typologie: 0,
|
||||||
|
image: myPhoto.path,
|
||||||
|
image_name: myPhoto.path.split('/').last));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// insert photo(s) in database (async)
|
||||||
objectbox.addPhotos(_listPhotos);
|
objectbox.addPhotos(_listPhotos);
|
||||||
|
|
||||||
/// refresh widget PhotoListPage
|
/// insert photo(s) in widget
|
||||||
refreshData();
|
_photoData.insertAll(0, _listPhotosModel);
|
||||||
|
|
||||||
|
/// refresh widget
|
||||||
|
setState(() => _listKey = GlobalKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void deletePhotos() {
|
void resetPhotos() {
|
||||||
print("DELETE PHOTO ------------");
|
/// for all photos taken
|
||||||
|
for (var photo in photoFiles) {
|
||||||
// delete files on local storage
|
/// delete image on local storage
|
||||||
photoFiles.forEach((element) {
|
deleteFile(photo);
|
||||||
//deleteFile(File(element.path));
|
}
|
||||||
//element.delete();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void showPopupDeleteFavorite(index, boxImageSize) {
|
Future<void> deleteFile(File file) async {
|
||||||
|
try {
|
||||||
|
if (await file.exists()) {
|
||||||
|
await file.delete();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Error in getting access to the file.
|
||||||
|
// todo toast
|
||||||
|
print(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showPopupDeletePhoto(index, boxImageSize) {
|
||||||
// set up the buttons
|
// set up the buttons
|
||||||
Widget cancelButton = TextButton(
|
Widget cancelButton = TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
@ -415,6 +447,10 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
int removeIndex = index;
|
int removeIndex = index;
|
||||||
var removedItem = _photoData.removeAt(removeIndex);
|
var removedItem = _photoData.removeAt(removeIndex);
|
||||||
|
// delete file on database
|
||||||
|
objectbox.delPhoto(removedItem.image_name);
|
||||||
|
// delete file on locale storages
|
||||||
|
deleteFile(new File(removedItem.image));
|
||||||
// This builder is just so that the animation has something
|
// This builder is just so that the animation has something
|
||||||
// to work with before it disappears from view since the original
|
// to work with before it disappears from view since the original
|
||||||
// has already been deleted.
|
// has already been deleted.
|
||||||
|
|
@ -427,7 +463,7 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
|
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
Fluttertoast.showToast(
|
Fluttertoast.showToast(
|
||||||
msg: 'Item has been deleted from your favorite',
|
msg: 'Photo has been deleted from your visit',
|
||||||
toastLength: Toast.LENGTH_SHORT);
|
toastLength: Toast.LENGTH_SHORT);
|
||||||
},
|
},
|
||||||
child: Text('Yes', style: TextStyle(color: SOFT_BLUE)));
|
child: Text('Yes', style: TextStyle(color: SOFT_BLUE)));
|
||||||
|
|
@ -438,10 +474,10 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
'Delete Favorite',
|
'Delete Photo',
|
||||||
style: TextStyle(fontSize: 18),
|
style: TextStyle(fontSize: 18),
|
||||||
),
|
),
|
||||||
content: Text('Are you sure to delete this item from your Favorite ?',
|
content: Text('Are you sure to delete this photo from your visit ?',
|
||||||
style: TextStyle(fontSize: 13, color: _color1)),
|
style: TextStyle(fontSize: 13, color: _color1)),
|
||||||
actions: [
|
actions: [
|
||||||
cancelButton,
|
cancelButton,
|
||||||
|
|
@ -458,28 +494,21 @@ class _PhotoListPageState extends State<PhotoListPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteFile(File file) async {
|
Future<void> rotateAndReplaceImage(File imageFile) async {
|
||||||
try {
|
// Read the image file into a Uint8List
|
||||||
if (await file.exists()) {
|
Uint8List bytes = await imageFile.readAsBytes();
|
||||||
await file.delete();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// Error in getting access to the file.
|
|
||||||
// todo toast
|
|
||||||
print(e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future refreshData() async {
|
// Decode the bytes into an Image object using the image package
|
||||||
/// clear all data
|
img.Image? image = img.decodeImage(bytes);
|
||||||
/// TODO on pourrait simplement ajouter les nouvelles photos (bien mieux)
|
|
||||||
_photoData.clear();
|
|
||||||
photoFiles.clear();
|
|
||||||
|
|
||||||
/// reload all photo data from database
|
// Rotate the image clockwise by 90 degrees
|
||||||
_loadData();
|
img.Image? rotatedImage = img.copyRotate(image!, angle: 10);
|
||||||
|
|
||||||
/// reinitialiez AnimatedList widget
|
// Encode the rotated image back into a Uint8List
|
||||||
setState(() => _listKey = GlobalKey());
|
Uint8List rotatedBytes = img.encodePng(rotatedImage);
|
||||||
|
|
||||||
|
// Overwrite the original file with the rotated image
|
||||||
|
deleteFile(imageFile);
|
||||||
|
await imageFile.writeAsBytes(rotatedBytes, flush: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
24
pubspec.lock
24
pubspec.lock
|
|
@ -17,6 +17,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.6.0"
|
version: "5.6.0"
|
||||||
|
archive:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: archive
|
||||||
|
sha256: d6347d54a2d8028e0437e3c099f66fdb8ae02c4720c1e7534c9f24c10351f85d
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.3.6"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -461,6 +469,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.2"
|
version: "4.0.2"
|
||||||
|
image:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: image
|
||||||
|
sha256: "483a389d6ccb292b570c31b3a193779b1b0178e7eb571986d9a49904b6861227"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.15"
|
||||||
image_picker:
|
image_picker:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -781,6 +797,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
|
pointycastle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointycastle
|
||||||
|
sha256: c3120a968135aead39699267f4c74bc9a08e4e909e86bc1b0af5bfd78691123c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.7.2"
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ dependencies:
|
||||||
image_picker: ^0.8.7
|
image_picker: ^0.8.7
|
||||||
camera: ^0.10.3+2
|
camera: ^0.10.3+2
|
||||||
permission_handler: 10.2.0
|
permission_handler: 10.2.0
|
||||||
|
image: ^4.0.15
|
||||||
|
|
||||||
flutter_cache_manager: ^3.3.0
|
flutter_cache_manager: ^3.3.0
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue