|
| 1 | +import 'dart:async'; |
1 | 2 | import 'dart:math'; |
2 | 3 |
|
3 | 4 | import 'package:flutter/cupertino.dart'; |
4 | 5 | import 'package:flutter/material.dart'; |
5 | 6 | import 'package:flutter_gen/gen_l10n/app_localizations.dart'; |
6 | 7 | import 'package:openfoodfacts/openfoodfacts.dart'; |
| 8 | +import 'package:provider/provider.dart'; |
| 9 | +import 'package:smooth_app/data_models/preferences/user_preferences.dart'; |
| 10 | +import 'package:smooth_app/database/local_database.dart'; |
7 | 11 | import 'package:smooth_app/generic_lib/buttons/smooth_large_button_with_icon.dart'; |
8 | 12 | import 'package:smooth_app/generic_lib/design_constants.dart'; |
9 | 13 | import 'package:smooth_app/helpers/product_cards_helper.dart'; |
10 | 14 | import 'package:smooth_app/pages/prices/get_prices_model.dart'; |
11 | 15 | import 'package:smooth_app/pages/prices/price_meta_product.dart'; |
12 | 16 | import 'package:smooth_app/pages/prices/prices_page.dart'; |
13 | 17 | import 'package:smooth_app/pages/prices/product_price_add_page.dart'; |
14 | | -import 'package:smooth_app/query/product_query.dart'; |
| 18 | +import 'package:smooth_app/pages/prices/product_price_refresher.dart'; |
15 | 19 | import 'package:smooth_app/resources/app_icons.dart' as icons; |
16 | 20 | import 'package:smooth_app/themes/smooth_theme.dart'; |
17 | 21 | import 'package:smooth_app/themes/smooth_theme_colors.dart'; |
@@ -130,67 +134,64 @@ class _PricesCardViewButton extends StatefulWidget { |
130 | 134 | } |
131 | 135 |
|
132 | 136 | class _PricesCardViewButtonState extends State<_PricesCardViewButton> { |
133 | | - late final GetPricesModel _model; |
134 | | - late final Future<MaybeError<GetPricesResult>> _prices = _showProductPrices(); |
| 137 | + GetPricesModel? _model; |
| 138 | + ProductPriceRefresher? _productPriceRefresher; |
135 | 139 |
|
136 | 140 | @override |
137 | | - Widget build(BuildContext context) => |
138 | | - FutureBuilder<MaybeError<GetPricesResult>>( |
139 | | - future: _prices, |
140 | | - builder: ( |
141 | | - final BuildContext context, |
142 | | - final AsyncSnapshot<MaybeError<GetPricesResult>> snapshot, |
143 | | - ) { |
144 | | - final AppLocalizations appLocalizations = |
145 | | - AppLocalizations.of(context); |
146 | | - GetPricesResult? pricesResult; |
147 | | - if (snapshot.hasData && !snapshot.data!.isError) { |
148 | | - pricesResult = snapshot.data!.value; |
149 | | - } |
150 | | - return Badge( |
151 | | - offset: Offset.zero, |
152 | | - isLabelVisible: pricesResult?.total != null, |
153 | | - backgroundColor: |
154 | | - context.extension<SmoothColorsThemeExtension>().secondaryNormal, |
155 | | - label: Padding( |
156 | | - padding: const EdgeInsetsDirectional.only( |
157 | | - start: VERY_SMALL_SPACE, |
158 | | - end: VERY_SMALL_SPACE, |
159 | | - top: VERY_SMALL_SPACE, |
160 | | - bottom: 6.0, |
161 | | - ), |
162 | | - child: Text( |
163 | | - '${pricesResult?.total}', |
164 | | - style: const TextStyle( |
165 | | - color: Colors.white, |
166 | | - fontWeight: FontWeight.bold, |
167 | | - ), |
168 | | - ), |
169 | | - ), |
170 | | - child: SmoothLargeButtonWithIcon( |
171 | | - text: appLocalizations.prices_view_prices, |
172 | | - leadingIcon: const Icon(CupertinoIcons.tag_fill), |
173 | | - onPressed: () async => Navigator.of(context).push( |
174 | | - MaterialPageRoute<void>( |
175 | | - builder: (BuildContext context) => PricesPage( |
176 | | - _model, |
177 | | - pricesResult: pricesResult, |
178 | | - ), |
179 | | - ), |
180 | | - ), |
181 | | - ), |
182 | | - ); |
183 | | - }, |
184 | | - ); |
| 141 | + Widget build(BuildContext context) { |
| 142 | + final AppLocalizations appLocalizations = AppLocalizations.of(context); |
185 | 143 |
|
186 | | - Future<MaybeError<GetPricesResult>> _showProductPrices() async { |
187 | | - _model = GetPricesModel.product( |
| 144 | + _model ??= GetPricesModel.product( |
188 | 145 | product: PriceMetaProduct.product(widget.product), |
189 | 146 | context: context, |
190 | 147 | ); |
191 | | - return OpenPricesAPIClient.getPrices( |
192 | | - _model.parameters, |
193 | | - uriHelper: ProductQuery.uriPricesHelper, |
| 148 | + _productPriceRefresher ??= ProductPriceRefresher( |
| 149 | + model: _model!, |
| 150 | + userPreferences: context.read<UserPreferences>(), |
| 151 | + pricesResult: null, |
| 152 | + refreshDisplay: () { |
| 153 | + if (mounted) { |
| 154 | + setState(() {}); |
| 155 | + } |
| 156 | + }, |
| 157 | + ); |
| 158 | + |
| 159 | + context.watch<LocalDatabase>(); |
| 160 | + unawaited(_productPriceRefresher!.runIfNeeded()); |
| 161 | + |
| 162 | + final int? total = _productPriceRefresher!.pricesResult?.total; |
| 163 | + return Badge( |
| 164 | + offset: Offset.zero, |
| 165 | + isLabelVisible: total != null, |
| 166 | + backgroundColor: |
| 167 | + context.extension<SmoothColorsThemeExtension>().secondaryNormal, |
| 168 | + label: Padding( |
| 169 | + padding: const EdgeInsetsDirectional.only( |
| 170 | + start: VERY_SMALL_SPACE, |
| 171 | + end: VERY_SMALL_SPACE, |
| 172 | + top: VERY_SMALL_SPACE, |
| 173 | + bottom: 6.0, |
| 174 | + ), |
| 175 | + child: Text( |
| 176 | + '$total', |
| 177 | + style: const TextStyle( |
| 178 | + color: Colors.white, |
| 179 | + fontWeight: FontWeight.bold, |
| 180 | + ), |
| 181 | + ), |
| 182 | + ), |
| 183 | + child: SmoothLargeButtonWithIcon( |
| 184 | + text: appLocalizations.prices_view_prices, |
| 185 | + leadingIcon: const Icon(CupertinoIcons.tag_fill), |
| 186 | + onPressed: () async => Navigator.of(context).push( |
| 187 | + MaterialPageRoute<void>( |
| 188 | + builder: (BuildContext context) => PricesPage( |
| 189 | + _model!, |
| 190 | + pricesResult: _productPriceRefresher!.pricesResult, |
| 191 | + ), |
| 192 | + ), |
| 193 | + ), |
| 194 | + ), |
194 | 195 | ); |
195 | 196 | } |
196 | 197 | } |
0 commit comments