Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 3332 - crop page title now reflects image field #3366

Merged
merged 6 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:provider/provider.dart';
import 'package:smooth_app/data_models/product_image_data.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/database/transient_file.dart';
import 'package:smooth_app/helpers/product_cards_helper.dart';
import 'package:smooth_app/pages/image_crop_page.dart';
import 'package:smooth_app/pages/product/product_image_gallery_view.dart';

Expand Down Expand Up @@ -45,7 +46,12 @@ class _ImageUploadCardState extends State<ImageUploadCard> {
imageField: widget.productImageData.imageField,
),
icon: const Icon(Icons.add_a_photo),
label: Text(widget.productImageData.buttonText),
label: Text(
getProductImageButtonText(
appLocalizations,
widget.productImageData.imageField,
),
),
);
}
return GestureDetector(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:smooth_app/cards/data_cards/image_upload_card.dart';
import 'package:smooth_app/data_models/product_image_data.dart';
Expand All @@ -23,19 +22,16 @@ class ProductImageCarousel extends StatelessWidget {

@override
Widget build(BuildContext context) {
final AppLocalizations appLocalizations = AppLocalizations.of(context);
final List<ProductImageData> productImagesData;
if (alternateImageUrl != null) {
productImagesData = <ProductImageData>[
ProductImageData(
imageUrl: alternateImageUrl,
imageField: ImageField.OTHER,
title: '',
buttonText: '',
),
];
} else {
productImagesData = getProductMainImagesData(product, appLocalizations);
productImagesData = getProductMainImagesData(product);
}
return SizedBox(
height: height,
Expand Down
7 changes: 0 additions & 7 deletions packages/smooth_app/lib/data_models/product_image_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,17 @@ import 'package:openfoodfacts/openfoodfacts.dart';
class ProductImageData {
const ProductImageData({
required this.imageField,
required this.title,
required this.buttonText,
this.imageUrl,
});

factory ProductImageData.from(ProductImage image, String barcode) {
return ProductImageData(
imageField: image.field,
// TODO(VaiTon): i18n
title: image.imgid ?? '',
buttonText: image.imgid ?? '',
imageUrl: ImageHelper.buildUrl(barcode, image),
);
}

final ImageField imageField;
final String title;
final String buttonText;
final String? imageUrl;

/// Try to convert [imageUrl] to specified [size].
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:smooth_app/data_models/product_image_data.dart';
import 'package:smooth_app/generic_lib/loading_sliver.dart';
import 'package:smooth_app/generic_lib/widgets/images/smooth_images_view.dart';
import 'package:smooth_app/generic_lib/widgets/smooth_list_tile_card.dart';
import 'package:smooth_app/helpers/product_cards_helper.dart';

/// Displays a [SliverList] by using [SmoothListTileCard] for showing images
/// passed via [imagesData].
Expand All @@ -18,6 +20,7 @@ class SmoothImagesSliverList extends SmoothImagesView {

@override
Widget build(BuildContext context) {
final AppLocalizations appLocalizations = AppLocalizations.of(context);
final ThemeData themeData = Theme.of(context);
final List<MapEntry<ProductImageData, ImageProvider?>> imageList =
imagesData.entries.toList();
Expand All @@ -31,7 +34,10 @@ class SmoothImagesSliverList extends SmoothImagesView {
childBuilder: (_, int index) => SmoothListTileCard.image(
imageProvider: imageList[index].value,
title: Text(
imageList[index].key.title,
getProductImageTitle(
appLocalizations,
imageList[index].key.imageField,
),
style: themeData.textTheme.headline4,
),
onTap: onTap == null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/database/local_database.dart';
Expand All @@ -23,11 +22,7 @@ class SmoothMainProductImage extends StatelessWidget {
Widget build(BuildContext context) {
context.watch<LocalDatabase>();
final ImageProvider? imageProvider = TransientFile.getImageProvider(
getProductImageData(
product,
AppLocalizations.of(context),
ImageField.FRONT,
),
getProductImageData(product, ImageField.FRONT),
product.barcode!,
);

Expand Down
41 changes: 26 additions & 15 deletions packages/smooth_app/lib/helpers/product_cards_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -177,33 +177,24 @@ Widget addPanelButton(
);

List<ProductImageData> getProductMainImagesData(
Product product,
AppLocalizations appLocalizations, {
Product product, {
final bool includeOther = true,
}) =>
<ProductImageData>[
getProductImageData(product, appLocalizations, ImageField.FRONT),
getProductImageData(product, appLocalizations, ImageField.INGREDIENTS),
getProductImageData(product, appLocalizations, ImageField.NUTRITION),
getProductImageData(product, appLocalizations, ImageField.PACKAGING),
if (includeOther)
getProductImageData(product, appLocalizations, ImageField.OTHER),
getProductImageData(product, ImageField.FRONT),
getProductImageData(product, ImageField.INGREDIENTS),
getProductImageData(product, ImageField.NUTRITION),
getProductImageData(product, ImageField.PACKAGING),
if (includeOther) getProductImageData(product, ImageField.OTHER),
];

ProductImageData getProductImageData(
final Product product,
final AppLocalizations? appLocalizations,
final ImageField imageField,
) =>
ProductImageData(
imageField: imageField,
imageUrl: getProductImageUrl(product, imageField),
title: appLocalizations == null
? ''
: getProductImageTitle(appLocalizations, imageField),
buttonText: appLocalizations == null
? ''
: getProductImageButtonText(appLocalizations, imageField),
);

String? getProductImageUrl(
Expand All @@ -224,6 +215,7 @@ String? getProductImageUrl(
}
}

/// Returns a compact description of the image field.
String getProductImageTitle(
final AppLocalizations appLocalizations,
final ImageField imageField,
Expand All @@ -242,6 +234,25 @@ String getProductImageTitle(
}
}

/// Returns a verbose description of the image field.
String getImagePageTitle(
final AppLocalizations appLocalizations,
final ImageField imageField,
) {
switch (imageField) {
case ImageField.FRONT:
return appLocalizations.front_packaging_photo_title;
case ImageField.INGREDIENTS:
return appLocalizations.ingredients_photo_title;
case ImageField.NUTRITION:
return appLocalizations.nutritional_facts_photo_title;
case ImageField.PACKAGING:
return appLocalizations.recycling_photo_title;
case ImageField.OTHER:
return appLocalizations.other_interesting_photo_title;
}
}

String getProductImageButtonText(
final AppLocalizations appLocalizations,
final ImageField imageField,
Expand Down
23 changes: 15 additions & 8 deletions packages/smooth_app/lib/pages/crop_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,26 @@ abstract class CropHelper {
/// Returns the path of the image file after the crop operation.
Future<String?> getCroppedPath(
final BuildContext context,
final String inputPath,
);
final String inputPath, {
final String? pageTitle,
});
}

/// New version of the image cropper.
class _NewCropHelper extends CropHelper {
@override
Future<String?> getCroppedPath(
final BuildContext context,
final String inputPath,
) async =>
final String inputPath, {
final String? pageTitle,
}) async =>
Navigator.push<String>(
context,
MaterialPageRoute<String>(
builder: (BuildContext context) => CropPage(File(inputPath)),
builder: (BuildContext context) => CropPage(
File(inputPath),
title: pageTitle,
),
fullscreenDialog: true,
),
);
Expand All @@ -47,8 +52,9 @@ class _OldCropHelper extends CropHelper {
@override
Future<String?> getCroppedPath(
final BuildContext context,
final String inputPath,
) async =>
final String inputPath, {
final String? pageTitle,
}) async =>
(await ImageCropper().cropImage(
sourcePath: inputPath,
aspectRatioPresets: <CropAspectRatioPreset>[
Expand All @@ -62,7 +68,8 @@ class _OldCropHelper extends CropHelper {
AndroidUiSettings(
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
toolbarTitle: AppLocalizations.of(context).product_edit_photo_title,
toolbarTitle: pageTitle ??
AppLocalizations.of(context).product_edit_photo_title,
// They all need to be the same for dark/light mode as we can't change
// the background color and the action bar color
statusBarColor: Colors.black,
Expand Down
16 changes: 12 additions & 4 deletions packages/smooth_app/lib/pages/image_crop_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:provider/provider.dart';
import 'package:smooth_app/data_models/user_preferences.dart';
import 'package:smooth_app/generic_lib/dialogs/smooth_alert_dialog.dart';
import 'package:smooth_app/helpers/camera_helper.dart';
import 'package:smooth_app/helpers/product_cards_helper.dart';
import 'package:smooth_app/pages/crop_helper.dart';
import 'package:smooth_app/pages/product/confirm_and_upload_picture.dart';

Expand Down Expand Up @@ -85,7 +86,7 @@ Future<File?> confirmAndUploadNewPicture(
required final ImageField imageField,
required final String barcode,
}) async {
final File? croppedPhoto = await startNewImageCropping(widget);
final File? croppedPhoto = await startNewImageCropping(widget, imageField);
if (croppedPhoto == null) {
return null;
}
Expand All @@ -107,19 +108,22 @@ Future<File?> confirmAndUploadNewPicture(
/// Crops an image picked from the gallery or camera.
Future<File?> startNewImageCropping(
final State<StatefulWidget> widget,
final ImageField imageField,
) async =>
_startImageCropping(widget);
_startImageCropping(widget, imageField);

/// Crops an existing image.
Future<File?> startExistingImageCropping(
final State<StatefulWidget> widget,
final ImageField imageField,
final File? existingImage,
) async =>
_startImageCropping(widget, existingImage: existingImage);
_startImageCropping(widget, imageField, existingImage: existingImage);

/// Crops an image, either existing or picked from the gallery or camera.
Future<File?> _startImageCropping(
final State<StatefulWidget> widget, {
final State<StatefulWidget> widget,
final ImageField imageField, {
final File? existingImage,
}) async {
// Show a loading page on the Flutter side
Expand Down Expand Up @@ -148,6 +152,10 @@ Future<File?> _startImageCropping(
final String? croppedPath = await cropHelper.getCroppedPath(
widget.context,
sourceImagePath,
pageTitle: getImagePageTitle(
AppLocalizations.of(widget.context),
imageField,
),
);

await _hideScreenBetween(navigator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:smooth_app/background/background_task_image.dart';
import 'package:smooth_app/data_models/continuous_scan_model.dart';
import 'package:smooth_app/database/local_database.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/helpers/product_cards_helper.dart';
import 'package:smooth_app/pages/image_crop_page.dart';
import 'package:smooth_app/widgets/smooth_scaffold.dart';

Expand Down Expand Up @@ -51,7 +52,7 @@ class _ConfirmAndUploadPictureState extends State<ConfirmAndUploadPicture> {
return SmoothScaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text(_getAppBarTitle(appLocalizations, widget.imageField)),
title: Text(getImagePageTitle(appLocalizations, widget.imageField)),
),
body: Stack(
children: <Widget>[
Expand All @@ -74,8 +75,10 @@ class _ConfirmAndUploadPictureState extends State<ConfirmAndUploadPicture> {
iconData: Icons.camera_alt,
label: appLocalizations.capture,
onPressed: () async {
final File? retakenPhoto =
await startNewImageCropping(this);
final File? retakenPhoto = await startNewImageCropping(
this,
widget.imageField,
);
if (retakenPhoto == null) {
return;
}
Expand All @@ -90,7 +93,11 @@ class _ConfirmAndUploadPictureState extends State<ConfirmAndUploadPicture> {
label: appLocalizations.edit_photo_button_label,
onPressed: () async {
final File? croppedPhoto =
await startExistingImageCropping(this, photo);
await startExistingImageCropping(
this,
widget.imageField,
photo,
);
if (croppedPhoto == null) {
return;
}
Expand Down Expand Up @@ -126,24 +133,6 @@ class _ConfirmAndUploadPictureState extends State<ConfirmAndUploadPicture> {
);
}

String _getAppBarTitle(
final AppLocalizations appLocalizations,
final ImageField imageField,
) {
switch (imageField) {
case ImageField.FRONT:
return appLocalizations.front_packaging_photo_title;
case ImageField.INGREDIENTS:
return appLocalizations.ingredients_photo_title;
case ImageField.NUTRITION:
return appLocalizations.nutritional_facts_photo_title;
case ImageField.PACKAGING:
return appLocalizations.recycling_photo_title;
case ImageField.OTHER:
return appLocalizations.other_interesting_photo_title;
}
}

Future<void> _uploadCapturedPicture({
required String barcode,
required ImageField imageField,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,8 @@ class _EditOcrPageState extends State<EditOcrPage> {
final AppLocalizations appLocalizations = AppLocalizations.of(context);
context.watch<LocalDatabase>();
_product = _localDatabase.upToDate.getLocalUpToDate(_initialProduct);
final ProductImageData productImageData = getProductImageData(
_product,
appLocalizations,
_helper.getImageField(),
);
final ProductImageData productImageData =
getProductImageData(_product, _helper.getImageField());

return SmoothScaffold(
extendBodyBehindAppBar: true,
Expand Down
Loading