mobdr/lib/ui/home/photo_list.dart

486 lines
18 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:mobdr/config/constant.dart';
import 'package:mobdr/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:mobdr/model/photo_model.dart';
import 'package:mobdr/ui/reusable/cache_image_network.dart';
import 'package:mobdr/ui/reusable/global_widget.dart';
import 'package:mobdr/ui/home/photo_camera.dart';
import 'package:mobdr/objectbox.dart';
import 'package:mobdr/db/box_photo.dart';
class PhotoListPage extends StatefulWidget {
@override
_PhotoListPageState createState() => _PhotoListPageState();
}
class _PhotoListPageState extends State<PhotoListPage> {
final _globalWidget = GlobalWidget();
// initialize photos files list
final List<File> photoFiles = [];
List<PhotoModel> _photoData = [];
Color _color1 = Color(0xff777777);
Color _color2 = Color(0xFF515151);
// _listKey is used for AnimatedList
var _listKey = GlobalKey<AnimatedListState>();
@override
void initState() {
super.initState();
_loadData();
}
@override
void dispose() {
super.dispose();
}
void _loadData() {
for (Photo myPhoto in objectbox.getPhotos2()) {
_photoData.add(PhotoModel(
id: myPhoto.id,
id_visite: myPhoto.id_visite,
id_photo_typologie: myPhoto.id_photo_typologie,
image: myPhoto.image));
}
}
@override
Widget build(BuildContext context) {
final double boxImageSize = (MediaQuery.of(context).size.width / 4);
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
systemOverlayStyle: SystemUiOverlayStyle.dark,
elevation: 0,
title: Text(
'Catégorie : A trier',
style: TextStyle(fontSize: 18, color: Colors.black),
),
backgroundColor: Colors.white,
actions: [
GestureDetector(
onTap: () {
Fluttertoast.showToast(
msg: 'Click message', toastLength: Toast.LENGTH_SHORT);
},
child: Icon(Icons.email, color: _color1)),
IconButton(
icon: _globalWidget.customNotifIcon(
count: 8,
notifColor: _color1,
notifSize: 24,
labelSize: 14),
//icon: _globalWidget.customNotifIcon2(8, _color1),
onPressed: () {
Fluttertoast.showToast(
msg: 'Click notification',
toastLength: Toast.LENGTH_SHORT);
}),
],
),
body: RefreshIndicator(
onRefresh: refreshData,
child: AnimatedList(
key: _listKey,
initialItemCount: _photoData.length,
physics: AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index, animation) {
return _buildPhotolistCard(
_photoData[index], boxImageSize, animation, index);
},
),
),
floatingActionButton: fabCart(context));
}
Widget _buildPhotolistCard(
PhotoModel 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: () {
Fluttertoast.showToast(
msg: 'Click ' + photoData.image,
toastLength: Toast.LENGTH_SHORT);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Image.file(
File(photoData.image),
fit: BoxFit.cover,
height: 100,
width: 150,
),
),
SizedBox(
width: 10,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
photoData.id_photo_typologie.toString(),
style: TextStyle(fontSize: 13, color: _color2),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
Container(
margin: EdgeInsets.only(top: 5),
child: Text((index + 1).toString(),
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold)),
),
Container(
margin: EdgeInsets.only(top: 5),
child: Row(
children: [
Icon(Icons.location_on,
color: SOFT_GREY, size: 12),
Text(
' ' +
photoData.id_photo_typologie
.toString(),
style: TextStyle(
fontSize: 11, color: SOFT_GREY))
],
),
),
Container(
margin: EdgeInsets.only(top: 5),
child: Row(
children: [
Text(
'(' +
photoData.id_photo_typologie
.toString() +
')',
style: TextStyle(
fontSize: 11, color: SOFT_GREY))
],
),
),
Container(
margin: EdgeInsets.only(top: 5),
child: Text(
photoData.id_photo_typologie.toString() +
' ' +
'Sale',
style: TextStyle(
fontSize: 11, color: SOFT_GREY)),
),
],
),
)
],
),
),
Container(
margin: EdgeInsets.only(top: 12),
child: Row(
children: [
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showPopupDeleteFavorite(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),
),
),
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_BLUE, width: 1.0),
)),
child: Text(
'Copier dans galerie',
style: TextStyle(
color: SOFT_BLUE,
fontWeight: FontWeight.bold,
fontSize: 13),
textAlign: TextAlign.center,
)),
),
SizedBox(
width: 8,
),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showPopupDeleteFavorite(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.rotate_right_rounded,
color: _color1, size: 20),
),
),
SizedBox(
width: 8,
),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
showPopupDeleteFavorite(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.rotate_left_rounded,
color: _color1, size: 20),
),
)
],
),
)
],
),
),
),
),
);
}
Widget fabCart(context) {
return FloatingActionButton(
onPressed: () {
Route route = MaterialPageRoute(
builder: (context) => CameraPage(photoFiles: photoFiles));
Navigator.push(context, route).then((val) {
/// if the user has validated photos
if (val == true) {
savePhotos();
} else {
deletePhotos();
}
});
},
child: Stack(children: [
Icon(Icons.add_a_photo, color: BLACK21, size: 42),
Positioned(
right: 0,
bottom: 0,
child: Container(
padding: EdgeInsets.all(1),
decoration: BoxDecoration(
color: PRIMARY_COLOR,
borderRadius: BorderRadius.circular(14),
),
constraints: BoxConstraints(
minWidth: 16,
minHeight: 16,
),
child: Center(
child: Text(
_photoData.length.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 8,
),
textAlign: TextAlign.center,
),
),
),
)
]),
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0))),
);
}
void savePhotos() {
print("Save PHOTOS ----:" + photoFiles.length.toString());
if (photoFiles.length > 0) {
final List<Photo> _listPhotos = [];
for (var photo in photoFiles) {
_listPhotos
.add(Photo(id_visite: 0, id_photo_typologie: 0, image: photo.path));
}
objectbox.addPhotos(_listPhotos);
/// refresh widget PhotoListPage
refreshData();
}
}
void deletePhotos() {
print("DELETE PHOTO ------------");
// delete files on local storage
photoFiles.forEach((element) {
//deleteFile(File(element.path));
//element.delete();
});
}
void showPopupDeleteFavorite(index, boxImageSize) {
// set up the buttons
Widget cancelButton = TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('No', style: TextStyle(color: SOFT_BLUE)));
Widget continueButton = TextButton(
onPressed: () {
int removeIndex = index;
var removedItem = _photoData.removeAt(removeIndex);
// 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.
AnimatedRemovedItemBuilder builder = (context, animation) {
// A method to build the Card widget.
return _buildPhotolistCard(
removedItem, boxImageSize, animation, removeIndex);
};
_listKey.currentState!.removeItem(removeIndex, builder);
Navigator.pop(context);
Fluttertoast.showToast(
msg: 'Item has been deleted from your favorite',
toastLength: Toast.LENGTH_SHORT);
},
child: Text('Yes', style: TextStyle(color: SOFT_BLUE)));
// set up the AlertDialog
AlertDialog alert = AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
title: Text(
'Delete Favorite',
style: TextStyle(fontSize: 18),
),
content: Text('Are you sure to delete this item from your Favorite ?',
style: TextStyle(fontSize: 13, color: _color1)),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
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());
}
}
Future refreshData() async {
/// clear all data
/// TODO on pourrait simplement ajouter les nouvelles photos (bien mieux)
_photoData.clear();
photoFiles.clear();
/// reload all photo data from database
_loadData();
/// reinitialiez AnimatedList widget
setState(() => _listKey = GlobalKey());
}
}