-
-
Notifications
You must be signed in to change notification settings - Fork 368
feat: Added price count badges #6493
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
base: develop
Are you sure you want to change the base?
Changes from 13 commits
0018cc4
6733ba6
ab6e51d
0a85671
13fc402
5d0ce55
47b594b
a2781da
06b05d6
388b039
e178547
8304a52
f8c6f65
0618978
a9d2ceb
990b3be
ec91ea7
009560f
d94b876
6bc0b79
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import 'package:intl/intl.dart'; | |
import 'package:openfoodfacts/openfoodfacts.dart'; | ||
import 'package:smooth_app/helpers/launch_url_helper.dart'; | ||
import 'package:smooth_app/pages/prices/price_model.dart'; | ||
import 'package:smooth_app/pages/prices/prices_card.dart'; | ||
import 'package:smooth_app/pages/prices/product_price_add_page.dart'; | ||
import 'package:smooth_app/pages/product/common/product_refresher.dart'; | ||
import 'package:smooth_app/query/product_query.dart'; | ||
|
@@ -77,27 +78,40 @@ class _PriceProofPageState extends State<PriceProofPage> { | |
), | ||
], | ||
), | ||
body: Center( | ||
child: Image.network( | ||
_getUrl(false), | ||
fit: BoxFit.cover, | ||
loadingBuilder: (BuildContext context, Widget child, | ||
ImageChunkEvent? loadingProgress) { | ||
if (loadingProgress == null) { | ||
return child; | ||
} | ||
return Center( | ||
child: SizedBox( | ||
width: double.maxFinite, | ||
height: double.maxFinite, | ||
child: Image.network( | ||
_getUrl(true), | ||
fit: BoxFit.contain, | ||
), | ||
body: Stack( | ||
children: <Widget>[ | ||
Center( | ||
child: Image.network( | ||
_getUrl(false), | ||
fit: BoxFit.cover, | ||
loadingBuilder: (BuildContext context, Widget child, | ||
ImageChunkEvent? loadingProgress) { | ||
if (loadingProgress == null) { | ||
return child; | ||
} | ||
return Center( | ||
child: SizedBox( | ||
width: double.maxFinite, | ||
height: double.maxFinite, | ||
child: Image.network( | ||
_getUrl(true), | ||
fit: BoxFit.contain, | ||
), | ||
), | ||
); | ||
}, | ||
), | ||
), | ||
// Using PriceBadge component instead of custom badge | ||
if (_existingPrices != null) | ||
Positioned( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @asim-sahoo ping There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes |
||
top: 16.0, | ||
right: 16.0, | ||
child: PriceBadge( | ||
count: _existingPrices!.length, | ||
), | ||
); | ||
}, | ||
), | ||
), | ||
], | ||
), | ||
); | ||
} | ||
|
@@ -121,6 +135,7 @@ class _PriceProofPageState extends State<PriceProofPage> { | |
if (prices.isError) { | ||
return; | ||
} | ||
|
||
_existingPrices = prices.value.items ?? <Price>[]; | ||
if (mounted) { | ||
setState(() {}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,53 @@ import 'package:smooth_app/themes/smooth_theme.dart'; | |
import 'package:smooth_app/themes/smooth_theme_colors.dart'; | ||
import 'package:smooth_app/themes/theme_provider.dart'; | ||
|
||
/// Badge showing the number of prices with a payment icon | ||
class PriceBadge extends StatelessWidget { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please keep it simple and just use a If you really want to create your own widget - to be used in both proof grid and single proof pages:
|
||
const PriceBadge({ | ||
super.key, | ||
required this.count, | ||
}); | ||
|
||
final int count; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Container( | ||
padding: const EdgeInsets.all(8.0), | ||
decoration: BoxDecoration( | ||
color: Colors.blue, | ||
borderRadius: BorderRadius.circular(20.0), | ||
boxShadow: <BoxShadow>[ | ||
BoxShadow( | ||
color: Colors.black.withOpacity(0.2), | ||
blurRadius: 4.0, | ||
offset: const Offset(0, 2), | ||
), | ||
], | ||
), | ||
child: Row( | ||
mainAxisSize: MainAxisSize.min, | ||
children: <Widget>[ | ||
const Icon( | ||
Icons.payments_outlined, | ||
color: Colors.white, | ||
size: 18.0, | ||
), | ||
const SizedBox(width: 4.0), | ||
Text( | ||
'$count', | ||
style: const TextStyle( | ||
color: Colors.white, | ||
fontWeight: FontWeight.bold, | ||
fontSize: 16.0, | ||
), | ||
), | ||
], | ||
), | ||
); | ||
} | ||
} | ||
|
||
/// Card that displays buttons related to prices. | ||
class PricesCard extends StatelessWidget { | ||
const PricesCard(this.product); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,13 @@ | ||
import 'package:auto_size_text/auto_size_text.dart'; | ||
import 'dart:async'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; | ||
import 'package:intl/intl.dart'; | ||
import 'package:matomo_tracker/matomo_tracker.dart'; | ||
import 'package:openfoodfacts/openfoodfacts.dart'; | ||
import 'package:smooth_app/generic_lib/design_constants.dart'; | ||
import 'package:smooth_app/generic_lib/widgets/images/smooth_image.dart'; | ||
import 'package:smooth_app/generic_lib/widgets/smooth_back_button.dart'; | ||
import 'package:smooth_app/generic_lib/widgets/smooth_card.dart'; | ||
import 'package:smooth_app/helpers/launch_url_helper.dart'; | ||
import 'package:smooth_app/pages/prices/price_model.dart'; | ||
import 'package:smooth_app/pages/prices/price_proof_page.dart'; | ||
import 'package:smooth_app/query/product_query.dart'; | ||
import 'package:smooth_app/widgets/smooth_app_bar.dart'; | ||
|
@@ -138,9 +137,25 @@ class _PricesProofsPageState extends State<PricesProofsPage> | |
), | ||
), | ||
); | ||
}, // PriceProofPage | ||
child: _PriceProofImage(proof, | ||
squareSize: squareSize), | ||
}, | ||
child: _PriceProofImage( | ||
proof: proof, | ||
onTap: () async { | ||
if (widget.selectProof) { | ||
Navigator.of(context).pop(proof); | ||
return; | ||
} | ||
return Navigator.push<void>( | ||
context, | ||
MaterialPageRoute<void>( | ||
builder: (BuildContext context) => | ||
PriceProofPage( | ||
proof, | ||
), | ||
), | ||
); | ||
}, | ||
), | ||
); | ||
}, | ||
addAutomaticKeepAlives: false, | ||
|
@@ -192,57 +207,118 @@ class _PricesProofsPageState extends State<PricesProofsPage> | |
} | ||
} | ||
|
||
// TODO(monsieurtanuki): reuse whatever will be coded in https://github.com/openfoodfacts/smooth-app/pull/5366 | ||
class _PriceProofImage extends StatelessWidget { | ||
const _PriceProofImage( | ||
this.proof, { | ||
required this.squareSize, | ||
/// Enhanced version of PriceProofImage with price badge | ||
class _PriceProofImage extends StatefulWidget { | ||
const _PriceProofImage({ | ||
required this.proof, | ||
required this.onTap, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the point of changing the parameters? |
||
}); | ||
|
||
final Proof proof; | ||
final double squareSize; | ||
final VoidCallback onTap; | ||
|
||
@override | ||
State<_PriceProofImage> createState() => _PriceProofImageState(); | ||
} | ||
|
||
class _PriceProofImageState extends State<_PriceProofImage> { | ||
List<Price>? _prices; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
unawaited(_loadPrices()); | ||
} | ||
|
||
Future<void> _loadPrices() async { | ||
if (PriceModel.isProofNotGoodEnough(widget.proof)) { | ||
return; | ||
} | ||
final MaybeError<GetPricesResult> prices = | ||
await OpenPricesAPIClient.getPrices( | ||
GetPricesParameters()..proofId = widget.proof.id, | ||
uriHelper: ProductQuery.uriPricesHelper, | ||
); | ||
|
||
if (!mounted) { | ||
return; | ||
} | ||
|
||
if (prices.isError) { | ||
return; | ||
} | ||
|
||
_prices = prices.value.items ?? <Price>[]; | ||
if (mounted) { | ||
setState(() {}); | ||
} | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final DateFormat dateFormat = | ||
DateFormat.yMd(ProductQuery.getLocaleString()); | ||
final String date = dateFormat.format(proof.created); | ||
return Stack( | ||
children: <Widget>[ | ||
SmoothImage( | ||
width: squareSize, | ||
height: squareSize, | ||
imageProvider: NetworkImage( | ||
proof | ||
.getFileUrl( | ||
uriProductHelper: ProductQuery.uriPricesHelper, | ||
isThumbnail: true, | ||
) | ||
.toString(), | ||
return GestureDetector( | ||
onTap: widget.onTap, | ||
child: Stack( | ||
children: <Widget>[ | ||
Column( | ||
children: <Widget>[ | ||
Expanded( | ||
child: Image.network( | ||
widget.proof | ||
.getFileUrl( | ||
uriProductHelper: ProductQuery.uriPricesHelper, | ||
isThumbnail: true, | ||
) | ||
.toString(), | ||
fit: BoxFit.cover, | ||
), | ||
), | ||
Container( | ||
color: Colors.black.withOpacity(0.7), | ||
padding: const EdgeInsets.symmetric(vertical: 2.0), | ||
width: double.infinity, | ||
child: Text( | ||
dateFormat.format(widget.proof.created), | ||
textAlign: TextAlign.center, | ||
style: const TextStyle(color: Colors.white), | ||
), | ||
), | ||
], | ||
), | ||
rounded: false, | ||
), | ||
SizedBox( | ||
width: squareSize, | ||
height: squareSize, | ||
child: Align( | ||
alignment: Alignment.bottomCenter, | ||
child: Padding( | ||
padding: const EdgeInsets.all(SMALL_SPACE), | ||
if (_prices != null) | ||
Positioned( | ||
top: 8.0, | ||
right: 8.0, | ||
child: Container( | ||
height: VERY_LARGE_SPACE, | ||
color: Colors.white.withAlpha(128), | ||
width: 32.0, | ||
height: 32.0, | ||
decoration: BoxDecoration( | ||
color: Colors.blue, | ||
shape: BoxShape.circle, | ||
boxShadow: <BoxShadow>[ | ||
BoxShadow( | ||
color: Colors.black.withOpacity(0.2), | ||
blurRadius: 4.0, | ||
offset: const Offset(0, 2), | ||
), | ||
], | ||
), | ||
child: Center( | ||
child: AutoSizeText( | ||
date, | ||
maxLines: 1, | ||
child: Text( | ||
'${_prices!.length}', | ||
style: const TextStyle( | ||
color: Colors.white, | ||
fontWeight: FontWeight.bold, | ||
fontSize: 16.0, | ||
), | ||
), | ||
), | ||
), | ||
), | ||
), | ||
), | ||
], | ||
], | ||
), | ||
); | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove that file from the PR, it has nothing to do with your code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the changes were auto generated, I have reverted the changes but its still showing in the changed files. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't want to see this file here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've reverted all the changes to their original state, but they are still appearing in the changed section. Additionally, I don’t see any differences in the files so I dont know what to do. Could you please advise on how to resolve this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't want to see this file here.
Add some spaces here and here, make it as it used to be, whatever, this file doesn't belong here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reverted all the changes to their original state, but they are still appearing in the changed section. Additionally, I don’t see any differences in the files so I dont know what to do. Could you please advise on how to resolve this?