mirror of
https://github.com/openfoodfacts/smooth-app.git
synced 2025-08-26 20:50:18 +08:00
fix: 5576 - first step towards multi product types (#5593)
Impacted files: * `add_basic_details_page.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `background_task.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `background_task_download_products.dart`: saved new field `Product.productType` * `dao_product.dart`: now we're storing the `Product.productType` field * `edit_new_packagings.dart`: now using new field `Product.productType` * `edit_new_packagings_component.dart`: now using new field `Product.productType` * `edit_product_page.dart`: specific icon for "food" categories; no nutrition for "beauty" and "product" * `forgot_password_page.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `lazy_counter.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `login_result.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `newsfeed_provider.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `ocr_ingredients_helper.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `ocr_packaging_helper.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `onboarding_data_product.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `ordered_nutrients_cache.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `paged_product_query.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `product_cards_helper.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `product_image_crop_button.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `product_image_gallery_other_view.dart`: now using new field `Product.productType` * `product_image_other_page.dart`: now using new field `Product.productType` * `product_image_server_button.dart`: now using new field `Product.productType` * `product_image_widget.dart`: now using new field `Product.productType` * `product_list_page.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `product_query.dart`: now when we look for a barcode (or refresh a product), we use all productTypes if needed * `product_refresher.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `pubspec.lock`: wtf * `pubspec.yaml`: upgraded `openfoodfacts` to `3.15.0` for new `Product.productType` field * `sign_up_page.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `simple_input_page_helpers.dart`: new class dedicated to non-food categories * `simple_input_text_field.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `simple_input_widget.dart`: now using new field `Product.productType` * `temp_product_list_share_helper.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper` * `uploaded_image_gallery.dart`: now using new field `Product.productType` * `user_preferences_dev_debug_info.dart`: replaced getter `ProductQuery.uriProductHelper` with method `ProductQuery.getUriProductHelper`
This commit is contained in:
@ -183,7 +183,7 @@ abstract class BackgroundTask {
|
|||||||
|
|
||||||
// TODO(monsieurtanuki): store the uriProductHelper as well
|
// TODO(monsieurtanuki): store the uriProductHelper as well
|
||||||
@protected
|
@protected
|
||||||
UriProductHelper get uriProductHelper => ProductQuery.uriProductHelper;
|
UriProductHelper get uriProductHelper => ProductQuery.getUriProductHelper();
|
||||||
|
|
||||||
/// Returns true if tasks with the same stamp would overwrite each-other.
|
/// Returns true if tasks with the same stamp would overwrite each-other.
|
||||||
bool isDeduplicable() => true;
|
bool isDeduplicable() => true;
|
||||||
|
@ -133,9 +133,15 @@ class BackgroundTaskDownloadProducts extends BackgroundTaskProgressing {
|
|||||||
throw Exception('Something bad happened downloading products');
|
throw Exception('Something bad happened downloading products');
|
||||||
}
|
}
|
||||||
final DaoProduct daoProduct = DaoProduct(localDatabase);
|
final DaoProduct daoProduct = DaoProduct(localDatabase);
|
||||||
|
final ProductType? productType =
|
||||||
|
ProductQuery.extractProductType(uriProductHelper);
|
||||||
for (final Product product in downloadedProducts) {
|
for (final Product product in downloadedProducts) {
|
||||||
if (await _shouldBeUpdated(daoProduct, product.barcode!)) {
|
if (await _shouldBeUpdated(daoProduct, product.barcode!)) {
|
||||||
await daoProduct.put(product, language);
|
await daoProduct.put(
|
||||||
|
product,
|
||||||
|
language,
|
||||||
|
productType: productType,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final int deleted = await daoWorkBarcode.deleteBarcodes(work, barcodes);
|
final int deleted = await daoWorkBarcode.deleteBarcodes(work, barcodes);
|
||||||
|
@ -38,7 +38,7 @@ class LoginResult {
|
|||||||
try {
|
try {
|
||||||
final LoginStatus? loginStatus = await OpenFoodAPIClient.login2(
|
final LoginStatus? loginStatus = await OpenFoodAPIClient.login2(
|
||||||
user,
|
user,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(),
|
||||||
);
|
);
|
||||||
if (loginStatus == null) {
|
if (loginStatus == null) {
|
||||||
return const LoginResult(LoginResultType.serverIssue);
|
return const LoginResult(LoginResultType.serverIssue);
|
||||||
|
@ -106,7 +106,8 @@ class AppNewsProvider extends ChangeNotifier {
|
|||||||
/// or [https://world.openfoodfacts.[org/net]/resources/files/tagline-off-android-v3.json]
|
/// or [https://world.openfoodfacts.[org/net]/resources/files/tagline-off-android-v3.json]
|
||||||
Future<String?> _fetchJSON() async {
|
Future<String?> _fetchJSON() async {
|
||||||
try {
|
try {
|
||||||
final UriProductHelper uriProductHelper = ProductQuery.uriProductHelper;
|
final UriProductHelper uriProductHelper =
|
||||||
|
ProductQuery.getUriProductHelper();
|
||||||
final Map<String, String> headers = <String, String>{};
|
final Map<String, String> headers = <String, String>{};
|
||||||
final Uri uri;
|
final Uri uri;
|
||||||
|
|
||||||
|
@ -40,7 +40,9 @@ class OnboardingDataProduct extends AbstractOnboardingData<Product> {
|
|||||||
AbstractOnboardingData.barcode,
|
AbstractOnboardingData.barcode,
|
||||||
ProductQuery.getLanguage(),
|
ProductQuery.getLanguage(),
|
||||||
),
|
),
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: ProductType.food,
|
||||||
|
),
|
||||||
).timeout(SnackBarDuration.long);
|
).timeout(SnackBarDuration.long);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -94,25 +94,34 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
|||||||
|
|
||||||
Future<void> put(
|
Future<void> put(
|
||||||
final Product product,
|
final Product product,
|
||||||
final OpenFoodFactsLanguage language,
|
final OpenFoodFactsLanguage language, {
|
||||||
) async =>
|
final ProductType? productType,
|
||||||
|
}) async =>
|
||||||
putAll(
|
putAll(
|
||||||
<Product>[product],
|
<Product>[product],
|
||||||
language,
|
language,
|
||||||
|
productType: productType,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Replaces products in database
|
/// Replaces products in database
|
||||||
Future<void> putAll(
|
Future<void> putAll(
|
||||||
final Iterable<Product> products,
|
final Iterable<Product> products,
|
||||||
final OpenFoodFactsLanguage language,
|
final OpenFoodFactsLanguage language, {
|
||||||
) async =>
|
final ProductType? productType,
|
||||||
localDatabase.database.transaction(
|
}) async {
|
||||||
|
if (productType != null) {
|
||||||
|
for (final Product product in products) {
|
||||||
|
product.productType = productType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await localDatabase.database.transaction(
|
||||||
(final Transaction transaction) async => _bulkReplaceLoop(
|
(final Transaction transaction) async => _bulkReplaceLoop(
|
||||||
transaction,
|
transaction,
|
||||||
products,
|
products,
|
||||||
language,
|
language,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<String>> getAllKeys() async {
|
Future<List<String>> getAllKeys() async {
|
||||||
final List<String> result = <String>[];
|
final List<String> result = <String>[];
|
||||||
|
@ -271,7 +271,9 @@ ProductImageData getProductImageData(
|
|||||||
imageUrl: productImage.getUrl(
|
imageUrl: productImage.getUrl(
|
||||||
product.barcode!,
|
product.barcode!,
|
||||||
imageSize: ImageSize.DISPLAY,
|
imageSize: ImageSize.DISPLAY,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: product.productType,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
language: language,
|
language: language,
|
||||||
);
|
);
|
||||||
|
@ -6,7 +6,7 @@ Uri shareProductList(List<String> barcodes) {
|
|||||||
final String barcodesString = barcodes.join(',');
|
final String barcodesString = barcodes.join(',');
|
||||||
|
|
||||||
return UriHelper.replaceSubdomain(
|
return UriHelper.replaceSubdomain(
|
||||||
ProductQuery.uriProductHelper.getUri(
|
ProductQuery.getUriProductHelper().getUri(
|
||||||
path: 'products/$barcodesString',
|
path: 'products/$barcodesString',
|
||||||
addUserAgentParameters: false,
|
addUserAgentParameters: false,
|
||||||
),
|
),
|
||||||
|
@ -148,6 +148,7 @@ class _RawGridGallery extends StatelessWidget {
|
|||||||
squareSize: squareSize,
|
squareSize: squareSize,
|
||||||
imageSize: imageSize,
|
imageSize: imageSize,
|
||||||
heroTag: heroTag,
|
heroTag: heroTag,
|
||||||
|
productType: product.productType,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -66,6 +66,7 @@ class _ProductImageOtherPageState extends State<ProductImageOtherPage> {
|
|||||||
barcode: widget.product.barcode!,
|
barcode: widget.product.barcode!,
|
||||||
heroTag:
|
heroTag:
|
||||||
widget.currentImage == image ? widget.heroTag : null,
|
widget.currentImage == image ? widget.heroTag : null,
|
||||||
|
productType: widget.product.productType,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
).toList(growable: false),
|
).toList(growable: false),
|
||||||
@ -89,11 +90,13 @@ class _ProductImageViewer extends StatelessWidget {
|
|||||||
required this.image,
|
required this.image,
|
||||||
required this.barcode,
|
required this.barcode,
|
||||||
this.heroTag,
|
this.heroTag,
|
||||||
|
required this.productType,
|
||||||
});
|
});
|
||||||
|
|
||||||
final ProductImage image;
|
final ProductImage image;
|
||||||
final String barcode;
|
final String barcode;
|
||||||
final String? heroTag;
|
final String? heroTag;
|
||||||
|
final ProductType? productType;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -111,7 +114,9 @@ class _ProductImageViewer extends StatelessWidget {
|
|||||||
image: NetworkImage(
|
image: NetworkImage(
|
||||||
image.getUrl(
|
image.getUrl(
|
||||||
barcode,
|
barcode,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: productType,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
@ -153,6 +158,7 @@ class _ProductImageViewer extends StatelessWidget {
|
|||||||
_ProductImageDetailsButton(
|
_ProductImageDetailsButton(
|
||||||
image: image,
|
image: image,
|
||||||
barcode: barcode,
|
barcode: barcode,
|
||||||
|
productType: productType,
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
if (image.expired) _ProductImageOutdatedLabel(colors: colors),
|
if (image.expired) _ProductImageOutdatedLabel(colors: colors),
|
||||||
@ -211,10 +217,12 @@ class _ProductImageDetailsButton extends StatelessWidget {
|
|||||||
const _ProductImageDetailsButton({
|
const _ProductImageDetailsButton({
|
||||||
required this.image,
|
required this.image,
|
||||||
required this.barcode,
|
required this.barcode,
|
||||||
|
required this.productType,
|
||||||
});
|
});
|
||||||
|
|
||||||
final ProductImage image;
|
final ProductImage image;
|
||||||
final String barcode;
|
final String barcode;
|
||||||
|
final ProductType? productType;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -222,7 +230,9 @@ class _ProductImageDetailsButton extends StatelessWidget {
|
|||||||
final String url = image.url ??
|
final String url = image.url ??
|
||||||
image.getUrl(
|
image.getUrl(
|
||||||
barcode,
|
barcode,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: productType,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return DecoratedBox(
|
return DecoratedBox(
|
||||||
|
@ -17,6 +17,7 @@ class ProductImageWidget extends StatelessWidget {
|
|||||||
required this.productImage,
|
required this.productImage,
|
||||||
required this.barcode,
|
required this.barcode,
|
||||||
required this.squareSize,
|
required this.squareSize,
|
||||||
|
required this.productType,
|
||||||
this.imageSize,
|
this.imageSize,
|
||||||
this.heroTag,
|
this.heroTag,
|
||||||
});
|
});
|
||||||
@ -25,6 +26,7 @@ class ProductImageWidget extends StatelessWidget {
|
|||||||
final String barcode;
|
final String barcode;
|
||||||
final double squareSize;
|
final double squareSize;
|
||||||
final String? heroTag;
|
final String? heroTag;
|
||||||
|
final ProductType? productType;
|
||||||
|
|
||||||
/// Allows to fetch the optimized version of the image
|
/// Allows to fetch the optimized version of the image
|
||||||
final ImageSize? imageSize;
|
final ImageSize? imageSize;
|
||||||
@ -45,7 +47,9 @@ class ProductImageWidget extends StatelessWidget {
|
|||||||
imageProvider: NetworkImage(
|
imageProvider: NetworkImage(
|
||||||
productImage.getUrl(
|
productImage.getUrl(
|
||||||
barcode,
|
barcode,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: productType,
|
||||||
|
),
|
||||||
imageSize: imageSize,
|
imageSize: imageSize,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -25,12 +25,14 @@ class UploadedImageGallery extends StatelessWidget {
|
|||||||
required this.imageField,
|
required this.imageField,
|
||||||
required this.language,
|
required this.language,
|
||||||
required this.isLoggedInMandatory,
|
required this.isLoggedInMandatory,
|
||||||
|
required this.productType,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String barcode;
|
final String barcode;
|
||||||
final List<ProductImage> rawImages;
|
final List<ProductImage> rawImages;
|
||||||
final ImageField imageField;
|
final ImageField imageField;
|
||||||
final bool isLoggedInMandatory;
|
final bool isLoggedInMandatory;
|
||||||
|
final ProductType? productType;
|
||||||
|
|
||||||
/// Language for which we'll save the cropped image.
|
/// Language for which we'll save the cropped image.
|
||||||
final OpenFoodFactsLanguage language;
|
final OpenFoodFactsLanguage language;
|
||||||
@ -70,7 +72,9 @@ class UploadedImageGallery extends StatelessWidget {
|
|||||||
rawImage.getUrl(
|
rawImage.getUrl(
|
||||||
barcode,
|
barcode,
|
||||||
imageSize: ImageSize.ORIGINAL,
|
imageSize: ImageSize.ORIGINAL,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: productType,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
DaoInt(localDatabase),
|
DaoInt(localDatabase),
|
||||||
);
|
);
|
||||||
@ -102,6 +106,7 @@ class UploadedImageGallery extends StatelessWidget {
|
|||||||
productImage: rawImage,
|
productImage: rawImage,
|
||||||
barcode: barcode,
|
barcode: barcode,
|
||||||
squareSize: columnWidth,
|
squareSize: columnWidth,
|
||||||
|
productType: productType,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -79,7 +79,7 @@ class LazyCounterUserSearch extends LazyCounter {
|
|||||||
final SearchResult result = await OpenFoodAPIClient.searchProducts(
|
final SearchResult result = await OpenFoodAPIClient.searchProducts(
|
||||||
user,
|
user,
|
||||||
configuration,
|
configuration,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(),
|
||||||
);
|
);
|
||||||
return result.count;
|
return result.count;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -27,10 +27,10 @@ class _UserPreferencesDebugInfoState extends State<UserPreferencesDebugInfo> {
|
|||||||
'IsLoggedIn': ProductQuery.isLoggedIn().toString(),
|
'IsLoggedIn': ProductQuery.isLoggedIn().toString(),
|
||||||
'UUID': OpenFoodAPIConfiguration.uuid.toString(),
|
'UUID': OpenFoodAPIConfiguration.uuid.toString(),
|
||||||
'Matomo Visitor ID': AnalyticsHelper.matomoVisitorId,
|
'Matomo Visitor ID': AnalyticsHelper.matomoVisitorId,
|
||||||
'QueryType': ProductQuery.uriProductHelper.isTestMode
|
'QueryType': ProductQuery.getUriProductHelper().isTestMode
|
||||||
? 'QueryType.TEST'
|
? 'QueryType.TEST'
|
||||||
: 'QueryType.PROD',
|
: 'QueryType.PROD',
|
||||||
'Domain': ProductQuery.uriProductHelper.domain,
|
'Domain': ProductQuery.getUriProductHelper().domain,
|
||||||
'UserAgent-name': '${OpenFoodAPIConfiguration.userAgent?.name}',
|
'UserAgent-name': '${OpenFoodAPIConfiguration.userAgent?.name}',
|
||||||
'UserAgent-system': '${OpenFoodAPIConfiguration.userAgent?.system}',
|
'UserAgent-system': '${OpenFoodAPIConfiguration.userAgent?.system}',
|
||||||
};
|
};
|
||||||
|
@ -207,7 +207,9 @@ class _AddBasicDetailsPageState extends State<AddBasicDetailsPage> {
|
|||||||
user: ProductQuery.getReadUser(),
|
user: ProductQuery.getReadUser(),
|
||||||
limit: 25,
|
limit: 25,
|
||||||
fuzziness: Fuzziness.none,
|
fuzziness: Fuzziness.none,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: widget.product.productType,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -450,7 +450,7 @@ class _ProductListPageState extends State<ProductListPage>
|
|||||||
barcodes,
|
barcodes,
|
||||||
language,
|
language,
|
||||||
),
|
),
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(),
|
||||||
);
|
);
|
||||||
final List<Product>? freshProducts = searchResult.products;
|
final List<Product>? freshProducts = searchResult.products;
|
||||||
if (freshProducts == null) {
|
if (freshProducts == null) {
|
||||||
|
@ -153,6 +153,36 @@ class ProductRefresher {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the product type stored locally for that product.
|
||||||
|
static Future<ProductType?> getCurrentProductType({
|
||||||
|
required final LocalDatabase localDatabase,
|
||||||
|
required final String barcode,
|
||||||
|
}) async {
|
||||||
|
final Product? localProduct = await DaoProduct(localDatabase).get(barcode);
|
||||||
|
return localProduct?.productType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the list of types to use for that barcode.
|
||||||
|
Future<List<ProductType>> getOrderedProductTypes({
|
||||||
|
required final LocalDatabase localDatabase,
|
||||||
|
required final String barcode,
|
||||||
|
}) async {
|
||||||
|
final List<ProductType> result = <ProductType>[];
|
||||||
|
final ProductType? productType = await getCurrentProductType(
|
||||||
|
localDatabase: localDatabase,
|
||||||
|
barcode: barcode,
|
||||||
|
);
|
||||||
|
if (productType != null) {
|
||||||
|
result.add(productType);
|
||||||
|
}
|
||||||
|
for (final ProductType value in ProductType.values) {
|
||||||
|
if (!result.contains(value)) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// Fetches the product from the server and refreshes the local database.
|
/// Fetches the product from the server and refreshes the local database.
|
||||||
///
|
///
|
||||||
/// Silent version.
|
/// Silent version.
|
||||||
@ -160,21 +190,35 @@ class ProductRefresher {
|
|||||||
required final LocalDatabase localDatabase,
|
required final LocalDatabase localDatabase,
|
||||||
required final String barcode,
|
required final String barcode,
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
final List<ProductType> productTypes = await getOrderedProductTypes(
|
||||||
|
localDatabase: localDatabase,
|
||||||
|
barcode: barcode,
|
||||||
|
);
|
||||||
|
late UriProductHelper uriProductHelper;
|
||||||
final OpenFoodFactsLanguage language = ProductQuery.getLanguage();
|
final OpenFoodFactsLanguage language = ProductQuery.getLanguage();
|
||||||
|
try {
|
||||||
|
for (final ProductType productType in productTypes) {
|
||||||
|
uriProductHelper = ProductQuery.getUriProductHelper(
|
||||||
|
productType: productType,
|
||||||
|
);
|
||||||
final ProductResultV3 result = await OpenFoodAPIClient.getProductV3(
|
final ProductResultV3 result = await OpenFoodAPIClient.getProductV3(
|
||||||
getBarcodeQueryConfiguration(
|
getBarcodeQueryConfiguration(
|
||||||
barcode,
|
barcode,
|
||||||
language,
|
language,
|
||||||
),
|
),
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: uriProductHelper,
|
||||||
user: ProductQuery.getReadUser(),
|
user: ProductQuery.getReadUser(),
|
||||||
);
|
);
|
||||||
if (result.product != null) {
|
if (result.product != null) {
|
||||||
await DaoProduct(localDatabase).put(result.product!, language);
|
await DaoProduct(localDatabase).put(
|
||||||
|
result.product!,
|
||||||
|
language,
|
||||||
|
productType: productType,
|
||||||
|
);
|
||||||
localDatabase.upToDate.setLatestDownloadedProduct(result.product!);
|
localDatabase.upToDate.setLatestDownloadedProduct(result.product!);
|
||||||
return FetchedProduct.found(result.product!);
|
return FetchedProduct.found(result.product!);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return const FetchedProduct.internetNotFound();
|
return const FetchedProduct.internetNotFound();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logs.e('Refresh from server error', ex: e);
|
Logs.e('Refresh from server error', ex: e);
|
||||||
@ -186,7 +230,7 @@ class ProductRefresher {
|
|||||||
isConnected: false,
|
isConnected: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final String host = ProductQuery.uriProductHelper.host;
|
final String host = uriProductHelper.host;
|
||||||
final PingData result = await Ping(host, count: 1).stream.first;
|
final PingData result = await Ping(host, count: 1).stream.first;
|
||||||
return FetchedProduct.error(
|
return FetchedProduct.error(
|
||||||
exceptionString: e.toString(),
|
exceptionString: e.toString(),
|
||||||
@ -208,7 +252,7 @@ class ProductRefresher {
|
|||||||
final SearchResult searchResult = await OpenFoodAPIClient.searchProducts(
|
final SearchResult searchResult = await OpenFoodAPIClient.searchProducts(
|
||||||
ProductQuery.getReadUser(),
|
ProductQuery.getReadUser(),
|
||||||
getBarcodeListQueryConfiguration(barcodes, language),
|
getBarcodeListQueryConfiguration(barcodes, language),
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(),
|
||||||
);
|
);
|
||||||
if (searchResult.products == null) {
|
if (searchResult.products == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -117,6 +117,7 @@ class _EditNewPackagingsState extends State<EditNewPackagings>
|
|||||||
setState(() => _removePackagingAt(deleteIndex)),
|
setState(() => _removePackagingAt(deleteIndex)),
|
||||||
helper: _helpers[index],
|
helper: _helpers[index],
|
||||||
categories: upToDateProduct.categories,
|
categories: upToDateProduct.categories,
|
||||||
|
productType: upToDateProduct.productType,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -17,12 +17,14 @@ class EditNewPackagingsComponent extends StatefulWidget {
|
|||||||
required this.deleteCallback,
|
required this.deleteCallback,
|
||||||
required this.helper,
|
required this.helper,
|
||||||
required this.categories,
|
required this.categories,
|
||||||
|
required this.productType,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
final VoidCallback deleteCallback;
|
final VoidCallback deleteCallback;
|
||||||
final EditNewPackagingsHelper helper;
|
final EditNewPackagingsHelper helper;
|
||||||
final String? categories;
|
final String? categories;
|
||||||
|
final ProductType? productType;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<EditNewPackagingsComponent> createState() =>
|
State<EditNewPackagingsComponent> createState() =>
|
||||||
@ -58,6 +60,7 @@ class _EditNewPackagingsComponentState
|
|||||||
iconColor: iconColor,
|
iconColor: iconColor,
|
||||||
minLengthForSuggestions: 0,
|
minLengthForSuggestions: 0,
|
||||||
categories: widget.categories,
|
categories: widget.categories,
|
||||||
|
productType: widget.productType,
|
||||||
),
|
),
|
||||||
_EditTextLine(
|
_EditTextLine(
|
||||||
title: appLocalizations.edit_packagings_element_field_material,
|
title: appLocalizations.edit_packagings_element_field_material,
|
||||||
@ -69,6 +72,7 @@ class _EditNewPackagingsComponentState
|
|||||||
minLengthForSuggestions: 0,
|
minLengthForSuggestions: 0,
|
||||||
categories: widget.categories,
|
categories: widget.categories,
|
||||||
shapeProvider: () => widget.helper.controllerShape.text,
|
shapeProvider: () => widget.helper.controllerShape.text,
|
||||||
|
productType: widget.productType,
|
||||||
),
|
),
|
||||||
_EditTextLine(
|
_EditTextLine(
|
||||||
title: appLocalizations.edit_packagings_element_field_recycling,
|
title: appLocalizations.edit_packagings_element_field_recycling,
|
||||||
@ -76,12 +80,14 @@ class _EditNewPackagingsComponentState
|
|||||||
tagType: TagType.PACKAGING_RECYCLING,
|
tagType: TagType.PACKAGING_RECYCLING,
|
||||||
iconName: 'recycling',
|
iconName: 'recycling',
|
||||||
iconColor: iconColor,
|
iconColor: iconColor,
|
||||||
|
productType: widget.productType,
|
||||||
),
|
),
|
||||||
_EditTextLine(
|
_EditTextLine(
|
||||||
title: appLocalizations.edit_packagings_element_field_quantity,
|
title: appLocalizations.edit_packagings_element_field_quantity,
|
||||||
controller: widget.helper.controllerQuantity,
|
controller: widget.helper.controllerQuantity,
|
||||||
iconName: 'quantity',
|
iconName: 'quantity',
|
||||||
iconColor: iconColor,
|
iconColor: iconColor,
|
||||||
|
productType: widget.productType,
|
||||||
),
|
),
|
||||||
_EditNumberLine(
|
_EditNumberLine(
|
||||||
title: appLocalizations.edit_packagings_element_field_weight,
|
title: appLocalizations.edit_packagings_element_field_weight,
|
||||||
@ -133,6 +139,7 @@ class _EditTextLine extends StatefulWidget {
|
|||||||
this.minLengthForSuggestions = 1,
|
this.minLengthForSuggestions = 1,
|
||||||
this.categories,
|
this.categories,
|
||||||
this.shapeProvider,
|
this.shapeProvider,
|
||||||
|
required this.productType,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
@ -144,6 +151,7 @@ class _EditTextLine extends StatefulWidget {
|
|||||||
final int minLengthForSuggestions;
|
final int minLengthForSuggestions;
|
||||||
final String? categories;
|
final String? categories;
|
||||||
final String? Function()? shapeProvider;
|
final String? Function()? shapeProvider;
|
||||||
|
final ProductType? productType;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_EditTextLine> createState() => _EditTextLineState();
|
State<_EditTextLine> createState() => _EditTextLineState();
|
||||||
@ -195,6 +203,7 @@ class _EditTextLineState extends State<_EditTextLine> {
|
|||||||
minLengthForSuggestions: widget.minLengthForSuggestions,
|
minLengthForSuggestions: widget.minLengthForSuggestions,
|
||||||
categories: widget.categories,
|
categories: widget.categories,
|
||||||
shapeProvider: widget.shapeProvider,
|
shapeProvider: widget.shapeProvider,
|
||||||
|
productType: widget.productType,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -90,7 +90,9 @@ class OcrIngredientsHelper extends OcrHelper {
|
|||||||
getUser(),
|
getUser(),
|
||||||
product.barcode!,
|
product.barcode!,
|
||||||
language,
|
language,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: product.productType,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return result.ingredientsTextFromImage;
|
return result.ingredientsTextFromImage;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,9 @@ class OcrPackagingHelper extends OcrHelper {
|
|||||||
getUser(),
|
getUser(),
|
||||||
product.barcode!,
|
product.barcode!,
|
||||||
language,
|
language,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: product.productType,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return result.textFromImage;
|
return result.textFromImage;
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,13 @@ class _EditProductPageState extends State<EditProductPage> with UpToDateMixin {
|
|||||||
product: upToDateProduct,
|
product: upToDateProduct,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_getSimpleListTileItem(SimpleInputPageCategoryHelper()),
|
if (upToDateProduct.productType == null ||
|
||||||
|
upToDateProduct.productType == ProductType.food)
|
||||||
|
_getSimpleListTileItem(SimpleInputPageCategoryHelper())
|
||||||
|
else
|
||||||
|
_getSimpleListTileItem(SimpleInputPageCategoryNotFoodHelper()),
|
||||||
|
if (upToDateProduct.productType != ProductType.beauty &&
|
||||||
|
upToDateProduct.productType != ProductType.product)
|
||||||
_ListTitleItem(
|
_ListTitleItem(
|
||||||
leading:
|
leading:
|
||||||
const SvgIcon('assets/cacheTintable/scale-balance.svg'),
|
const SvgIcon('assets/cacheTintable/scale-balance.svg'),
|
||||||
|
@ -59,7 +59,7 @@ class OrderedNutrientsCache {
|
|||||||
final String string = await OpenFoodAPIClient.getOrderedNutrientsJsonString(
|
final String string = await OpenFoodAPIClient.getOrderedNutrientsJsonString(
|
||||||
country: ProductQuery.getCountry(),
|
country: ProductQuery.getCountry(),
|
||||||
language: ProductQuery.getLanguage(),
|
language: ProductQuery.getLanguage(),
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(),
|
||||||
);
|
);
|
||||||
final OrderedNutrients result = OrderedNutrients.fromJson(
|
final OrderedNutrients result = OrderedNutrients.fromJson(
|
||||||
jsonDecode(string) as Map<String, dynamic>,
|
jsonDecode(string) as Map<String, dynamic>,
|
||||||
@ -75,6 +75,6 @@ class OrderedNutrientsCache {
|
|||||||
return 'nutrients.pl'
|
return 'nutrients.pl'
|
||||||
'/${country.offTag}'
|
'/${country.offTag}'
|
||||||
'/${language.code}'
|
'/${language.code}'
|
||||||
'/${ProductQuery.uriProductHelper.domain}';
|
'/${ProductQuery.getUriProductHelper().domain}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,12 @@ class ProductImageCropButton extends ProductImageButton {
|
|||||||
if (productImage != null) {
|
if (productImage != null) {
|
||||||
final int? imageId = int.tryParse(productImage.imgid!);
|
final int? imageId = int.tryParse(productImage.imgid!);
|
||||||
if (imageId != null) {
|
if (imageId != null) {
|
||||||
await _openCropAgainPage(context, imageId, productImage);
|
await _openCropAgainPage(
|
||||||
|
context,
|
||||||
|
imageId,
|
||||||
|
productImage,
|
||||||
|
product.productType,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,6 +89,7 @@ class ProductImageCropButton extends ProductImageButton {
|
|||||||
final BuildContext context,
|
final BuildContext context,
|
||||||
final int imageId,
|
final int imageId,
|
||||||
final ProductImage productImage,
|
final ProductImage productImage,
|
||||||
|
final ProductType? productType,
|
||||||
) async {
|
) async {
|
||||||
final NavigatorState navigatorState = Navigator.of(context);
|
final NavigatorState navigatorState = Navigator.of(context);
|
||||||
final LocalDatabase localDatabase = context.read<LocalDatabase>();
|
final LocalDatabase localDatabase = context.read<LocalDatabase>();
|
||||||
@ -94,7 +100,9 @@ class ProductImageCropButton extends ProductImageButton {
|
|||||||
size: ImageSize.ORIGINAL,
|
size: ImageSize.ORIGINAL,
|
||||||
).getUrl(
|
).getUrl(
|
||||||
barcode,
|
barcode,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: productType,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
DaoInt(localDatabase),
|
DaoInt(localDatabase),
|
||||||
);
|
);
|
||||||
|
@ -51,7 +51,11 @@ class ProductImageServerButton extends ProductImageButton {
|
|||||||
ImageSize.DISPLAY,
|
ImageSize.DISPLAY,
|
||||||
);
|
);
|
||||||
if (rawImages.isNotEmpty) {
|
if (rawImages.isNotEmpty) {
|
||||||
await _openGallery(context: context, rawImages: rawImages);
|
await _openGallery(
|
||||||
|
context: context,
|
||||||
|
rawImages: rawImages,
|
||||||
|
productType: product.productType,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,12 +99,17 @@ class ProductImageServerButton extends ProductImageButton {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await _openGallery(context: context, rawImages: rawImages);
|
await _openGallery(
|
||||||
|
context: context,
|
||||||
|
rawImages: rawImages,
|
||||||
|
productType: product.productType,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _openGallery({
|
Future<void> _openGallery({
|
||||||
required final BuildContext context,
|
required final BuildContext context,
|
||||||
required final List<ProductImage> rawImages,
|
required final List<ProductImage> rawImages,
|
||||||
|
required final ProductType? productType,
|
||||||
}) =>
|
}) =>
|
||||||
Navigator.push<void>(
|
Navigator.push<void>(
|
||||||
context,
|
context,
|
||||||
@ -111,6 +120,7 @@ class ProductImageServerButton extends ProductImageButton {
|
|||||||
imageField: imageField,
|
imageField: imageField,
|
||||||
language: language,
|
language: language,
|
||||||
isLoggedInMandatory: isLoggedInMandatory,
|
isLoggedInMandatory: isLoggedInMandatory,
|
||||||
|
productType: productType,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -445,6 +445,12 @@ class SimpleInputPageCategoryHelper extends AbstractSimpleInputPageHelper {
|
|||||||
AnalyticsEditEvents getAnalyticsEditEvent() => AnalyticsEditEvents.categories;
|
AnalyticsEditEvents getAnalyticsEditEvent() => AnalyticsEditEvents.categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SimpleInputPageCategoryNotFoodHelper
|
||||||
|
extends SimpleInputPageCategoryHelper {
|
||||||
|
@override
|
||||||
|
Widget getIcon() => const Icon(Icons.edit);
|
||||||
|
}
|
||||||
|
|
||||||
/// Implementation for "Countries" of an [AbstractSimpleInputPageHelper].
|
/// Implementation for "Countries" of an [AbstractSimpleInputPageHelper].
|
||||||
class SimpleInputPageCountryHelper extends AbstractSimpleInputPageHelper {
|
class SimpleInputPageCountryHelper extends AbstractSimpleInputPageHelper {
|
||||||
@override
|
@override
|
||||||
|
@ -18,6 +18,7 @@ class SimpleInputTextField extends StatefulWidget {
|
|||||||
this.categories,
|
this.categories,
|
||||||
this.shapeProvider,
|
this.shapeProvider,
|
||||||
this.padding,
|
this.padding,
|
||||||
|
required this.productType,
|
||||||
});
|
});
|
||||||
|
|
||||||
final FocusNode focusNode;
|
final FocusNode focusNode;
|
||||||
@ -31,6 +32,7 @@ class SimpleInputTextField extends StatefulWidget {
|
|||||||
final String? categories;
|
final String? categories;
|
||||||
final String? Function()? shapeProvider;
|
final String? Function()? shapeProvider;
|
||||||
final EdgeInsetsGeometry? padding;
|
final EdgeInsetsGeometry? padding;
|
||||||
|
final ProductType? productType;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SimpleInputTextField> createState() => _SimpleInputTextFieldState();
|
State<SimpleInputTextField> createState() => _SimpleInputTextFieldState();
|
||||||
@ -54,7 +56,9 @@ class _SimpleInputTextFieldState extends State<SimpleInputTextField> {
|
|||||||
user: ProductQuery.getReadUser(),
|
user: ProductQuery.getReadUser(),
|
||||||
// number of suggestions the user can scroll through: compromise between quantity and readability of the suggestions
|
// number of suggestions the user can scroll through: compromise between quantity and readability of the suggestions
|
||||||
limit: 15,
|
limit: 15,
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(
|
||||||
|
productType: widget.productType,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,7 @@ class _SimpleInputWidgetState extends State<SimpleInputWidget> {
|
|||||||
padding: const EdgeInsetsDirectional.only(
|
padding: const EdgeInsetsDirectional.only(
|
||||||
start: 9.0,
|
start: 9.0,
|
||||||
),
|
),
|
||||||
|
productType: widget.product.productType,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tooltip(
|
Tooltip(
|
||||||
|
@ -37,7 +37,7 @@ class _ForgotPasswordPageState extends State<ForgotPasswordPage>
|
|||||||
_userIdController.text,
|
_userIdController.text,
|
||||||
country: ProductQuery.getCountry(),
|
country: ProductQuery.getCountry(),
|
||||||
language: ProductQuery.getLanguage(),
|
language: ProductQuery.getLanguage(),
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(),
|
||||||
);
|
);
|
||||||
if (status.status == 200) {
|
if (status.status == 200) {
|
||||||
_send = true;
|
_send = true;
|
||||||
|
@ -336,7 +336,7 @@ class _SignUpPageState extends State<SignUpPage> with TraceableClientMixin {
|
|||||||
orgName: _foodProducer ? _brandController.trimmedText : null,
|
orgName: _foodProducer ? _brandController.trimmedText : null,
|
||||||
country: ProductQuery.getCountry(),
|
country: ProductQuery.getCountry(),
|
||||||
language: ProductQuery.getLanguage(),
|
language: ProductQuery.getLanguage(),
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(),
|
||||||
),
|
),
|
||||||
title: appLocalisations.sign_up_page_action_doing_it,
|
title: appLocalisations.sign_up_page_action_doing_it,
|
||||||
);
|
);
|
||||||
|
@ -38,7 +38,7 @@ abstract class PagedProductQuery {
|
|||||||
OpenFoodAPIClient.searchProducts(
|
OpenFoodAPIClient.searchProducts(
|
||||||
ProductQuery.getReadUser(),
|
ProductQuery.getReadUser(),
|
||||||
getQueryConfiguration(),
|
getQueryConfiguration(),
|
||||||
uriHelper: ProductQuery.uriProductHelper,
|
uriHelper: ProductQuery.getUriProductHelper(),
|
||||||
);
|
);
|
||||||
|
|
||||||
AbstractQueryConfiguration getQueryConfiguration();
|
AbstractQueryConfiguration getQueryConfiguration();
|
||||||
|
@ -164,7 +164,7 @@ abstract class ProductQuery {
|
|||||||
comment: 'Test user for project smoothie',
|
comment: 'Test user for project smoothie',
|
||||||
);
|
);
|
||||||
|
|
||||||
static late UriProductHelper uriProductHelper;
|
static late UriProductHelper _uriProductHelper;
|
||||||
|
|
||||||
/// Product helper only for prices.
|
/// Product helper only for prices.
|
||||||
static late UriProductHelper uriPricesHelper;
|
static late UriProductHelper uriPricesHelper;
|
||||||
@ -178,7 +178,7 @@ abstract class ProductQuery {
|
|||||||
? uriHelperFoodProd
|
? uriHelperFoodProd
|
||||||
: getTestUriProductHelper(userPreferences);
|
: getTestUriProductHelper(userPreferences);
|
||||||
|
|
||||||
uriProductHelper = getProductHelper(
|
_uriProductHelper = getProductHelper(
|
||||||
UserPreferencesDevMode.userPreferencesFlagProd,
|
UserPreferencesDevMode.userPreferencesFlagProd,
|
||||||
);
|
);
|
||||||
uriPricesHelper = getProductHelper(
|
uriPricesHelper = getProductHelper(
|
||||||
@ -201,6 +201,42 @@ abstract class ProductQuery {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ProductType? extractProductType(
|
||||||
|
final UriProductHelper uriProductHelper,
|
||||||
|
) {
|
||||||
|
final String domain = uriProductHelper.domain;
|
||||||
|
for (final ProductType productType in ProductType.values) {
|
||||||
|
if (domain.contains(productType.getDomain())) {
|
||||||
|
return productType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(monsieurtanuki): make the parameter "required"
|
||||||
|
static UriProductHelper getUriProductHelper({
|
||||||
|
final ProductType? productType,
|
||||||
|
}) {
|
||||||
|
final UriProductHelper currentUriProductHelper = _uriProductHelper;
|
||||||
|
if (productType == null) {
|
||||||
|
return currentUriProductHelper;
|
||||||
|
}
|
||||||
|
final ProductType? currentProductType =
|
||||||
|
extractProductType(currentUriProductHelper);
|
||||||
|
if (currentProductType == null) {
|
||||||
|
return currentUriProductHelper;
|
||||||
|
}
|
||||||
|
if (currentProductType == productType) {
|
||||||
|
return currentUriProductHelper;
|
||||||
|
}
|
||||||
|
return UriProductHelper(
|
||||||
|
domain: currentUriProductHelper.domain.replaceFirst(
|
||||||
|
currentProductType.getDomain(),
|
||||||
|
productType.getDomain(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static List<ProductField> get fields => const <ProductField>[
|
static List<ProductField> get fields => const <ProductField>[
|
||||||
ProductField.NAME,
|
ProductField.NAME,
|
||||||
ProductField.NAME_ALL_LANGUAGES,
|
ProductField.NAME_ALL_LANGUAGES,
|
||||||
@ -255,3 +291,12 @@ abstract class ProductQuery {
|
|||||||
ProductField.OWNER_FIELDS,
|
ProductField.OWNER_FIELDS,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension ProductTypeExtension on ProductType {
|
||||||
|
String getDomain() => switch (this) {
|
||||||
|
ProductType.food => 'openfoodfacts',
|
||||||
|
ProductType.beauty => 'openbeautyfacts',
|
||||||
|
ProductType.petFood => 'openpetfoodfacts',
|
||||||
|
ProductType.product => 'openproductsfacts',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -964,18 +964,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.5"
|
version: "10.0.4"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.5"
|
version: "3.0.3"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1028,10 +1028,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.1"
|
version: "0.8.0"
|
||||||
matomo_tracker:
|
matomo_tracker:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1044,10 +1044,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0"
|
version: "1.12.0"
|
||||||
mgrs_dart:
|
mgrs_dart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1269,10 +1269,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
|
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.5"
|
version: "3.1.4"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -1599,10 +1599,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.2"
|
version: "0.7.0"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1743,10 +1743,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.2.5"
|
version: "14.2.1"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
Reference in New Issue
Block a user