diff --git a/frontend/pshared/lib/provider/payment/quotation.dart b/frontend/pshared/lib/provider/payment/quotation.dart index d20680e..21aeec4 100644 --- a/frontend/pshared/lib/provider/payment/quotation.dart +++ b/frontend/pshared/lib/provider/payment/quotation.dart @@ -84,12 +84,9 @@ class QuotationProvider extends ChangeNotifier { return _lastRequestSignature == _signature(_pendingIntent!); } - bool get hasLiveQuote => - _isLoaded && - !_isExpired && - !_quotation.isLoading && - _quotation.error == null && - quotation != null; + bool get isReady => _isLoaded && !_isExpired && !_quotation.isLoading && _quotation.error == null; + + bool get hasLiveQuote => isReady && quotation != null; Duration? get timeToExpire { final expiresAt = _quoteExpiry; @@ -176,9 +173,10 @@ class QuotationProvider extends ChangeNotifier { void refreshNow({bool force = true}) { _debounceTimer?.cancel(); - if (!_organizationAttached) return; - if (_pendingIntent == null) { - _reset(); + if (!canRequestQuote) { + if (_pendingIntent == null) { + _reset(); + } return; } unawaited(_requestQuotation(_pendingIntent!, force: force)); diff --git a/frontend/pweb/lib/pages/payment_methods/page.dart b/frontend/pweb/lib/pages/payment_methods/page.dart index 29bad82..0a64404 100644 --- a/frontend/pweb/lib/pages/payment_methods/page.dart +++ b/frontend/pweb/lib/pages/payment_methods/page.dart @@ -15,8 +15,6 @@ import 'package:pweb/pages/payment_methods/payment_page/body.dart'; import 'package:pweb/widgets/sidebar/destinations.dart'; import 'package:pweb/services/posthog.dart'; -import 'package:pweb/generated/i18n/app_localizations.dart'; - class PaymentPage extends StatefulWidget { final ValueChanged? onBack; @@ -85,16 +83,12 @@ class _PaymentPageState extends State { final flowProvider = context.read(); final paymentProvider = context.read(); final quotationProvider = context.read(); - final loc = AppLocalizations.of(context)!; if (paymentProvider.isLoading) return; if (!quotationProvider.hasLiveQuote) { if (quotationProvider.canRequestQuote) { quotationProvider.refreshNow(); } - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(quotationProvider.canRequestQuote ? loc.quoteExpired : loc.quoteUnavailable)), - ); return; } diff --git a/frontend/pweb/lib/pages/payment_methods/payment_page/page.dart b/frontend/pweb/lib/pages/payment_methods/payment_page/page.dart index eb0c976..70fb650 100644 --- a/frontend/pweb/lib/pages/payment_methods/payment_page/page.dart +++ b/frontend/pweb/lib/pages/payment_methods/payment_page/page.dart @@ -1,14 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - import 'package:pshared/models/payment/wallet.dart'; import 'package:pshared/models/recipient/recipient.dart'; -import 'package:pshared/provider/payment/provider.dart'; -import 'package:pshared/provider/payment/quotation.dart'; import 'package:pshared/provider/recipient/provider.dart'; -import 'package:pweb/models/button_state.dart'; import 'package:pweb/pages/dashboard/payouts/form.dart'; import 'package:pweb/pages/payment_methods/payment_page/back_button.dart'; import 'package:pweb/pages/payment_methods/payment_page/header.dart'; @@ -103,18 +98,7 @@ class PaymentPageContent extends StatelessWidget { SizedBox(height: dimensions.paddingLarge), const QuoteStatus(), SizedBox(height: dimensions.paddingXXLarge), - Consumer2( - builder: (context, quotation, payment, _) { - final canSend = quotation.hasLiveQuote && !payment.isLoading; - final state = payment.isLoading - ? ButtonState.loading - : (canSend ? ButtonState.enabled : ButtonState.disabled); - return SendButton( - onPressed: canSend ? onSend : null, - state: state, - ); - }, - ), + SendButton(onPressed: onSend), SizedBox(height: dimensions.paddingLarge), ], ), diff --git a/frontend/pweb/lib/pages/payment_methods/payment_page/send_button.dart b/frontend/pweb/lib/pages/payment_methods/payment_page/send_button.dart index 13216f1..b8d47f5 100644 --- a/frontend/pweb/lib/pages/payment_methods/payment_page/send_button.dart +++ b/frontend/pweb/lib/pages/payment_methods/payment_page/send_button.dart @@ -1,5 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:pshared/provider/payment/provider.dart'; +import 'package:pshared/provider/payment/quotation.dart'; + import 'package:pweb/models/button_state.dart'; import 'package:pweb/utils/dimensions.dart'; @@ -8,58 +13,64 @@ import 'package:pweb/generated/i18n/app_localizations.dart'; class SendButton extends StatelessWidget { final VoidCallback? onPressed; - final ButtonState state; const SendButton({ super.key, required this.onPressed, - this.state = ButtonState.enabled, }); @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - final dimensions = AppDimensions(); - final isLoading = state == ButtonState.loading; - final isActive = state == ButtonState.enabled && onPressed != null && !isLoading; - final backgroundColor = isActive - ? theme.colorScheme.primary - : theme.colorScheme.primary.withValues(alpha: 0.5); - final textColor = theme.colorScheme.onSecondary.withValues(alpha: isActive ? 1 : 0.7); + Widget build(BuildContext context) => Consumer2( + builder: (context, quotation, payment, _) { + final theme = Theme.of(context); + final dimensions = AppDimensions(); - return Center( - child: SizedBox( - width: dimensions.buttonWidth, - height: dimensions.buttonHeight, - child: InkWell( - borderRadius: BorderRadius.circular(dimensions.borderRadiusSmall), - onTap: isActive ? onPressed : null, - child: Container( - decoration: BoxDecoration( - color: backgroundColor, - borderRadius: BorderRadius.circular(dimensions.borderRadiusSmall), + final canSend = quotation.hasLiveQuote && !payment.isLoading; + final state = payment.isLoading + ? ButtonState.loading + : (canSend ? ButtonState.enabled : ButtonState.disabled); + final isLoading = state == ButtonState.loading; + final isActive = state == ButtonState.enabled && onPressed != null; + + final backgroundColor = isActive + ? theme.colorScheme.primary + : theme.colorScheme.primary.withValues(alpha: 0.5); + final textColor = theme.colorScheme.onSecondary.withValues(alpha: isActive ? 1 : 0.7); + + return Center( + child: SizedBox( + width: dimensions.buttonWidth, + height: dimensions.buttonHeight, + child: InkWell( + borderRadius: BorderRadius.circular(dimensions.borderRadiusSmall), + onTap: isActive ? onPressed : null, + child: Container( + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: BorderRadius.circular(dimensions.borderRadiusSmall), + ), + child: Center( + child: isLoading + ? SizedBox( + height: dimensions.iconSizeSmall, + width: dimensions.iconSizeSmall, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation(textColor), + ), + ) + : Text( + AppLocalizations.of(context)!.send, + style: theme.textTheme.bodyLarge?.copyWith( + color: textColor, + fontWeight: FontWeight.w600, + ), + ), + ), + ), + ), ), - child: Center( - child: isLoading - ? SizedBox( - height: dimensions.iconSizeSmall, - width: dimensions.iconSizeSmall, - child: CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(textColor), - ), - ) - : Text( - AppLocalizations.of(context)!.send, - style: theme.textTheme.bodyLarge?.copyWith( - color: textColor, - fontWeight: FontWeight.w600, - ), - ), - ), - ), - ), - ), - ); - } + ); + }, + ); }