Allow editing existing image entries

This commit is contained in:
Roland Geider
2021-05-10 13:24:51 +02:00
parent 3c96476bdb
commit 4cb473ebf3
4 changed files with 88 additions and 21 deletions

View File

@@ -388,5 +388,11 @@
"selectIngredient": "Please select an ingredient",
"@selectIngredient": {
"description": "Error message when the user hasn't selected an ingredient from the autocompleter"
}
},
"selectImage": "Please select an image",
"@selectImage": {
"description": "Label and error message when the user hasn't selected an image to save"
},
"takePicture": "Take a picture",
"chooseFromLibrary": "Choose from photo library"
}

View File

@@ -464,6 +464,32 @@ class WorkoutPlans extends WgerBaseProvider with ChangeNotifier {
notifyListeners();
}
Future<void> editImage(gallery.Image image, PickedFile? imageFile) async {
var request = http.MultipartRequest('PATCH', makeUrl(_galleryUrlPath, id: image.id));
request.headers.addAll({
HttpHeaders.authorizationHeader: 'Token ${auth.token}',
HttpHeaders.userAgentHeader: 'wger Workout Manager App',
});
// Only send the image if a new one was selected
if (imageFile != null) {
request.files.add(await http.MultipartFile.fromPath('image', imageFile.path));
}
// Update image info
final data = image.toJson();
request.fields['id'] = data['id'];
request.fields['date'] = data['date'];
request.fields['description'] = data['description'];
final res = await request.send();
final respStr = await res.stream.bytesToString();
final responseData = json.decode(respStr);
image.url = responseData['image'];
notifyListeners();
}
Future<void> deleteImage(gallery.Image image) async {
await deleteRequest(_galleryUrlPath, image.id!);
images.removeWhere((element) => element.id == image.id);

View File

@@ -48,6 +48,8 @@ class _ImageFormState extends State<ImageForm> {
@override
void initState() {
super.initState();
dateController.text = toDate(widget._image.date)!;
descriptionController.text = widget._image.description;
}
@@ -61,6 +63,33 @@ class _ImageFormState extends State<ImageForm> {
});
}
/// Returns widget with current picture, depending on whether the user is
/// editing an existing entry or adding a new one. A text message is shown if
/// neither is available
Widget getPicture() {
// An image file was selected, use it
if (_file != null) {
return Image(
image: FileImage(File(_file!.path)),
);
}
// We are editing an existing entry
if (widget._image.url != null) {
return Image.network(widget._image.url!);
}
// No picture available, show a message to the user
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(AppLocalizations.of(context)!.selectImage),
SizedBox(height: 8),
Icon(Icons.photo_camera),
],
);
}
@override
Widget build(BuildContext context) {
return Form(
@@ -84,7 +113,7 @@ class _ImageFormState extends State<ImageForm> {
_showPicker(ImageSource.camera);
},
leading: Icon(Icons.photo_camera),
title: Text("Take a picture"),
title: Text(AppLocalizations.of(context)!.takePicture),
),
ListTile(
onTap: () {
@@ -92,27 +121,14 @@ class _ImageFormState extends State<ImageForm> {
_showPicker(ImageSource.gallery);
},
leading: Icon(Icons.photo_library),
title: Text("Choose from photo library"))
title: Text(AppLocalizations.of(context)!.chooseFromLibrary))
],
),
);
},
);
},
child: _file != null
? Image(
image: FileImage(File(_file!.path)),
//fit: BoxFit.none,
)
: Column(
//mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('please select an image'),
SizedBox(height: 8),
Icon(Icons.photo_camera),
],
),
child: getPicture(),
),
),
TextFormField(
@@ -136,8 +152,8 @@ class _ImageFormState extends State<ImageForm> {
widget._image.date = DateTime.parse(newValue!);
},
validator: (value) {
if (_file == null) {
return 'Please select an image';
if (widget._image.id == null && _file == null) {
return AppLocalizations.of(context)!.selectImage;
}
return null;
@@ -164,9 +180,12 @@ class _ImageFormState extends State<ImageForm> {
}
_form.currentState!.save();
if (_file != null) {
if (widget._image.id == null) {
Provider.of<WorkoutPlans>(context, listen: false).addImage(widget._image, _file!);
Navigator.of(context).pop();
} else {
Provider.of<WorkoutPlans>(context, listen: false).editImage(widget._image, _file);
Navigator.of(context).pop();
}
},
),

View File

@@ -18,9 +18,13 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:wger/providers/workout_plans.dart';
import 'package:wger/screens/form_screen.dart';
import 'forms.dart';
class Gallery extends StatelessWidget {
const Gallery();
@@ -69,7 +73,19 @@ class Gallery extends StatelessWidget {
.deleteImage(currentImage);
Navigator.of(context).pop();
}),
IconButton(icon: Icon(Icons.edit), onPressed: () {}),
IconButton(
icon: Icon(Icons.edit),
onPressed: () {
Navigator.pushNamed(
context,
FormScreen.routeName,
arguments: FormScreenArguments(
AppLocalizations.of(context)!.edit,
ImageForm(currentImage),
true,
),
);
}),
],
)
],