forked from openfoodfacts/smooth-app
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: 4301 - new "up-to-date" provider for product list
New files: * `up_to_date_interest.dart`: Management of the interest for a key. * `up_to_date_product_list_mixin.dart`: Provides the most up-to-date local product list data for a StatefulWidget. * `up_to_date_product_list_provider.dart`: Provider that reflects the latest barcode lists on ProductLists. Impacted files: * `dao_product_list.dart`: made public method `getKey`; refreshes the provider * `local_database.dart`: added a new `UpToDateProductListProvider` * `product_list_page.dart`: now extends `UpToDateProductListMixin * `up_to_date_product_provider.dart`: refactored using a `UpToDateInterest` * `user_preferences_account.dart`: removed redundant access to product list page
- Loading branch information
1 parent
1cd22a6
commit e199713
Showing
8 changed files
with
183 additions
and
74 deletions.
There are no files selected for viewing
28 changes: 28 additions & 0 deletions
28
packages/smooth_app/lib/data_models/up_to_date_interest.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,28 @@ | ||
/// Management of the interest for a key. | ||
class UpToDateInterest { | ||
/// Number of time an interest was shown for a given key. | ||
final Map<String, int> _interestCounts = <String, int>{}; | ||
|
||
/// Shows an interest for a key. | ||
void add(final String key) { | ||
final int result = (_interestCounts[key] ?? 0) + 1; | ||
_interestCounts[key] = result; | ||
} | ||
|
||
/// Loses an interest for a key. | ||
/// | ||
/// Returns true if completely lost interest. | ||
bool remove(final String key) { | ||
final int result = (_interestCounts[key] ?? 0) - 1; | ||
if (result <= 0) { | ||
_interestCounts.remove(key); | ||
return true; | ||
} | ||
_interestCounts[key] = result; | ||
return false; | ||
} | ||
|
||
bool get isEmpty => _interestCounts.isEmpty; | ||
|
||
bool containsKey(final String key) => _interestCounts.containsKey(key); | ||
} |
55 changes: 55 additions & 0 deletions
55
packages/smooth_app/lib/data_models/up_to_date_product_list_mixin.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,55 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:smooth_app/data_models/product_list.dart'; | ||
import 'package:smooth_app/database/dao_product_list.dart'; | ||
import 'package:smooth_app/database/local_database.dart'; | ||
|
||
/// Provides the most up-to-date local product list data for a StatefulWidget. | ||
@optionalTypeArgs | ||
mixin UpToDateProductListMixin<T extends StatefulWidget> on State<T> { | ||
/// To be used in the `initState` method. | ||
void initUpToDate( | ||
final ProductList initialProductList, | ||
final LocalDatabase localDatabase, | ||
) { | ||
_productList = initialProductList; | ||
_localDatabase = localDatabase; | ||
_localDatabase.upToDateProductList.showInterest(initialProductList); | ||
_localDatabase.upToDateProductList.setLocalUpToDate( | ||
DaoProductList.getKey(_productList), | ||
_productList.barcodes, | ||
); | ||
} | ||
|
||
late final LocalDatabase _localDatabase; | ||
|
||
late ProductList _productList; | ||
|
||
ProductList get productList => _productList; | ||
|
||
set productList(final ProductList productList) { | ||
final ProductList previous = _productList; | ||
_productList = productList; | ||
_localDatabase.upToDateProductList.showInterest(_productList); | ||
_localDatabase.upToDateProductList.loseInterest(previous); | ||
_localDatabase.upToDateProductList.setLocalUpToDate( | ||
DaoProductList.getKey(_productList), | ||
_productList.barcodes, | ||
); | ||
} | ||
|
||
@override | ||
void dispose() { | ||
_localDatabase.upToDateProductList.loseInterest(_productList); | ||
super.dispose(); | ||
} | ||
|
||
/// Refreshes [upToDateProduct] with the latest available local data. | ||
/// | ||
/// To be used in the `build` method, after a call to | ||
/// `context.watch<LocalDatabase>()`. | ||
void refreshUpToDate() { | ||
final List<String> barcodes = | ||
_localDatabase.upToDateProductList.getLocalUpToDate(_productList); | ||
_productList.set(barcodes); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
packages/smooth_app/lib/data_models/up_to_date_product_list_provider.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,54 @@ | ||
import 'package:smooth_app/data_models/product_list.dart'; | ||
import 'package:smooth_app/data_models/up_to_date_interest.dart'; | ||
import 'package:smooth_app/database/dao_product_list.dart'; | ||
import 'package:smooth_app/database/local_database.dart'; | ||
|
||
/// Provider that reflects the latest barcode lists on [ProductList]s. | ||
class UpToDateProductListProvider { | ||
UpToDateProductListProvider(this.localDatabase); | ||
|
||
final LocalDatabase localDatabase; | ||
|
||
/// Product lists currently displayed in the app. | ||
/// | ||
/// We need to know which product lists are "interesting" because we need to | ||
/// cache barcode lists in memory for instant access. And we should cache only | ||
/// them, because we cannot cache all product lists in memory. | ||
final UpToDateInterest _interest = UpToDateInterest(); | ||
|
||
final Map<String, List<String>> _barcodes = <String, List<String>>{}; | ||
|
||
/// Shows an interest for a product list. | ||
/// | ||
/// Typically, to be used by a widget in `initState`. | ||
void showInterest(final ProductList productList) => | ||
_interest.add(_getKey(productList)); | ||
|
||
/// Loses interest for a product list. | ||
/// | ||
/// Typically, to be used by a widget in `dispose`. | ||
void loseInterest(final ProductList productList) { | ||
final String key = _getKey(productList); | ||
if (!_interest.remove(key)) { | ||
return; | ||
} | ||
_barcodes.remove(key); | ||
} | ||
|
||
String _getKey(final ProductList productList) => | ||
DaoProductList.getKey(productList); | ||
|
||
void setLocalUpToDate( | ||
final String key, | ||
final List<String> barcodes, | ||
) { | ||
if (!_interest.containsKey(key)) { | ||
return; | ||
} | ||
_barcodes[key] = List<String>.from(barcodes); // need to copy | ||
} | ||
|
||
/// Returns the latest barcodes. | ||
List<String> getLocalUpToDate(final ProductList productList) => | ||
_barcodes[_getKey(productList)] ?? <String>[]; | ||
} |
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
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
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
Oops, something went wrong.