From d95078d28b3d7c758308e8f0dcfa396c239dc56d Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 5 May 2020 13:28:40 +0300 Subject: [PATCH] Add to favorites from list. --- ios/Flutter/.last_build_id | 1 + ios/Runner.xcodeproj/project.pbxproj | 3 -- lib/data/abstract/favorites_repository.dart | 5 ++- lib/data/abstract/model/product.dart | 20 +++++++++ .../repositories/product_repository_impl.dart | 42 +++++++++++++++---- .../features/favorites/favorites_bloc.dart | 4 ++ .../favorites/views/favourites_list_view.dart | 1 + .../widgets/extensions/product_view.dart | 6 +++ .../independent/base_product_list_item.dart | 2 +- 9 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 ios/Flutter/.last_build_id diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id new file mode 100644 index 00000000..6577ce3c --- /dev/null +++ b/ios/Flutter/.last_build_id @@ -0,0 +1 @@ +0e81f4131a64923bd5ca5804c4d3b13f \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 58162454..8df36347 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -307,7 +307,6 @@ /* Begin XCBuildConfiguration section */ 249021D3217E4FDB00AE95B9 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -384,7 +383,6 @@ }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -440,7 +438,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; diff --git a/lib/data/abstract/favorites_repository.dart b/lib/data/abstract/favorites_repository.dart index 2cac3a78..f5ad226d 100644 --- a/lib/data/abstract/favorites_repository.dart +++ b/lib/data/abstract/favorites_repository.dart @@ -30,7 +30,10 @@ abstract class FavoritesRepository { Product product, HashMap selectedAttributes); ///removes product with [productId] from the list of favorites - Future removeFromFavorites(int productId); + Future> removeFromFavorites(int productId); + + //check if product was added to favorite + bool checkFavorite(int productId); ///returns filter options available for favorite products. ///All rules should be set with initial (unselected) values diff --git a/lib/data/abstract/model/product.dart b/lib/data/abstract/model/product.dart index 44275081..608505e4 100644 --- a/lib/data/abstract/model/product.dart +++ b/lib/data/abstract/model/product.dart @@ -167,4 +167,24 @@ class Product extends Equatable { CommerceImage get mainImage => (images != null && images.isNotEmpty) ? images.first : CommerceImage.placeHolder(); + + Product copyWith({bool isFavorite}) { + return Product( + id, + title: title, + subTitle: subTitle, + shortDescription: description, + description: description, + price: price ?? 0, + discountPercent: discountPercent, + amountAvailable: amountAvailable, + averageRating: averageRating, + categories: categories, + hashTags: hashTags, + ratingCount: ratingCount, + images: images, + isFavorite: isFavorite ?? isFavorite, + selectableAttributes: selectableAttributes + ); + } } diff --git a/lib/data/repositories/product_repository_impl.dart b/lib/data/repositories/product_repository_impl.dart index 48cc3c3a..717f5693 100644 --- a/lib/data/repositories/product_repository_impl.dart +++ b/lib/data/repositories/product_repository_impl.dart @@ -18,7 +18,7 @@ import 'package:openflutterecommerce/locator.dart'; //Uses remote or local data depending on NetworkStatus class ProductRepositoryImpl extends ProductRepository with FavoritesRepository { - final ProductDataStorage _dataStorage = ProductDataStorage(); + static ProductDataStorage dataStorage = ProductDataStorage(); @override Future getProduct(int id) { @@ -64,9 +64,19 @@ class ProductRepositoryImpl extends ProductRepository with FavoritesRepository { productRepository = LocalProductRepository(); } - _dataStorage.products = await productRepository.getProducts(); + List products = await productRepository.getProducts(); - return _dataStorage.products; + //check favorites + dataStorage.products = []; + products.forEach( (product) =>{ + dataStorage.products.add( + product.copyWith( + isFavorite: checkFavorite(product.id) + ) + ) + }); + + return dataStorage.products; } on HttpRequestException { throw RemoteServerException(); } @@ -74,7 +84,7 @@ class ProductRepositoryImpl extends ProductRepository with FavoritesRepository { @override Future addToFavorites(Product product, HashMap selectedAttributes) async { - _dataStorage.favProducts.add(FavoriteProduct(product, selectedAttributes)); + dataStorage.favProducts.add(FavoriteProduct(product, selectedAttributes)); } @override @@ -84,19 +94,33 @@ class ProductRepositoryImpl extends ProductRepository with FavoritesRepository { /*_dataStorage.products = await getProducts(); _dataStorage.products.forEach((product) => _dataStorage.favProducts.add(FavoriteProduct(product, HashMap())));*/ - return _dataStorage.favProducts; + return dataStorage.favProducts; } @override Future getFavoritesFilterOptions() async { //TODO: remove when favorite feature will be implemented - return FilterRules.getSelectableAttributes(_dataStorage.products); + return FilterRules.getSelectableAttributes(dataStorage.products); + } + + @override + Future> removeFromFavorites(int productId) async { + //TODO: remove from database in the future + dataStorage.favProducts.removeWhere((product) => product.product.id == productId); + return dataStorage.favProducts; } @override - Future removeFromFavorites(int productId) { - // TODO: implement removeFromFavorites - return null; + bool checkFavorite(int productId) { + // TODO: implement checkFavorite + bool isFavorite = false; + for( int i = 0; i < dataStorage.favProducts.length; i++) { + if ( dataStorage.favProducts[i].product.id == productId) { + isFavorite = true; + break; + } + } + return isFavorite; } } diff --git a/lib/presentation/features/favorites/favorites_bloc.dart b/lib/presentation/features/favorites/favorites_bloc.dart index bcfe321d..e6ae8933 100644 --- a/lib/presentation/features/favorites/favorites_bloc.dart +++ b/lib/presentation/features/favorites/favorites_bloc.dart @@ -44,6 +44,10 @@ class FavouriteBloc extends Bloc { yield state.copyWith(filterRules: event.filterRules, data: filteredData); } else if (event is AddToCartEvent) { //TODO add to cart + } else if ( event is RemoveFromFavoriteEvent ) { + yield state.getLoading(); + final filteredData = await favoritesRepository.removeFromFavorites(event.productId); + yield state.copyWith(data: filteredData); } } } diff --git a/lib/presentation/features/favorites/views/favourites_list_view.dart b/lib/presentation/features/favorites/views/favourites_list_view.dart index 89a07785..d424a5ce 100644 --- a/lib/presentation/features/favorites/views/favourites_list_view.dart +++ b/lib/presentation/features/favorites/views/favourites_list_view.dart @@ -52,6 +52,7 @@ class FavoritesListView extends StatelessWidget { )); } }, + childCount: state.data?.length ), ); }); diff --git a/lib/presentation/widgets/extensions/product_view.dart b/lib/presentation/widgets/extensions/product_view.dart index de227423..c234dfda 100644 --- a/lib/presentation/widgets/extensions/product_view.dart +++ b/lib/presentation/widgets/extensions/product_view.dart @@ -141,6 +141,9 @@ extension FavoriteView on FavoriteProduct { ? null : 'Sorry, this item is currently sold out', bottomRoundButton: FloatingActionButton( + heroTag: 'Remove from Cart' +Random() + .nextInt(1000000) + .toString(), backgroundColor: AppColors.red, onPressed: onAddToCart, child: Icon( @@ -192,6 +195,9 @@ extension FavoriteView on FavoriteProduct { ? null : 'Sorry, this item is currently sold out', bottomRoundButton: FloatingActionButton( + heroTag: 'Add to Cart' + Random() + .nextInt(1000000) + .toString(), backgroundColor: AppColors.red, onPressed: onAddToCart, child: Icon( diff --git a/lib/presentation/widgets/independent/base_product_list_item.dart b/lib/presentation/widgets/independent/base_product_list_item.dart index a26db3ae..dad04cf5 100644 --- a/lib/presentation/widgets/independent/base_product_list_item.dart +++ b/lib/presentation/widgets/independent/base_product_list_item.dart @@ -29,7 +29,7 @@ class BaseProductListItem extends StatelessWidget { Widget build(BuildContext context) { return Container( width: MediaQuery.of(context).size.width, - height: imageHeight + 20, + height: imageHeight + 30, padding: EdgeInsets.symmetric(horizontal: AppSizes.widgetSidePadding / 2), child: Opacity( opacity: inactiveMessage == null ? 1 : 0.6,