Skip to content

Instantly share code, notes, and snippets.

@martynov-alex
Last active September 4, 2023 12:01
Show Gist options
  • Select an option

  • Save martynov-alex/c7aabb3016288b061f78ae5fb98e8031 to your computer and use it in GitHub Desktop.

Select an option

Save martynov-alex/c7aabb3016288b061f78ae5fb98e8031 to your computer and use it in GitHub Desktop.
Queue example
import 'dart:collection';
void main() async {
final repository = ProductDetailRepository();
final service = RecentlyWatchedService(productDetailRepository: repository);
await Future.delayed(const Duration(seconds: 1));
service.add(const Product(7));
service.add(const Product(3));
service.add(const Product(2));
service.add(const Product(3));
service.add(const Product(5));
service.add(const Product(7));
service.add(const Product(8));
print(service.products);
final repoProducts = await repository.getRecentlyWatchedProducts();
print(repoProducts);
}
const _maxProductsQuantity = 6;
/// A service that allows you to track previously watched products.
class RecentlyWatchedService {
final IProductDetailRepository _productDetailRepository;
final _products = Queue<Product>();
List<Product> get products => _products.toList();
RecentlyWatchedService({
required IProductDetailRepository productDetailRepository,
}) : _productDetailRepository = productDetailRepository {
_init();
}
/// Add recently watched product.
void add(Product product) {
_handleNewProduct(product);
_saveRecentlyWatchedProducts();
}
void _handleNewProduct(Product product) {
if (_products.isEmpty) {
_products.addFirst(product);
return;
}
_products.remove(product);
final hasReachedMax = _products.length >= _maxProductsQuantity;
if (hasReachedMax) _products.removeLast();
_products.addFirst(product);
}
Future<void> _init() async {
try {
final products =
await _productDetailRepository.getRecentlyWatchedProducts();
if (products.isEmpty) return;
_products.addAll(products);
} on Object catch (e, stack) {
// Handle error.
print('Error $e, stack $stack');
}
}
Future<void> _saveRecentlyWatchedProducts() async {
try {
await _productDetailRepository.saveRecentlyWatchedProducts(
products: _products.toList(),
);
} on Object catch (e, stack) {
// Handle error.
print('Error $e, stack $stack');
}
}
}
class Product {
final int id;
const Product(this.id);
@override
String toString() => id.toString();
@override
bool operator ==(Object other) =>
identical(this, other) || other is Product && id == other.id;
@override
int get hashCode => id.hashCode;
}
/// Repository interface.
abstract interface class IProductDetailRepository {
/// Get a list of previously watched products.
Future<List<Product>> getRecentlyWatchedProducts();
/// Save previously watched products.
Future<void> saveRecentlyWatchedProducts({
required List<Product> products,
});
}
class ProductDetailRepository implements IProductDetailRepository {
final _products = <Product>[const Product(0), const Product(9)];
ProductDetailRepository();
@override
Future<List<Product>> getRecentlyWatchedProducts() async =>
Future.delayed(const Duration(seconds: 1), () => _products);
@override
Future<void> saveRecentlyWatchedProducts({
required List<Product> products,
}) async =>
Future.delayed(const Duration(seconds: 1), () {
_products
..clear()
..addAll(products);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment