import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:provider/provider.dart'; import 'package:qpay/screens/gateway/gateway_controller.dart'; import 'package:qpay/screens/transaction_controller.dart'; import 'package:qpay/widgets/step_loading_widget.dart'; import 'package:web/web.dart' as web; class PollScreen extends StatefulWidget { final String? transactionId; const PollScreen({super.key, this.transactionId}); @override State createState() => _PollScreenState(); } class _PollScreenState extends State { late GatewayController controller; late TransactionController transactionController; @override void initState() { super.initState(); controller = GatewayController(context); transactionController = Provider.of( context, listen: false, ); _startPolling(); } void _startPolling() { // Priority 1: transaction ID passed via route param (/poll/:id) String? transactionId = widget.transactionId; // Priority 2: localStorage (for when gateway redirect causes page reload // and the route param path is not available due to hub redirect override) if (transactionId == null && kIsWeb) { transactionId = web.window.localStorage.getItem('pendingTransactionId'); web.window.localStorage.removeItem('pendingTransactionId'); } // Priority 3: in-memory confirmation data (normal SPA navigation) if (transactionId == null) { try { transactionId = transactionController.model.confirmationData['id'] as String?; } catch (_) { // confirmationData is late and may not be initialized // after a page reload -- ignore } } if (transactionId != null && transactionId.isNotEmpty) { controller.pollTransaction(transactionId); } } @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Completing your transaction'), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () => context.go('/'), ), ), body: ListenableBuilder( listenable: controller, builder: (context, child) { if (controller.model.status == 'SUCCESS') { WidgetsBinding.instance.addPostFrameCallback((_) { context.go('/integration'); }); } return StepLoadingWidget( currentStep: 1, title: 'Verifying Payment', subtitle: 'We\'re checking with our gateway if your transaction was ' 'successful. This won\'t take long.', status: controller.model.status, isLoading: controller.model.isLoading, errorMessage: 'We failed to check your transaction status', onRetry: () { controller.model.isCancelled = false; _startPolling(); }, ); }, ), ); } }