import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import '../models/app_error.dart'; import '../models/product.dart'; import '../services/product_service.dart'; /// The app-wide product list, kept in sync with the database. Stock changes /// from tabs show up here automatically. class InventoryViewModel extends ChangeNotifier { final ProductService productService; InventoryViewModel({required this.productService}); StreamSubscription>? _subscription; List _products = []; bool _hasLoaded = false; AppError? _loadError; List get products => _products; bool get hasLoaded => _hasLoaded; bool get isLoading => !_hasLoaded; AppError? get loadError => _loadError; void ensureLoaded() { if (_subscription != null) return; _subscription = productService.watchProducts().listen( _onProducts, onError: _onLoadError, ); } /// Starts watching again after a load error. void retry() { unawaited(_subscription?.cancel()); _subscription = null; _hasLoaded = false; _loadError = null; notifyListeners(); ensureLoaded(); } void _onProducts(List products) { _products = products; _hasLoaded = true; _loadError = null; notifyListeners(); } void _onLoadError(Object error, StackTrace stack) { debugPrint('InventoryViewModel: load error: $error'); unawaited(Sentry.captureException(error, stackTrace: stack)); _hasLoaded = true; _loadError = AppError.loadProducts; notifyListeners(); } @override void dispose() { _subscription?.cancel(); super.dispose(); } }