Files
kooltab/lib/viewmodels/inventory_view_model.dart
T
2026-10-26 23:15:05 +01:00

71 lines
1.7 KiB
Dart

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<List<Product>>? _subscription;
List<Product> _products = [];
bool _hasLoaded = false;
AppError? _loadError;
List<Product> 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<Product> 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();
}
}