Files
sendico/frontend/pweb/lib/controllers/payouts/quotation.dart
2026-02-21 21:55:20 +03:00

105 lines
2.7 KiB
Dart

import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:pshared/models/auto_refresh_mode.dart';
import 'package:pshared/models/payment/quote/status_type.dart';
import 'package:pshared/provider/payment/quotation/quotation.dart';
class QuotationController extends ChangeNotifier {
QuotationProvider? _quotation;
Timer? _ticker;
void update(QuotationProvider quotation) {
if (identical(_quotation, quotation)) return;
_quotation?.removeListener(_handleQuotationChanged);
_quotation = quotation;
_quotation?.addListener(_handleQuotationChanged);
_handleQuotationChanged();
}
bool get isLoading => _quotation?.isLoading ?? false;
Exception? get error => _quotation?.error;
bool get canRefresh => _quotation?.canRefresh ?? false;
bool get isReady => _quotation?.isReady ?? false;
AutoRefreshMode get autoRefreshMode =>
_quotation?.autoRefreshMode ?? AutoRefreshMode.on;
DateTime? get quoteExpiresAt => _quotation?.quoteExpiresAt;
Duration? get timeLeft {
final expiresAt = quoteExpiresAt;
if (expiresAt == null) return null;
return expiresAt.difference(DateTime.now().toUtc());
}
bool get isExpired {
final remaining = timeLeft;
if (remaining == null) return false;
return remaining <= Duration.zero;
}
QuoteStatusType get quoteStatus {
if (isLoading) return QuoteStatusType.loading;
if (error != null) return QuoteStatusType.error;
if (_quotation?.quotation == null) return QuoteStatusType.missing;
if (isExpired) return QuoteStatusType.expired;
return QuoteStatusType.active;
}
bool get hasLiveQuote => isReady && _quotation?.quotation != null && !isExpired;
void setAutoRefreshMode(AutoRefreshMode mode) {
_quotation?.setAutoRefreshMode(mode);
}
void refreshQuotation() {
_quotation?.refreshQuotation();
}
void _handleQuotationChanged() {
_syncTicker();
notifyListeners();
}
void _syncTicker() {
final expiresAt = quoteExpiresAt;
if (expiresAt == null) {
_stopTicker();
return;
}
final remaining = expiresAt.difference(DateTime.now().toUtc());
if (remaining <= Duration.zero) {
_stopTicker();
return;
}
_ticker ??= Timer.periodic(const Duration(seconds: 1), (_) {
final expiresAt = quoteExpiresAt;
if (expiresAt == null) {
_stopTicker();
return;
}
final remaining = expiresAt.difference(DateTime.now().toUtc());
if (remaining <= Duration.zero) {
_stopTicker();
}
notifyListeners();
});
}
void _stopTicker() {
_ticker?.cancel();
_ticker = null;
}
@override
void dispose() {
_quotation?.removeListener(_handleQuotationChanged);
_stopTicker();
super.dispose();
}
}