-
-
Notifications
You must be signed in to change notification settings - Fork 280
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: 5554 - display of cached counts on user page (#5573)
New files: * `lazy_counter.dart`: Lazy Counter, with a cached value stored locally, and a call to the server. * `lazy_counter_widget.dart`: Widget displaying a Lazy Counter: cached value, refresh button, and loading. Impacted files: * `user_preferences.dart`: added methods about storing a lazy count value * `user_preferences_account.dart`: refactored the display of counts with the new `LazyCounter` and `LazyCounterWidget` classes
- Loading branch information
1 parent
51b2277
commit 74660f8
Showing
4 changed files
with
194 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
packages/smooth_app/lib/pages/preferences/lazy_counter.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import 'package:flutter/foundation.dart'; | ||
import 'package:openfoodfacts/openfoodfacts.dart'; | ||
import 'package:smooth_app/data_models/preferences/user_preferences.dart'; | ||
import 'package:smooth_app/query/paged_user_product_query.dart'; | ||
import 'package:smooth_app/query/product_query.dart'; | ||
import 'package:smooth_app/services/smooth_services.dart'; | ||
|
||
/// Lazy Counter, with a cached value stored locally, and a call to the server. | ||
abstract class LazyCounter { | ||
const LazyCounter(); | ||
|
||
/// Returns the value cached locally; | ||
int? getLocalCount(final UserPreferences userPreferences) => | ||
userPreferences.getLazyCount(getSuffixTag()); | ||
|
||
/// Sets the value cached locally; | ||
Future<void> setLocalCount( | ||
final int value, | ||
final UserPreferences userPreferences, | ||
) => | ||
userPreferences.setLazyCount(value, getSuffixTag()); | ||
|
||
/// Returns the suffix tag used to cache the value locally; | ||
@protected | ||
String getSuffixTag(); | ||
|
||
/// Gets the latest value from the server. | ||
Future<int?> getServerCount(); | ||
} | ||
|
||
/// Lazy Counter dedicated to Prices counts. | ||
class LazyCounterPrices extends LazyCounter { | ||
const LazyCounterPrices(this.owner); | ||
|
||
final String? owner; | ||
|
||
@override | ||
String getSuffixTag() => 'P_$owner'; | ||
|
||
@override | ||
Future<int?> getServerCount() async { | ||
final MaybeError<GetPricesResult> result = | ||
await OpenPricesAPIClient.getPrices( | ||
GetPricesParameters() | ||
..owner = owner | ||
..pageSize = 1, | ||
uriHelper: ProductQuery.uriPricesHelper, | ||
); | ||
if (result.isError) { | ||
return null; | ||
} | ||
return result.value.total; | ||
} | ||
} | ||
|
||
/// Lazy Counter dedicated to OFF User Search counts. | ||
class LazyCounterUserSearch extends LazyCounter { | ||
const LazyCounterUserSearch(this.type); | ||
|
||
final UserSearchType type; | ||
|
||
@override | ||
String getSuffixTag() => 'US_$type'; | ||
|
||
@override | ||
Future<int?> getServerCount() async { | ||
final User user = ProductQuery.getWriteUser(); | ||
final ProductSearchQueryConfiguration configuration = type.getConfiguration( | ||
user.userId, | ||
1, | ||
1, | ||
ProductQuery.getLanguage(), | ||
// one field is enough as we want only the count | ||
// and we need at least one field (no field meaning all fields) | ||
<ProductField>[ProductField.BARCODE], | ||
); | ||
|
||
try { | ||
final SearchResult result = await OpenFoodAPIClient.searchProducts( | ||
user, | ||
configuration, | ||
uriHelper: ProductQuery.uriProductHelper, | ||
); | ||
return result.count; | ||
} catch (e) { | ||
Logs.e( | ||
'Could not count the number of products for $type, ${user.userId}', | ||
ex: e, | ||
); | ||
return null; | ||
} | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
packages/smooth_app/lib/pages/preferences/lazy_counter_widget.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:provider/provider.dart'; | ||
import 'package:smooth_app/data_models/preferences/user_preferences.dart'; | ||
import 'package:smooth_app/pages/preferences/lazy_counter.dart'; | ||
|
||
/// Widget displaying a Lazy Counter: cached value, refresh button, and loading. | ||
class LazyCounterWidget extends StatefulWidget { | ||
const LazyCounterWidget(this.lazyCounter); | ||
|
||
final LazyCounter lazyCounter; | ||
|
||
@override | ||
State<LazyCounterWidget> createState() => _LazyCounterWidgetState(); | ||
} | ||
|
||
class _LazyCounterWidgetState extends State<LazyCounterWidget> { | ||
bool _loading = false; | ||
int? _count; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
final UserPreferences userPreferences = context.read<UserPreferences>(); | ||
_count = widget.lazyCounter.getLocalCount(userPreferences); | ||
if (_count == null) { | ||
_asyncLoad(); | ||
} | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) => Row( | ||
mainAxisSize: MainAxisSize.min, | ||
mainAxisAlignment: MainAxisAlignment.end, | ||
crossAxisAlignment: CrossAxisAlignment.center, | ||
children: <Widget>[ | ||
if (_count != null) Text(_count.toString()), | ||
if (_loading) | ||
const Padding( | ||
padding: EdgeInsets.symmetric(horizontal: 12), | ||
child: SizedBox( | ||
width: 24, | ||
height: 24, | ||
child: CircularProgressIndicator.adaptive(), | ||
), | ||
) | ||
else | ||
IconButton( | ||
onPressed: () => _asyncLoad(), | ||
icon: const Icon(Icons.refresh), | ||
), | ||
], | ||
); | ||
|
||
Future<void> _asyncLoad() async { | ||
if (_loading) { | ||
return; | ||
} | ||
_loading = true; | ||
final UserPreferences userPreferences = context.read<UserPreferences>(); | ||
if (mounted) { | ||
setState(() {}); | ||
} | ||
try { | ||
final int? value = await widget.lazyCounter.getServerCount(); | ||
if (value != null) { | ||
await widget.lazyCounter.setLocalCount(value, userPreferences); | ||
_count = value; | ||
} | ||
} catch (e) { | ||
// | ||
} finally { | ||
_loading = false; | ||
if (mounted) { | ||
setState(() {}); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters