add favorite

This commit is contained in:
Phuoc Nguyen
2025-11-18 11:23:07 +07:00
parent 192c322816
commit a5eb95fa64
25 changed files with 2506 additions and 978 deletions

View File

@@ -1,148 +1,141 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:worker/features/favorites/data/datasources/favorites_local_datasource.dart';
import 'package:worker/features/favorites/data/models/favorite_model.dart';
import 'package:worker/core/network/dio_client.dart';
import 'package:worker/core/network/network_info.dart';
import 'package:worker/features/favorites/data/datasources/favorite_products_local_datasource.dart';
import 'package:worker/features/favorites/data/datasources/favorites_remote_datasource.dart';
import 'package:worker/features/favorites/data/repositories/favorites_repository_impl.dart';
import 'package:worker/features/favorites/domain/repositories/favorites_repository.dart';
import 'package:worker/features/products/domain/entities/product.dart';
import 'package:worker/features/products/domain/usecases/get_products.dart';
import 'package:worker/features/products/presentation/providers/products_provider.dart';
part 'favorites_provider.g.dart';
// ============================================================================
// DATASOURCE PROVIDER
// DATASOURCE PROVIDERS
// ============================================================================
/// Provides instance of FavoritesLocalDataSource
/// Provides instance of FavoritesRemoteDataSource
@riverpod
FavoritesLocalDataSource favoritesLocalDataSource(Ref ref) {
return FavoritesLocalDataSource();
Future<FavoritesRemoteDataSource> favoritesRemoteDataSource(Ref ref) async {
final dioClient = await ref.watch(dioClientProvider.future);
return FavoritesRemoteDataSource(dioClient.dio);
}
/// Provides instance of FavoriteProductsLocalDataSource
@riverpod
FavoriteProductsLocalDataSource favoriteProductsLocalDataSource(Ref ref) {
return FavoriteProductsLocalDataSource();
}
// ============================================================================
// CURRENT USER ID PROVIDER
// REPOSITORY PROVIDER
// ============================================================================
/// Provides the current logged-in user's ID
///
/// TODO: Replace with actual auth provider integration
/// For now, using hardcoded userId for development
/// Provides instance of FavoritesRepository with online-first approach
@riverpod
String currentUserId(Ref ref) {
// TODO: Integrate with actual auth provider when available
// Example: return ref.watch(authProvider).user?.id ?? 'user_001';
return 'user_001';
Future<FavoritesRepository> favoritesRepository(Ref ref) async {
final remoteDataSource = await ref.watch(favoritesRemoteDataSourceProvider.future);
final productsLocalDataSource = ref.watch(favoriteProductsLocalDataSourceProvider);
final networkInfo = ref.watch(networkInfoProvider);
return FavoritesRepositoryImpl(
remoteDataSource: remoteDataSource,
productsLocalDataSource: productsLocalDataSource,
networkInfo: networkInfo,
);
}
// ============================================================================
// MAIN FAVORITES PROVIDER
// MAIN FAVORITE PRODUCTS PROVIDER
// ============================================================================
/// Manages the favorites state for the current user
/// Manages favorite products with full Product data from wishlist API
///
/// Uses a Set<String> to store product IDs for efficient lookup.
/// Data is persisted to Hive for offline access.
@riverpod
class Favorites extends _$Favorites {
late FavoritesLocalDataSource _dataSource;
late String _userId;
/// This is the MAIN provider for the favorites feature.
/// Returns full Product objects with all data from the wishlist API.
///
/// Online-first: Fetches from API, caches locally
/// Offline: Returns cached products
///
/// Uses keepAlive to prevent unnecessary reloads.
/// Provides refresh() method for pull-to-refresh functionality.
///
/// AsyncNotifier pattern allows:
/// - Manual refresh capability
/// - Proper loading states during operations
/// - State updates after mutations
/// - Better error handling
@Riverpod(keepAlive: true)
class FavoriteProducts extends _$FavoriteProducts {
late FavoritesRepository _repository;
@override
Future<Set<String>> build() async {
_dataSource = ref.read(favoritesLocalDataSourceProvider);
_userId = ref.read(currentUserIdProvider);
// Load favorites from Hive
return await _loadFavorites();
Future<List<Product>> build() async {
_repository = await ref.read(favoritesRepositoryProvider.future);
return await _loadProducts();
}
// ==========================================================================
// PRIVATE METHODS
// ==========================================================================
/// Load favorites from Hive database
Future<Set<String>> _loadFavorites() async {
/// Load favorite products from repository
///
/// Online-first: Fetches from API, caches locally
/// Falls back to local cache on network failure
Future<List<Product>> _loadProducts() async {
try {
final favorites = await _dataSource.getAllFavorites(_userId);
final productIds = favorites.map((fav) => fav.productId).toSet();
debugPrint('Loaded ${productIds.length} favorites for user: $_userId');
return productIds;
final products = await _repository.getFavoriteProducts();
_debugPrint('Loaded ${products.length} favorite products');
return products;
} catch (e) {
debugPrint('Error loading favorites: $e');
return {};
_debugPrint('Error loading favorite products: $e');
rethrow;
}
}
/// Generate a unique favorite ID
String _generateFavoriteId(String productId) {
// Using format: userId_productId_timestamp
final timestamp = DateTime.now().millisecondsSinceEpoch;
return '${_userId}_${productId}_$timestamp';
}
// ==========================================================================
// PUBLIC METHODS
// ==========================================================================
/// Add a product to favorites
///
/// Creates a new favorite entry and persists it to Hive.
/// If the product is already favorited, this operation is a no-op.
/// Calls API to add to wishlist, then refreshes the products list.
/// No userId needed - the API uses the authenticated session.
Future<void> addFavorite(String productId) async {
try {
// Check if already favorited
final currentState = state.value ?? <String>{};
if (currentState.contains(productId)) {
debugPrint('Product $productId is already favorited');
return;
}
_debugPrint('Adding product to favorites: $productId');
// Create favorite model
final favorite = FavoriteModel(
favoriteId: _generateFavoriteId(productId),
productId: productId,
userId: _userId,
createdAt: DateTime.now(),
);
// Call repository to add to favorites (uses auth token from session)
await _repository.addFavorite(productId);
// Persist to Hive
await _dataSource.addFavorite(favorite);
// Refresh the products list after successful addition
await refresh();
// Update state
final newState = <String>{...currentState, productId};
state = AsyncValue.data(newState);
debugPrint('Added favorite: $productId');
} catch (e, stackTrace) {
debugPrint('Error adding favorite: $e');
state = AsyncValue.error(e, stackTrace);
_debugPrint('Successfully added favorite: $productId');
} catch (e) {
_debugPrint('Error adding favorite: $e');
rethrow;
}
}
/// Remove a product from favorites
///
/// Removes the favorite entry from Hive.
/// If the product is not favorited, this operation is a no-op.
/// Calls API to remove from wishlist, then refreshes the products list.
/// No userId needed - the API uses the authenticated session.
Future<void> removeFavorite(String productId) async {
try {
// Check if favorited
final currentState = state.value ?? <String>{};
if (!currentState.contains(productId)) {
debugPrint('Product $productId is not favorited');
return;
}
_debugPrint('Removing product from favorites: $productId');
// Remove from Hive
await _dataSource.removeFavorite(productId, _userId);
// Call repository to remove from favorites (uses auth token from session)
await _repository.removeFavorite(productId);
// Update state
final newState = <String>{...currentState};
newState.remove(productId);
state = AsyncValue.data(newState);
// Refresh the products list after successful removal
await refresh();
debugPrint('Removed favorite: $productId');
} catch (e, stackTrace) {
debugPrint('Error removing favorite: $e');
state = AsyncValue.error(e, stackTrace);
_debugPrint('Successfully removed favorite: $productId');
} catch (e) {
_debugPrint('Error removing favorite: $e');
rethrow;
}
}
@@ -151,38 +144,26 @@ class Favorites extends _$Favorites {
/// If the product is favorited, it will be removed.
/// If the product is not favorited, it will be added.
Future<void> toggleFavorite(String productId) async {
final currentState = state.value ?? <String>{};
final currentProducts = state.value ?? [];
final isFavorited = currentProducts.any((p) => p.productId == productId);
if (currentState.contains(productId)) {
if (isFavorited) {
await removeFavorite(productId);
} else {
await addFavorite(productId);
}
}
/// Refresh favorites from database
/// Refresh favorite products from API
///
/// Useful for syncing state after external changes or on app resume.
/// Used for pull-to-refresh functionality.
/// Fetches latest data from API and updates cache.
Future<void> refresh() async {
state = const AsyncValue.loading();
state = await AsyncValue.guard(() async {
return await _loadFavorites();
return await _loadProducts();
});
}
/// Clear all favorites for the current user
///
/// Removes all favorite entries from Hive.
Future<void> clearAll() async {
try {
await _dataSource.clearFavorites(_userId);
state = const AsyncValue.data({});
debugPrint('Cleared all favorites for user: $_userId');
} catch (e, stackTrace) {
debugPrint('Error clearing favorites: $e');
state = AsyncValue.error(e, stackTrace);
}
}
}
// ============================================================================
@@ -191,14 +172,15 @@ class Favorites extends _$Favorites {
/// Check if a specific product is favorited
///
/// Derived from the favorite products list.
/// Returns true if the product is in the user's favorites, false otherwise.
/// Safe to use in build methods - will return false during loading/error states.
@riverpod
bool isFavorite(Ref ref, String productId) {
final favoritesAsync = ref.watch(favoritesProvider);
final favoriteProductsAsync = ref.watch(favoriteProductsProvider);
return favoritesAsync.when(
data: (favorites) => favorites.contains(productId),
return favoriteProductsAsync.when(
data: (products) => products.any((p) => p.productId == productId),
loading: () => false,
error: (_, __) => false,
);
@@ -206,14 +188,15 @@ bool isFavorite(Ref ref, String productId) {
/// Get the total count of favorites
///
/// Derived from the favorite products list.
/// Returns the number of products in the user's favorites.
/// Safe to use in build methods - will return 0 during loading/error states.
@riverpod
int favoriteCount(Ref ref) {
final favoritesAsync = ref.watch(favoritesProvider);
final favoriteProductsAsync = ref.watch(favoriteProductsProvider);
return favoritesAsync.when(
data: (favorites) => favorites.length,
return favoriteProductsAsync.when(
data: (products) => products.length,
loading: () => 0,
error: (_, __) => 0,
);
@@ -221,51 +204,26 @@ int favoriteCount(Ref ref) {
/// Get all favorite product IDs as a list
///
/// Derived from the favorite products list.
/// Useful for filtering product lists or bulk operations.
/// Returns an empty list during loading/error states.
@riverpod
List<String> favoriteProductIds(Ref ref) {
final favoritesAsync = ref.watch(favoritesProvider);
final favoriteProductsAsync = ref.watch(favoriteProductsProvider);
return favoritesAsync.when(
data: (favorites) => favorites.toList(),
return favoriteProductsAsync.when(
data: (products) => products.map((p) => p.productId).toList(),
loading: () => <String>[],
error: (_, __) => <String>[],
);
}
// ============================================================================
// FAVORITE PRODUCTS PROVIDER
// ============================================================================
/// Get actual Product entities for favorited product IDs
///
/// Combines favorites state with products data to return full Product objects.
/// This is useful for displaying favorite products with complete information.
@riverpod
Future<List<Product>> favoriteProducts(Ref ref) async {
final favoriteIds = ref.watch(favoriteProductIdsProvider);
if (favoriteIds.isEmpty) {
return [];
}
// Get products repository with injected dependencies
final productsRepository = await ref.watch(productsRepositoryProvider.future);
final getProductsUseCase = GetProducts(productsRepository);
final allProducts = await getProductsUseCase();
// Filter to only include favorited products
return allProducts
.where((product) => favoriteIds.contains(product.productId))
.toList();
}
// ============================================================================
// DEBUG UTILITIES
// ============================================================================
/// Debug print helper
void debugPrint(String message) {
void _debugPrint(String message) {
// ignore: avoid_print
print('[FavoritesProvider] $message');
}

View File

@@ -8,170 +8,260 @@ part of 'favorites_provider.dart';
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
/// Provides instance of FavoritesLocalDataSource
/// Provides instance of FavoritesRemoteDataSource
@ProviderFor(favoritesLocalDataSource)
const favoritesLocalDataSourceProvider = FavoritesLocalDataSourceProvider._();
@ProviderFor(favoritesRemoteDataSource)
const favoritesRemoteDataSourceProvider = FavoritesRemoteDataSourceProvider._();
/// Provides instance of FavoritesLocalDataSource
/// Provides instance of FavoritesRemoteDataSource
final class FavoritesLocalDataSourceProvider
final class FavoritesRemoteDataSourceProvider
extends
$FunctionalProvider<
FavoritesLocalDataSource,
FavoritesLocalDataSource,
FavoritesLocalDataSource
AsyncValue<FavoritesRemoteDataSource>,
FavoritesRemoteDataSource,
FutureOr<FavoritesRemoteDataSource>
>
with $Provider<FavoritesLocalDataSource> {
/// Provides instance of FavoritesLocalDataSource
const FavoritesLocalDataSourceProvider._()
with
$FutureModifier<FavoritesRemoteDataSource>,
$FutureProvider<FavoritesRemoteDataSource> {
/// Provides instance of FavoritesRemoteDataSource
const FavoritesRemoteDataSourceProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'favoritesLocalDataSourceProvider',
name: r'favoritesRemoteDataSourceProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$favoritesLocalDataSourceHash();
String debugGetCreateSourceHash() => _$favoritesRemoteDataSourceHash();
@$internal
@override
$ProviderElement<FavoritesLocalDataSource> $createElement(
$FutureProviderElement<FavoritesRemoteDataSource> $createElement(
$ProviderPointer pointer,
) => $FutureProviderElement(pointer);
@override
FutureOr<FavoritesRemoteDataSource> create(Ref ref) {
return favoritesRemoteDataSource(ref);
}
}
String _$favoritesRemoteDataSourceHash() =>
r'ec129162e49f37512950106516c0be6cbe1dfceb';
/// Provides instance of FavoriteProductsLocalDataSource
@ProviderFor(favoriteProductsLocalDataSource)
const favoriteProductsLocalDataSourceProvider =
FavoriteProductsLocalDataSourceProvider._();
/// Provides instance of FavoriteProductsLocalDataSource
final class FavoriteProductsLocalDataSourceProvider
extends
$FunctionalProvider<
FavoriteProductsLocalDataSource,
FavoriteProductsLocalDataSource,
FavoriteProductsLocalDataSource
>
with $Provider<FavoriteProductsLocalDataSource> {
/// Provides instance of FavoriteProductsLocalDataSource
const FavoriteProductsLocalDataSourceProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'favoriteProductsLocalDataSourceProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$favoriteProductsLocalDataSourceHash();
@$internal
@override
$ProviderElement<FavoriteProductsLocalDataSource> $createElement(
$ProviderPointer pointer,
) => $ProviderElement(pointer);
@override
FavoritesLocalDataSource create(Ref ref) {
return favoritesLocalDataSource(ref);
FavoriteProductsLocalDataSource create(Ref ref) {
return favoriteProductsLocalDataSource(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(FavoritesLocalDataSource value) {
Override overrideWithValue(FavoriteProductsLocalDataSource value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<FavoritesLocalDataSource>(value),
providerOverride: $SyncValueProvider<FavoriteProductsLocalDataSource>(
value,
),
);
}
}
String _$favoritesLocalDataSourceHash() =>
r'2f6ff99042b7cc1087d8cfdad517f448952c25be';
String _$favoriteProductsLocalDataSourceHash() =>
r'852ae8132f466b3fa6549c26880821ea31e00092';
/// Provides the current logged-in user's ID
///
/// TODO: Replace with actual auth provider integration
/// For now, using hardcoded userId for development
/// Provides instance of FavoritesRepository with online-first approach
@ProviderFor(currentUserId)
const currentUserIdProvider = CurrentUserIdProvider._();
@ProviderFor(favoritesRepository)
const favoritesRepositoryProvider = FavoritesRepositoryProvider._();
/// Provides the current logged-in user's ID
///
/// TODO: Replace with actual auth provider integration
/// For now, using hardcoded userId for development
/// Provides instance of FavoritesRepository with online-first approach
final class CurrentUserIdProvider
extends $FunctionalProvider<String, String, String>
with $Provider<String> {
/// Provides the current logged-in user's ID
///
/// TODO: Replace with actual auth provider integration
/// For now, using hardcoded userId for development
const CurrentUserIdProvider._()
final class FavoritesRepositoryProvider
extends
$FunctionalProvider<
AsyncValue<FavoritesRepository>,
FavoritesRepository,
FutureOr<FavoritesRepository>
>
with
$FutureModifier<FavoritesRepository>,
$FutureProvider<FavoritesRepository> {
/// Provides instance of FavoritesRepository with online-first approach
const FavoritesRepositoryProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'currentUserIdProvider',
name: r'favoritesRepositoryProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$currentUserIdHash();
String debugGetCreateSourceHash() => _$favoritesRepositoryHash();
@$internal
@override
$ProviderElement<String> $createElement($ProviderPointer pointer) =>
$ProviderElement(pointer);
$FutureProviderElement<FavoritesRepository> $createElement(
$ProviderPointer pointer,
) => $FutureProviderElement(pointer);
@override
String create(Ref ref) {
return currentUserId(ref);
}
/// {@macro riverpod.override_with_value}
Override overrideWithValue(String value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<String>(value),
);
FutureOr<FavoritesRepository> create(Ref ref) {
return favoritesRepository(ref);
}
}
String _$currentUserIdHash() => r'7f968e463454a4ad87bce0442f62ecc24a6f756e';
String _$favoritesRepositoryHash() =>
r'1856b5972aaf9d243f8e5450973ea3ab4aead3f6';
/// Manages the favorites state for the current user
/// Manages favorite products with full Product data from wishlist API
///
/// Uses a Set<String> to store product IDs for efficient lookup.
/// Data is persisted to Hive for offline access.
@ProviderFor(Favorites)
const favoritesProvider = FavoritesProvider._();
/// Manages the favorites state for the current user
/// This is the MAIN provider for the favorites feature.
/// Returns full Product objects with all data from the wishlist API.
///
/// Uses a Set<String> to store product IDs for efficient lookup.
/// Data is persisted to Hive for offline access.
final class FavoritesProvider
extends $AsyncNotifierProvider<Favorites, Set<String>> {
/// Manages the favorites state for the current user
/// Online-first: Fetches from API, caches locally
/// Offline: Returns cached products
///
/// Uses keepAlive to prevent unnecessary reloads.
/// Provides refresh() method for pull-to-refresh functionality.
///
/// AsyncNotifier pattern allows:
/// - Manual refresh capability
/// - Proper loading states during operations
/// - State updates after mutations
/// - Better error handling
@ProviderFor(FavoriteProducts)
const favoriteProductsProvider = FavoriteProductsProvider._();
/// Manages favorite products with full Product data from wishlist API
///
/// This is the MAIN provider for the favorites feature.
/// Returns full Product objects with all data from the wishlist API.
///
/// Online-first: Fetches from API, caches locally
/// Offline: Returns cached products
///
/// Uses keepAlive to prevent unnecessary reloads.
/// Provides refresh() method for pull-to-refresh functionality.
///
/// AsyncNotifier pattern allows:
/// - Manual refresh capability
/// - Proper loading states during operations
/// - State updates after mutations
/// - Better error handling
final class FavoriteProductsProvider
extends $AsyncNotifierProvider<FavoriteProducts, List<Product>> {
/// Manages favorite products with full Product data from wishlist API
///
/// Uses a Set<String> to store product IDs for efficient lookup.
/// Data is persisted to Hive for offline access.
const FavoritesProvider._()
/// This is the MAIN provider for the favorites feature.
/// Returns full Product objects with all data from the wishlist API.
///
/// Online-first: Fetches from API, caches locally
/// Offline: Returns cached products
///
/// Uses keepAlive to prevent unnecessary reloads.
/// Provides refresh() method for pull-to-refresh functionality.
///
/// AsyncNotifier pattern allows:
/// - Manual refresh capability
/// - Proper loading states during operations
/// - State updates after mutations
/// - Better error handling
const FavoriteProductsProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'favoritesProvider',
isAutoDispose: true,
name: r'favoriteProductsProvider',
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$favoritesHash();
String debugGetCreateSourceHash() => _$favoriteProductsHash();
@$internal
@override
Favorites create() => Favorites();
FavoriteProducts create() => FavoriteProducts();
}
String _$favoritesHash() => r'fccd46f5cd1bbf2b58a13ea90c6d1644ece767b0';
String _$favoriteProductsHash() => r'd43c41db210259021df104f9fecdd00cf474d196';
/// Manages the favorites state for the current user
/// Manages favorite products with full Product data from wishlist API
///
/// Uses a Set<String> to store product IDs for efficient lookup.
/// Data is persisted to Hive for offline access.
/// This is the MAIN provider for the favorites feature.
/// Returns full Product objects with all data from the wishlist API.
///
/// Online-first: Fetches from API, caches locally
/// Offline: Returns cached products
///
/// Uses keepAlive to prevent unnecessary reloads.
/// Provides refresh() method for pull-to-refresh functionality.
///
/// AsyncNotifier pattern allows:
/// - Manual refresh capability
/// - Proper loading states during operations
/// - State updates after mutations
/// - Better error handling
abstract class _$Favorites extends $AsyncNotifier<Set<String>> {
FutureOr<Set<String>> build();
abstract class _$FavoriteProducts extends $AsyncNotifier<List<Product>> {
FutureOr<List<Product>> build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<AsyncValue<Set<String>>, Set<String>>;
final ref = this.ref as $Ref<AsyncValue<List<Product>>, List<Product>>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<AsyncValue<Set<String>>, Set<String>>,
AsyncValue<Set<String>>,
AnyNotifier<AsyncValue<List<Product>>, List<Product>>,
AsyncValue<List<Product>>,
Object?,
Object?
>;
@@ -181,6 +271,7 @@ abstract class _$Favorites extends $AsyncNotifier<Set<String>> {
/// Check if a specific product is favorited
///
/// Derived from the favorite products list.
/// Returns true if the product is in the user's favorites, false otherwise.
/// Safe to use in build methods - will return false during loading/error states.
@@ -189,6 +280,7 @@ const isFavoriteProvider = IsFavoriteFamily._();
/// Check if a specific product is favorited
///
/// Derived from the favorite products list.
/// Returns true if the product is in the user's favorites, false otherwise.
/// Safe to use in build methods - will return false during loading/error states.
@@ -196,6 +288,7 @@ final class IsFavoriteProvider extends $FunctionalProvider<bool, bool, bool>
with $Provider<bool> {
/// Check if a specific product is favorited
///
/// Derived from the favorite products list.
/// Returns true if the product is in the user's favorites, false otherwise.
/// Safe to use in build methods - will return false during loading/error states.
const IsFavoriteProvider._({
@@ -249,10 +342,11 @@ final class IsFavoriteProvider extends $FunctionalProvider<bool, bool, bool>
}
}
String _$isFavoriteHash() => r'8d69e5efe981a3717eebdd7ee192fd75afe722d5';
String _$isFavoriteHash() => r'6e2f5a50d2350975e17d91f395595cd284b69c20';
/// Check if a specific product is favorited
///
/// Derived from the favorite products list.
/// Returns true if the product is in the user's favorites, false otherwise.
/// Safe to use in build methods - will return false during loading/error states.
@@ -269,6 +363,7 @@ final class IsFavoriteFamily extends $Family
/// Check if a specific product is favorited
///
/// Derived from the favorite products list.
/// Returns true if the product is in the user's favorites, false otherwise.
/// Safe to use in build methods - will return false during loading/error states.
@@ -281,6 +376,7 @@ final class IsFavoriteFamily extends $Family
/// Get the total count of favorites
///
/// Derived from the favorite products list.
/// Returns the number of products in the user's favorites.
/// Safe to use in build methods - will return 0 during loading/error states.
@@ -289,6 +385,7 @@ const favoriteCountProvider = FavoriteCountProvider._();
/// Get the total count of favorites
///
/// Derived from the favorite products list.
/// Returns the number of products in the user's favorites.
/// Safe to use in build methods - will return 0 during loading/error states.
@@ -296,6 +393,7 @@ final class FavoriteCountProvider extends $FunctionalProvider<int, int, int>
with $Provider<int> {
/// Get the total count of favorites
///
/// Derived from the favorite products list.
/// Returns the number of products in the user's favorites.
/// Safe to use in build methods - will return 0 during loading/error states.
const FavoriteCountProvider._()
@@ -331,10 +429,11 @@ final class FavoriteCountProvider extends $FunctionalProvider<int, int, int>
}
}
String _$favoriteCountHash() => r'1f147fe5ef28b1477034bd567cfc05ab3e8e90db';
String _$favoriteCountHash() => r'f6f9ab69653671dbc6085dc75b2cae35a47c31a5';
/// Get all favorite product IDs as a list
///
/// Derived from the favorite products list.
/// Useful for filtering product lists or bulk operations.
/// Returns an empty list during loading/error states.
@@ -343,6 +442,7 @@ const favoriteProductIdsProvider = FavoriteProductIdsProvider._();
/// Get all favorite product IDs as a list
///
/// Derived from the favorite products list.
/// Useful for filtering product lists or bulk operations.
/// Returns an empty list during loading/error states.
@@ -351,6 +451,7 @@ final class FavoriteProductIdsProvider
with $Provider<List<String>> {
/// Get all favorite product IDs as a list
///
/// Derived from the favorite products list.
/// Useful for filtering product lists or bulk operations.
/// Returns an empty list during loading/error states.
const FavoriteProductIdsProvider._()
@@ -387,57 +488,4 @@ final class FavoriteProductIdsProvider
}
String _$favoriteProductIdsHash() =>
r'a6814af9a1775b908b4101e64ce3056e1534b561';
/// Get actual Product entities for favorited product IDs
///
/// Combines favorites state with products data to return full Product objects.
/// This is useful for displaying favorite products with complete information.
@ProviderFor(favoriteProducts)
const favoriteProductsProvider = FavoriteProductsProvider._();
/// Get actual Product entities for favorited product IDs
///
/// Combines favorites state with products data to return full Product objects.
/// This is useful for displaying favorite products with complete information.
final class FavoriteProductsProvider
extends
$FunctionalProvider<
AsyncValue<List<Product>>,
List<Product>,
FutureOr<List<Product>>
>
with $FutureModifier<List<Product>>, $FutureProvider<List<Product>> {
/// Get actual Product entities for favorited product IDs
///
/// Combines favorites state with products data to return full Product objects.
/// This is useful for displaying favorite products with complete information.
const FavoriteProductsProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'favoriteProductsProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$favoriteProductsHash();
@$internal
@override
$FutureProviderElement<List<Product>> $createElement(
$ProviderPointer pointer,
) => $FutureProviderElement(pointer);
@override
FutureOr<List<Product>> create(Ref ref) {
return favoriteProducts(ref);
}
}
String _$favoriteProductsHash() => r'630acfbc403cc4deb486c7b0199f128252a8990b';
r'2e281e9a5dee122d326354afd515a68c7f0c4137';