gecko/lib/widgets/transaction_in_progress_til...

161 lines
5.9 KiB
Dart

import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/scale_functions.dart';
import 'package:gecko/models/transaction_content.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/widgets/datapod_avatar.dart';
import 'package:gecko/widgets/transaction_status.dart';
import 'package:gecko/widgets/transaction_status_icon.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
import 'package:fade_and_translate/fade_and_translate.dart';
class TransactionInProgressTule extends StatefulWidget {
const TransactionInProgressTule(
{Key? key, required this.address, this.transactionId})
: super(key: key);
final String address;
final String? transactionId;
@override
State<TransactionInProgressTule> createState() =>
_TransactionInProgressTuleState();
}
class _TransactionInProgressTuleState extends State<TransactionInProgressTule> {
late bool isVisible;
late TransactionContent txContent;
@override
void initState() {
isVisible = true;
StreamSubscription<QueryResult>? subscription;
final sub = Provider.of<SubstrateSdk>(context, listen: false);
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
final stream = duniterIndexer.subscribeHistoryIssued(widget.address);
txContent = sub.transactionStatus[widget.transactionId]!;
subscription = stream.listen((result) {
if (result.hasException) {
log.e(result.exception);
isVisible = true;
} else {
final Map transData =
result.data?['account_by_pk']['transactions_issued'].first;
final String receiver = transData['receiver_pubkey'];
final double amount = transData['amount'] / 100;
final createdAt = DateTime.parse(transData['created_at']);
final difference = createdAt.difference(DateTime.now());
if (receiver == txContent.to &&
amount == txContent.amount &&
difference.inSeconds.abs() < 30) {
isVisible = false;
txContent.status = TransactionStatus.finalized;
sub.reload();
subscription?.cancel();
} else {
isVisible = true;
}
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
final statusIcon =
TransactionStatusIcon(txContent.status, size: 21, stroke: 2);
String humanStatus = '';
final finalAmount = txContent.amount * -1;
if (txContent.status == TransactionStatus.success) {
humanStatus = 'extrinsicValidated'.tr(args: [actionMap['pay']!]);
} else if (txContent.status == TransactionStatus.failed) {
humanStatus = errorTransactionMap[txContent.error] ?? txContent.error!;
} else {
humanStatus = statusStatusMap[txContent.status] ??
'Unknown status: ${txContent.status}';
}
return FadeAndTranslate(
visible: isVisible,
translate: const Offset(0, -40),
delay: const Duration(seconds: 2),
duration: const Duration(milliseconds: 700),
onCompleted: () => duniterIndexer.reload(),
child: Padding(
padding: const EdgeInsets.all(8),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: orangeC,
width: 2,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 10),
Text(
'Transaction en cours',
style: scaledTextStyle(
fontSize: 19,
color: Colors.blueAccent,
fontWeight: FontWeight.w400),
),
ListTile(
key: const Key('transactionInProgress'),
contentPadding:
const EdgeInsets.symmetric(horizontal: 5, vertical: 15),
leading: DatapodAvatar(address: txContent.to, size: 50),
title: Padding(
padding: const EdgeInsets.only(bottom: 5),
child: Text(getShortPubkey(txContent.to),
style: scaledTextStyle(
fontSize: 17, fontFamily: 'Monospace')),
),
subtitle: Row(
children: [
statusIcon,
ScaledSizedBox(width: 10),
ScaledSizedBox(
width: 160,
child: Text(
humanStatus,
style: scaledTextStyle(
fontStyle: FontStyle.italic,
color: Theme.of(context)
.textTheme
.titleLarge!
.color,
fontSize: 14),
),
),
],
),
trailing: Text("$finalAmount $currencyName",
style: scaledTextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.blue[700]),
textAlign: TextAlign.justify),
dense: !isTall,
isThreeLine: false),
],
),
),
),
);
});
}
}