Files
velocity-pay-flutter/lib/screens/gateway/gateway_controller.dart
2026-03-26 19:53:24 +02:00

133 lines
3.3 KiB
Dart

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;
int count = 0;
}
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<TransactionController>(
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;
model.status = '';
notifyListeners();
}
void finishLoading() {
model.isLoading = false;
notifyListeners();
}
Future<void> poll(String uid) async {
startLoading();
try {
dynamic workflowResponse = await http.get('/public/transaction/poll/$uid');
logger.i(workflowResponse.toString());
dynamic response = workflowResponse['body'];
model.status = response['status'];
transactionController.model.paymentStatus = response['paymentStatus'];
finishLoading();
if(model.status == 'SUCCESS') {
transactionController.updateReceiptData(response);
}
notifyListeners();
} catch (e) {
finishLoading();
logger.e(e);
_showErrorSnackBar(
"Network error. Please try again or contact support",
);
}
}
Future<void> pollTransaction(String uid) async {
// only poll for 5 minutes
int max = 30;
while (!model.isCancelled) {
max++;
// Check cancellation flag instead of true
// Wait 5 seconds before the next poll
await Future.delayed(const Duration(seconds: 10));
// Check again after delay in case it was cancelled during the delay
if (model.isCancelled) break;
await poll(uid);
if(max > 30) {
model.isCancelled = true;
}
}
}
// 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('/public/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();
}
}