import 'package:flutter/material.dart'; import 'dart:async'; // Add Timer import import 'package:qpay/http/http.dart'; import 'package:qpay/screens/transaction_controller.dart'; import 'package:provider/provider.dart'; class GatewayModel { bool isLoading = false; String status = ''; String? errorMessage; bool isCancelled = false; } class GatewayController extends ChangeNotifier { final GatewayModel model = GatewayModel(); final Http http = Http(); Timer? _pollTimer; // Add timer field BuildContext context; late TransactionController transactionController; GatewayController(this.context) { transactionController = Provider.of( context, listen: false, ); } void _showErrorSnackBar(String? message) { WidgetsBinding.instance.addPostFrameCallback((_) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(message.toString()), behavior: SnackBarBehavior.floating, backgroundColor: Colors.deepOrange, ), ); }); } void startLoading() { model.isLoading = true; notifyListeners(); } void finishLoading() { model.isLoading = false; notifyListeners(); } Future pollTransaction(String uid) async { while (!model.isCancelled) { // Check cancellation flag instead of true // Wait 5 seconds before the next poll await Future.delayed(const Duration(seconds: 5)); // Check again after delay in case it was cancelled during the delay if (model.isCancelled) break; try { dynamic response = await http.get('/transaction/poll/$uid'); logger.i(response.toString()); if (response['status'] == 'SUCCESS') { model.status = response['status']; transactionController.updateReceiptData(response); notifyListeners(); break; } } catch (e) { logger.e(e); _showErrorSnackBar( "Network error. Please try again or contact support", ); } } } // Alternative method using Timer instead of while loop void pollTransactionWithTimer(String uid) { _pollTimer = Timer.periodic(const Duration(seconds: 5), (timer) async { if (model.isCancelled) { timer.cancel(); return; } try { dynamic response = await http.get('/transaction/poll/$uid'); logger.i(response.toString()); if (response['status'] == 'SUCCESS') { model.status = response['status']; transactionController.updateReceiptData(response); notifyListeners(); timer.cancel(); // Stop polling on success } } catch (e) { logger.e(e); _showErrorSnackBar( "Network error. Please try again or contact support", ); } }); } @override void dispose() { model.isCancelled = true; _pollTimer?.cancel(); // Cancel timer if it exists super.dispose(); } }