add favorite
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
import 'package:worker/core/errors/exceptions.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/domain/repositories/favorites_repository.dart';
|
||||
import 'package:worker/features/products/domain/entities/product.dart';
|
||||
|
||||
/// Favorites Repository Implementation
|
||||
///
|
||||
/// Implements the FavoritesRepository interface with online-first approach:
|
||||
/// 1. Always try API first when online
|
||||
/// 2. Cache API responses locally
|
||||
/// 3. Fall back to local cache on network errors
|
||||
class FavoritesRepositoryImpl implements FavoritesRepository {
|
||||
FavoritesRepositoryImpl({
|
||||
required this.remoteDataSource,
|
||||
required this.productsLocalDataSource,
|
||||
required this.networkInfo,
|
||||
});
|
||||
|
||||
final FavoritesRemoteDataSource remoteDataSource;
|
||||
final FavoriteProductsLocalDataSource productsLocalDataSource;
|
||||
final NetworkInfo networkInfo;
|
||||
|
||||
// =========================================================================
|
||||
// GET FAVORITE PRODUCTS (Returns actual Product entities)
|
||||
// =========================================================================
|
||||
|
||||
/// Get favorite products with full product data
|
||||
///
|
||||
/// Online-first: Fetches from API, caches locally
|
||||
/// Offline: Returns cached products
|
||||
@override
|
||||
Future<List<Product>> getFavoriteProducts() async {
|
||||
try {
|
||||
// Online-first: Try to fetch from API
|
||||
if (await networkInfo.isConnected) {
|
||||
_debugPrint('Fetching favorite products from API');
|
||||
|
||||
try {
|
||||
// Get products from wishlist API
|
||||
final remoteProducts = await remoteDataSource.getFavorites();
|
||||
|
||||
// Cache products locally
|
||||
await productsLocalDataSource.saveProducts(remoteProducts);
|
||||
|
||||
_debugPrint('Fetched ${remoteProducts.length} favorite products from API');
|
||||
return remoteProducts.map((model) => model.toEntity()).toList();
|
||||
} on ServerException catch (e) {
|
||||
_debugPrint('API error, falling back to cache: $e');
|
||||
return _getProductsFromCache();
|
||||
} on NetworkException catch (e) {
|
||||
_debugPrint('Network error, falling back to cache: $e');
|
||||
return _getProductsFromCache();
|
||||
}
|
||||
} else {
|
||||
// Offline: Use local cache
|
||||
_debugPrint('Offline - using cached favorite products');
|
||||
return _getProductsFromCache();
|
||||
}
|
||||
} catch (e) {
|
||||
_debugPrint('Error getting favorite products: $e');
|
||||
return _getProductsFromCache();
|
||||
}
|
||||
}
|
||||
|
||||
/// Get favorite products from local cache
|
||||
Future<List<Product>> _getProductsFromCache() async {
|
||||
try {
|
||||
final cachedProducts = await productsLocalDataSource.getAllProducts();
|
||||
_debugPrint('Loaded ${cachedProducts.length} favorite products from cache');
|
||||
return cachedProducts.map((model) => model.toEntity()).toList();
|
||||
} catch (e) {
|
||||
_debugPrint('Error loading from cache: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// ADD FAVORITE
|
||||
// =========================================================================
|
||||
|
||||
@override
|
||||
Future<void> addFavorite(String productId) async {
|
||||
try {
|
||||
// Online-first: Try to add via API
|
||||
if (await networkInfo.isConnected) {
|
||||
_debugPrint('Adding favorite via API: $productId');
|
||||
|
||||
try {
|
||||
final success = await remoteDataSource.addToFavorites(productId);
|
||||
|
||||
if (success) {
|
||||
_debugPrint('Added favorite successfully: $productId');
|
||||
} else {
|
||||
throw const ServerException('Failed to add to favorites');
|
||||
}
|
||||
} on ServerException catch (e) {
|
||||
_debugPrint('API error adding favorite: $e');
|
||||
rethrow;
|
||||
} on NetworkException catch (e) {
|
||||
_debugPrint('Network error adding favorite: $e');
|
||||
rethrow;
|
||||
}
|
||||
} else {
|
||||
// Offline: Queue for later sync
|
||||
_debugPrint('Offline - cannot add favorite: $productId');
|
||||
throw const NetworkException('No internet connection');
|
||||
}
|
||||
} catch (e) {
|
||||
_debugPrint('Error adding favorite: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// REMOVE FAVORITE
|
||||
// =========================================================================
|
||||
|
||||
@override
|
||||
Future<bool> removeFavorite(String productId) async {
|
||||
try {
|
||||
// Online-first: Try to remove via API
|
||||
if (await networkInfo.isConnected) {
|
||||
_debugPrint('Removing favorite via API: $productId');
|
||||
|
||||
try {
|
||||
final success = await remoteDataSource.removeFromFavorites(productId);
|
||||
|
||||
if (success) {
|
||||
_debugPrint('Removed favorite successfully: $productId');
|
||||
}
|
||||
|
||||
return success;
|
||||
} on ServerException catch (e) {
|
||||
_debugPrint('API error removing favorite: $e');
|
||||
return false;
|
||||
} on NetworkException catch (e) {
|
||||
_debugPrint('Network error removing favorite: $e');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Offline: Cannot remove
|
||||
_debugPrint('Offline - cannot remove favorite: $productId');
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
_debugPrint('Error removing favorite: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// DEBUG UTILITIES
|
||||
// ============================================================================
|
||||
|
||||
/// Debug print helper
|
||||
void _debugPrint(String message) {
|
||||
// ignore: avoid_print
|
||||
print('[FavoritesRepository] $message');
|
||||
}
|
||||
Reference in New Issue
Block a user