From 1bff9682e0e75674afeca27c2747f4f2968c16d8 Mon Sep 17 00:00:00 2001 From: mokeyCode Date: Mon, 17 Apr 2023 01:26:50 +0800 Subject: [PATCH] fix bugs & add new functions --- android/app/src/main/AndroidManifest.xml | 1 + lib/common/global.dart | 5 +- lib/common/transaction.dart | 1 + lib/l10n/app_de.arb | 3 +- lib/l10n/app_en.arb | 3 +- lib/l10n/app_fr.arb | 3 +- lib/l10n/app_ja.arb | 3 +- lib/l10n/app_ru.arb | 3 +- lib/l10n/app_zh.arb | 3 +- lib/main.dart | 2 - lib/page/common/add_contacts_page.dart | 20 +++- lib/page/common/check_page.dart | 4 - lib/page/common/create_wallet_page.dart | 3 +- lib/page/common/face_id_page.dart | 2 - lib/page/common/secure_wallet_page.dart | 72 -------------- lib/page/detail/contacts_page.dart | 41 ++++---- lib/page/detail/receive_page.dart | 1 - lib/page/detail/send_page.dart | 57 +++++++----- lib/page/detail/transaction_page.dart | 114 +++++++++++++++++++++-- lib/page/wallet/contacts_page.dart | 4 +- lib/page/wallet/wallet_page.dart | 2 +- lib/widget/create_wallet_widget.dart | 1 - lib/widget/home_button.dart | 1 - lib/widget/home_transaction_item.dart | 3 +- lib/widget/label_button.dart | 1 - lib/widget/modal_frame.dart | 6 +- lib/widget/nav_header.dart | 1 - lib/widget/security.dart | 2 - lib/widget/wallet_header.dart | 1 - macos/Podfile.lock | 12 +++ 30 files changed, 218 insertions(+), 157 deletions(-) delete mode 100644 lib/page/common/secure_wallet_page.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 2942b1d..404375c 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ diff --git a/lib/common/global.dart b/lib/common/global.dart index 78eae2b..0adc697 100644 --- a/lib/common/global.dart +++ b/lib/common/global.dart @@ -154,9 +154,8 @@ class Global { ), ], options: const AuthenticationOptions(biometricOnly: true, sensitiveTransaction: false)); - } on PlatformException catch (e) { - // print(e); - } + // ignore: empty_catches + } on PlatformException {} return authenticated; } diff --git a/lib/common/transaction.dart b/lib/common/transaction.dart index 17af046..c9a9e9e 100644 --- a/lib/common/transaction.dart +++ b/lib/common/transaction.dart @@ -113,6 +113,7 @@ class TransactionHelper { static bool checkAddress(String address) { try { + if (address.isEmpty) return false; var addrBytes = Helper.base58Decode(address).reversed.toList(); Helper.base58Decode('4AzP6NX68y854ztnSMuBYLj8KHHAtX5HK').reversed.toList(); if (addrBytes.length != 24) { diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index d492ab2..5d7bb72 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -121,5 +121,6 @@ "no_contacts":"Keine Kontakte", "tips":"Tipps", "wallet_tips":"Wischen Sie den Eintrag nach rechts, um das Wallet zu löschen。", - "hide_balance":"Guthaben ausblenden" + "hide_balance":"Guthaben ausblenden", + "contact_address_repeat": "Kontaktadresse existiert bereits" } \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 5cd7951..14177c3 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -121,5 +121,6 @@ "no_contacts":"Any contact", "tips":"Tips", "wallet_tips":"Swipe the item to the right to delete the wallet.", - "hide_balance":"Hide Balance" + "hide_balance":"Hide Balance", + "contact_address_repeat":"Contact address already exists" } \ No newline at end of file diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index c5c5486..bcc7082 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -121,5 +121,6 @@ "no_contacts":"Aucun contact", "tips":"Conseils", "wallet_tips":"Balayez l'élément vers la droite pour supprimer le portefeuille.", - "hide_balance":"Masquer le solde" + "hide_balance":"Masquer le solde", + "contact_address_repeat": "L'adresse de contact existe déjà" } \ No newline at end of file diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index cd25744..fa87014 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -121,5 +121,6 @@ "no_contacts":"連絡先がありません", "tips":"ヒント", "wallet_tips":"ウォレットを削除するには、アイテムを右にスワイプしてください。", - "hide_balance":"残高を非表示" + "hide_balance":"残高を非表示", + "contact_address_repeat": "連絡先がすでに存在しています" } \ No newline at end of file diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index 7e4a472..c12c05c 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -121,5 +121,6 @@ "no_contacts":"Нет контактов", "tips":"Советы", "wallet_tips":"Чтобы удалить кошелек, проведите элемент вправо.", - "hide_balance":"Скрыть баланс" + "hide_balance":"Скрыть баланс", + "contact_address_repeat": "Контактный адрес уже существует" } \ No newline at end of file diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index d591a71..661676b 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -121,5 +121,6 @@ "no_contacts":"没有联系人", "tips":"提示", "wallet_tips":"向右滑动该项以删除钱包。", - "hide_balance":"隐藏余额" + "hide_balance":"隐藏余额", + "contact_address_repeat": "联系地址已存在" } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index ce7ae2d..1475e5f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,5 @@ import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_statusbarcolor_ns/flutter_statusbarcolor_ns.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:xdag/common/color.dart'; @@ -109,7 +108,6 @@ class MyWidget extends StatelessWidget { "/create": (context) => const CreateWalletPage(), "/faceid": (context) => const FaceIDPage(), "/select": (context) => const WalletListPage(), - // "/security_wallet": (context) => const SecureWalletPage(), "/wallet": (context) => const WalletHomePage(), "/security": (context) => const SecurityPage(), "/legal": (context) => const LegalPage(), diff --git a/lib/page/common/add_contacts_page.dart b/lib/page/common/add_contacts_page.dart index 9192987..00a8763 100644 --- a/lib/page/common/add_contacts_page.dart +++ b/lib/page/common/add_contacts_page.dart @@ -1,6 +1,5 @@ import 'dart:io'; import 'package:auto_size_text_field/auto_size_text_field.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:xdag/common/color.dart'; @@ -41,9 +40,9 @@ class _AddContactsPage extends State { @override Widget build(BuildContext context) { - bool isButtonEnable = controller.text.isNotEmpty && controller2.text.isNotEmpty; + bool isButtonEnable = controller.text.trim().isNotEmpty && controller2.text.isNotEmpty; if (widget.isEdit) { - isButtonEnable = controller.text.isNotEmpty && controller2.text.isNotEmpty && (controller.text != widget.item!.address || controller2.text != widget.item!.name); + isButtonEnable = controller.text.trim().isNotEmpty && controller2.text.isNotEmpty && (controller.text != widget.item!.address || controller2.text != widget.item!.name); } ContactsModal contacts = Provider.of(context); return Scaffold( @@ -104,6 +103,7 @@ class _AddContactsPage extends State { error = AppLocalizations.of(context).walletAddressError; }); } + // ignore: empty_catches } catch (e) {} }, child: Row( @@ -259,6 +259,20 @@ class _AddContactsPage extends State { if (widget.isEdit) { await contacts.changeContacts(index: widget.index, name: controller2.text, address: controller.text); } else { + // 检查有没有重复地址 + bool hasRepeat = false; + for (var i = 0; i < contacts.contactsList.length; i++) { + if (contacts.contactsList[i].address == controller.text) { + hasRepeat = true; + break; + } + } + if (hasRepeat) { + setState(() { + error = AppLocalizations.of(context).contact_address_repeat; + }); + return; + } await contacts.addContacts(name: controller2.text, address: controller.text); } if (mounted) Navigator.pop(context); diff --git a/lib/page/common/check_page.dart b/lib/page/common/check_page.dart index 3141a52..28cbf29 100644 --- a/lib/page/common/check_page.dart +++ b/lib/page/common/check_page.dart @@ -1,6 +1,4 @@ import 'dart:io'; - -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:xdag/common/color.dart'; @@ -53,8 +51,6 @@ class _CheckPageState extends State { tipsText = AppLocalizations.of(context).use_biometrics_tips_3; } var padding = Helper.isDesktop ? 10.0 : ScreenHelper.topPadding; - - // print(Global.devBiometricsType != -1 && !widget.onlyPassword); return Scaffold( backgroundColor: DarkColors.bgColor, body: WillPopScope( diff --git a/lib/page/common/create_wallet_page.dart b/lib/page/common/create_wallet_page.dart index 8e94ce6..db5de3d 100644 --- a/lib/page/common/create_wallet_page.dart +++ b/lib/page/common/create_wallet_page.dart @@ -1,6 +1,5 @@ import 'dart:isolate'; import 'package:auto_size_text_field/auto_size_text_field.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:provider/provider.dart'; @@ -106,7 +105,7 @@ class _CreateWalletPageState extends State { args = ModalRoute.of(context)!.settings.arguments as CreateWalletPageRouteParams; } int selectIndex = isPrivateKey ? 1 : 0; - bool isButtonEnable = walletName.isNotEmpty && isAgree; + bool isButtonEnable = walletName.trim().isNotEmpty && isAgree; if (args.isImport) { if (isPrivateKey) { isButtonEnable = isButtonEnable && importContent.length == 64; diff --git a/lib/page/common/face_id_page.dart b/lib/page/common/face_id_page.dart index 10118eb..b3772d7 100644 --- a/lib/page/common/face_id_page.dart +++ b/lib/page/common/face_id_page.dart @@ -1,6 +1,4 @@ import 'dart:io'; - -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:xdag/common/color.dart'; diff --git a/lib/page/common/secure_wallet_page.dart b/lib/page/common/secure_wallet_page.dart deleted file mode 100644 index a66983b..0000000 --- a/lib/page/common/secure_wallet_page.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:xdag/common/color.dart'; -import 'package:xdag/common/helper.dart'; -import 'package:xdag/widget/button.dart'; -import 'package:xdag/widget/create_wallet_widget.dart'; - -class SecureWalletPage extends StatelessWidget { - const SecureWalletPage({super.key}); - @override - Widget build(BuildContext context) { - ScreenHelper.initScreen(context); - var bottomPadding = ScreenHelper.bottomPadding; - const titleStyle = TextStyle( - decoration: TextDecoration.none, - fontSize: 24, - fontFamily: 'RobotoMono', - fontWeight: FontWeight.w700, - color: DarkColors.mainColor, - ); - const descStyle = TextStyle( - decoration: TextDecoration.none, - fontSize: 14, - fontFamily: 'RobotoMono', - fontWeight: FontWeight.w500, - color: Colors.white, - ); - return Scaffold( - appBar: null, - body: Container( - color: DarkColors.bgColor, - child: Column( - children: [ - CreateWalletStep(onPressed: () {}, step: 2), - Expanded( - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 25), - child: Column( - children: [ - const Text("Create Wallet", style: titleStyle), - const SizedBox(height: 30), - Expanded( - child: Center( - child: Image.asset( - 'images/lock.png', - fit: BoxFit.contain, - ), - )), - const SizedBox(height: 20), - const Text("Please store the mnemonics in a safe place, preferably on a device without internet access or on paper.", style: descStyle), - const SizedBox(height: 12), - const Text("When you wish to use the wallet on a new device, this is the only way that the mnemonics can be recovered from your wallet.", style: descStyle), - ], - ), - ), - ), - Container(color: DarkColors.lineColor, height: 1, width: double.infinity), - Container( - margin: EdgeInsets.fromLTRB(15, 20, 15, bottomPadding > 0 ? bottomPadding : 20), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: const [ - Button(text: "Start", bgColor: DarkColors.mainColor), - SizedBox(height: 20), - Button(text: "Remind Me Later", bgColor: DarkColors.lineColor), - ], - ), - ) - ], - ))); - } -} diff --git a/lib/page/detail/contacts_page.dart b/lib/page/detail/contacts_page.dart index 0431c6a..4d42fad 100644 --- a/lib/page/detail/contacts_page.dart +++ b/lib/page/detail/contacts_page.dart @@ -1,6 +1,5 @@ import 'dart:io'; import 'package:auto_size_text_field/auto_size_text_field.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:xdag/common/color.dart'; @@ -23,7 +22,7 @@ class ContactsPage extends StatefulWidget { class ContactsStatePage extends State { late TextEditingController controller; - String walletAddress = ""; + bool isButtonEnable = false; String error = ""; @override void initState() { @@ -33,7 +32,7 @@ class ContactsStatePage extends State { @override Widget build(BuildContext context) { - bool isButtonEnable = walletAddress.isNotEmpty; + // bool isButtonEnable = controller.text.isNotEmpty; ContactsModal contacts = Provider.of(context); return Scaffold( backgroundColor: DarkColors.bgColor, @@ -75,7 +74,8 @@ class ContactsStatePage extends State { bool flag = TransactionHelper.checkAddress(res); if (flag) { setState(() { - walletAddress = res; + // walletAddress = res; + isButtonEnable = true; error = ""; }); controller.text = res; @@ -84,7 +84,8 @@ class ContactsStatePage extends State { controller.clear(); controller.selection = TextSelection.fromPosition(const TextPosition(offset: 0)); setState(() { - walletAddress = ""; + // walletAddress = ""; + isButtonEnable = false; error = AppLocalizations.of(context).walletAddressError; }); } @@ -92,10 +93,12 @@ class ContactsStatePage extends State { controller.clear(); controller.selection = TextSelection.fromPosition(const TextPosition(offset: 0)); setState(() { - walletAddress = ""; + // walletAddress = ""; + isButtonEnable = false; error = AppLocalizations.of(context).walletAddressError; }); } + // ignore: empty_catches } catch (e) {} }, child: Row( @@ -118,7 +121,7 @@ class ContactsStatePage extends State { controller: controller, onChanged: (value) { setState(() { - walletAddress = value; + isButtonEnable = value.isNotEmpty; error = ""; }); }, @@ -209,13 +212,19 @@ class ContactsStatePage extends State { return MyCupertinoButton( padding: EdgeInsets.zero, onPressed: () async { - controller.text = item.address; - controller.selection = TextSelection.fromPosition(TextPosition(offset: item.address.length)); - Navigator.pushNamed( - context, - '/send', - arguments: SendPageRouteParams(address: item.address), - ); + // controller.text = item.address; + // controller.selection = TextSelection.fromPosition(TextPosition(offset: item.address.length)); + // setState(() { + // isButtonEnable = true; + // error = ""; + // }); + if (mounted) { + Navigator.pushNamed( + context, + '/send', + arguments: SendPageRouteParams(address: item.address, name: item.name), + ); + } }, child: Container( decoration: BoxDecoration( @@ -265,12 +274,12 @@ class ContactsStatePage extends State { disable: !isButtonEnable, onPressed: () async { // to send - bool flag = TransactionHelper.checkAddress(walletAddress); + bool flag = TransactionHelper.checkAddress(controller.text); if (flag) { Navigator.pushNamed( context, '/send', - arguments: SendPageRouteParams(address: walletAddress), + arguments: SendPageRouteParams(address: controller.text), ); } else { setState(() { diff --git a/lib/page/detail/receive_page.dart b/lib/page/detail/receive_page.dart index d3dc81d..3f5a460 100644 --- a/lib/page/detail/receive_page.dart +++ b/lib/page/detail/receive_page.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; diff --git a/lib/page/detail/send_page.dart b/lib/page/detail/send_page.dart index 87497cd..be11c6c 100644 --- a/lib/page/detail/send_page.dart +++ b/lib/page/detail/send_page.dart @@ -2,7 +2,6 @@ import 'dart:isolate'; import 'package:auto_size_text_field/auto_size_text_field.dart'; import 'package:dio/dio.dart'; import 'package:extended_text/extended_text.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; @@ -22,7 +21,8 @@ import 'package:bip32/bip32.dart' as bip32; class SendPageRouteParams { final String address; - SendPageRouteParams({required this.address}); + final String name; + SendPageRouteParams({required this.address, this.name = ''}); } class SendPage extends StatefulWidget { @@ -59,7 +59,6 @@ class _SendPageState extends State { } static void isolateFunction(SendPort sendPort) async { - //这里是新的线程,不要用外部的变量 final receivePort = ReceivePort(); sendPort.send(receivePort.sendPort); @@ -69,7 +68,6 @@ class _SendPageState extends State { String amount = data[2] as String; String fromAddress = data[3] as String; String remark = data[4] as String; - // 判断 isPrivate 是否有空格 bool isPrivateKey = res.trim().split(' ').length == 1; bip32.BIP32 wallet = Helper.createWallet(isPrivate: isPrivateKey, content: res); String result = TransactionHelper.getTransaction(fromAddress, toAddress, remark, double.parse(amount), wallet); @@ -90,11 +88,6 @@ class _SendPageState extends State { var subSendPort = data; subSendPort.send([res, toAddress, amount, fromAddress, remark]); } else if (data is List) { - setState(() { - isLoad = false; - amount = ''; - remark = ''; - }); String result = data[1]; Response response = await dio.post( Global.rpcURL, @@ -111,9 +104,16 @@ class _SendPageState extends State { // print(res); if (res.length == 32 && res.trim().split(' ').length == 1) { var transactionItem = Transaction(time: '', amount: Helper.removeTrailingZeros(sendAmount.toString()), address: fromAddress, status: 'pending', from: fromAddress, to: toAddress, type: 0, hash: '', fee: 0, blockAddress: res, remark: sendRemark); - Helper.showBottomSheet(context, TransactionPage(transaction: transactionItem, address: fromAddress)); controller.clear(); controller2.clear(); + setState(() { + isLoad = false; + amount = ''; + remark = ''; + }); + Helper.changeAndroidStatusBar(true); + await Helper.showBottomSheet(context, TransactionPage(transaction: transactionItem, address: fromAddress)); + Helper.changeAndroidStatusBar(false); } else { // snackbar setState(() { @@ -181,7 +181,7 @@ class _SendPageState extends State { const SizedBox(width: 15), Expanded( child: ExtendedText( - args.address, + args.name.isEmpty ? args.address : args.name, textAlign: TextAlign.center, maxLines: 1, style: const TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500), @@ -344,20 +344,31 @@ class _SendPageState extends State { FocusScope.of(context).unfocus(); await Future.delayed(const Duration(milliseconds: 200)); } + // 展示当前 from to amount + if (context.mounted) { - await showModalBottomSheet( - backgroundColor: DarkColors.bgColor, - context: context, - isScrollControlled: true, - builder: (BuildContext buildContext) => CheckPage(checkCallback: (bool isCheck) async { - if (isCheck) { - String? data = await Global.getWalletDataByAddress(wallet.address); - if (data != null && context.mounted) { - send(data, args.address, wallet.address); - } - } - }), + Helper.changeAndroidStatusBar(true); + var transactionItem = Transaction(time: '', amount: Helper.removeTrailingZeros(amount.toString()), address: wallet.address, status: 'pending', from: wallet.address, to: args.address, type: 0, hash: '', fee: 0, blockAddress: "", remark: remark); + bool? flag = await Helper.showBottomSheet( + context, + TransactionShowDetail(transaction: transactionItem), ); + Helper.changeAndroidStatusBar(false); + if (context.mounted && flag == true) { + await showModalBottomSheet( + backgroundColor: DarkColors.bgColor, + context: context, + isScrollControlled: true, + builder: (BuildContext buildContext) => CheckPage(checkCallback: (bool isCheck) async { + if (isCheck) { + String? data = await Global.getWalletDataByAddress(wallet.address); + if (data != null && context.mounted) { + send(data, args.address, wallet.address); + } + } + }), + ); + } } }, ), diff --git a/lib/page/detail/transaction_page.dart b/lib/page/detail/transaction_page.dart index 8b7cf53..42a7f02 100644 --- a/lib/page/detail/transaction_page.dart +++ b/lib/page/detail/transaction_page.dart @@ -1,11 +1,11 @@ import 'package:dio/dio.dart'; import 'package:extended_text/extended_text.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:xdag/common/color.dart'; import 'package:xdag/common/helper.dart'; import 'package:xdag/model/wallet_modal.dart'; +import 'package:xdag/widget/button.dart'; import 'package:xdag/widget/desktop.dart'; import 'package:xdag/widget/modal_frame.dart'; import 'package:xdag/common/global.dart'; @@ -25,6 +25,7 @@ class _TransactionPageState extends State { String otherAddress = ""; String fee = ""; String hash = ""; + String transactionState = 'Pending'; double height = 430; final dio = Dio(); @@ -49,7 +50,11 @@ class _TransactionPageState extends State { bool isSend = transaction.from == address; Response response = await dio.get("${Global.explorURL}/block/${widget.transaction.blockAddress}", cancelToken: cancelToken); String newFee = ""; + String newTransactionState = "Pending"; String newOtherAddress = ""; + if (response.data['state'] != null) { + newTransactionState = response.data['state']; + } if (response.data['block_as_transaction'] != null) { for (var i = 0; i < response.data["block_as_transaction"].length; i++) { var item = response.data["block_as_transaction"][i]; @@ -73,7 +78,9 @@ class _TransactionPageState extends State { otherAddress = newOtherAddress; fee = Helper.removeTrailingZeros(newFee.toString()); hash = response.data['hash']; + transactionState = newTransactionState; }); + // ignore: empty_catches } catch (e) {} } @@ -85,7 +92,15 @@ class _TransactionPageState extends State { return ModalFrame( height: height, title: isSend ? AppLocalizations.of(context).send : AppLocalizations.of(context).receive, - isHideLeftDownButton: true, + rightBtn: CircleButton( + icon: Icons.refresh, + onPressed: () { + if (isLoading) return; + setState(() { + isLoading = true; + }); + fetchData(); + }), isShowRightCloseButton: true, child: Column( children: [ @@ -93,8 +108,14 @@ class _TransactionPageState extends State { const SizedBox(height: 5), if (transaction.status == 'pending') Text( - "${AppLocalizations.of(context).state}: ${AppLocalizations.of(context).pending}", - style: const TextStyle(decoration: TextDecoration.none, fontSize: 14, fontFamily: 'RobotoMono', fontWeight: FontWeight.w400, color: DarkColors.redColor), + "${AppLocalizations.of(context).state}: $transactionState", + style: TextStyle( + decoration: TextDecoration.none, + fontSize: 14, + fontFamily: 'RobotoMono', + fontWeight: FontWeight.w400, + color: transactionState == 'Accepted' ? DarkColors.greenColor : DarkColors.redColor, + ), ) else const SizedBox(), @@ -102,7 +123,7 @@ class _TransactionPageState extends State { const SizedBox() else Text( - "${isSend ? AppLocalizations.of(context).send_on : AppLocalizations.of(context).receive_on} ${Helper.formatFullTime(transaction.time)}", + "${isSend ? AppLocalizations.of(context).send_on : AppLocalizations.of(context).receive_on} ${Helper.formatFullTime(transaction.time)} UTC", style: const TextStyle(decoration: TextDecoration.none, fontSize: 14, fontFamily: 'RobotoMono', fontWeight: FontWeight.w400, color: Colors.white54), ), const SizedBox(height: 25), @@ -171,17 +192,96 @@ class _TransactionPageState extends State { } } +class TransactionShowDetail extends StatelessWidget { + final Transaction transaction; + const TransactionShowDetail({super.key, required this.transaction}); + + @override + Widget build(BuildContext context) { + bool isSameAddress = transaction.from == transaction.to; + return ModalFrame( + height: 430, + title: '', + isHideLeftDownButton: true, + isShowRightCloseButton: true, + child: Column( + children: [ + Expanded( + child: Column( + children: [ + Text('${transaction.amount} XDAG', textAlign: TextAlign.center, style: const TextStyle(decoration: TextDecoration.none, fontSize: 22, fontFamily: 'RobotoMono', fontWeight: FontWeight.w700, color: DarkColors.greenColor)), + const SizedBox(height: 20), + TransactionButton( + showCopy: false, + readFont: isSameAddress, + borderRadius: const BorderRadius.only(topLeft: Radius.circular(8), topRight: Radius.circular(8)), + title: AppLocalizations.of(context).receiver, + value: transaction.to, + ), + const SizedBox(height: 1), + TransactionButton( + showCopy: false, + readFont: isSameAddress, + borderRadius: BorderRadius.zero, + title: AppLocalizations.of(context).sender, + value: transaction.from, + ), + const SizedBox(height: 1), + TransactionButton( + showCopy: false, + title: AppLocalizations.of(context).fee, + value: '0.00 XDAG', + ), + const SizedBox(height: 1), + TransactionButton( + showCopy: false, + title: AppLocalizations.of(context).remark, + value: transaction.remark, + borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8)), + ), + ], + )), + Container( + margin: EdgeInsets.fromLTRB(15, 20, 15, ScreenHelper.bottomPadding > 0 ? ScreenHelper.bottomPadding : 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Button( + text: AppLocalizations.of(context).send, + width: ScreenHelper.screenWidth - 30, + bgColor: DarkColors.mainColor, + textColor: Colors.white, + onPressed: () async { + Navigator.of(context).pop(true); + }, + ), + ], + ), + ), + ], + ), + ); + } +} + class TransactionButton extends StatelessWidget { final String title; final String value; final BorderRadiusGeometry borderRadius; final bool showCopy; - const TransactionButton({super.key, required this.title, required this.value, required this.showCopy, this.borderRadius = const BorderRadius.all(Radius.circular(0))}); + final bool readFont; + const TransactionButton({super.key, required this.title, required this.value, required this.showCopy, this.readFont = false, this.borderRadius = const BorderRadius.all(Radius.circular(0))}); @override Widget build(BuildContext context) { TextStyle titleStyle = const TextStyle(decoration: TextDecoration.none, fontSize: 16, fontFamily: 'RobotoMono', fontWeight: FontWeight.w400, color: Colors.white54); - TextStyle valueStyle = const TextStyle(decoration: TextDecoration.none, fontSize: 12, fontFamily: 'RobotoMono', fontWeight: FontWeight.w700, color: Colors.white); + TextStyle valueStyle = TextStyle( + decoration: TextDecoration.none, + fontSize: 12, + fontFamily: 'RobotoMono', + fontWeight: FontWeight.w700, + color: readFont ? DarkColors.redColor : Colors.white, + ); Widget icon = showCopy == true ? Container( margin: const EdgeInsets.only(left: 5), diff --git a/lib/page/wallet/contacts_page.dart b/lib/page/wallet/contacts_page.dart index 048354e..7545ce0 100644 --- a/lib/page/wallet/contacts_page.dart +++ b/lib/page/wallet/contacts_page.dart @@ -61,8 +61,6 @@ class ContactsMainPage extends StatelessWidget { isScrollControlled: true, builder: (BuildContext buildContext) => const AddContactsPage(), ); - // ContactsItem? item = contacts.contactsList.get(0); - // contacts.changeContacts(item: item!, name: '123', address: '123'); }, ), ], @@ -172,7 +170,7 @@ class ContactsMainPage extends StatelessWidget { Navigator.pushNamed( context, '/send', - arguments: SendPageRouteParams(address: item.address), + arguments: SendPageRouteParams(address: item.address, name: item.name), ); } } diff --git a/lib/page/wallet/wallet_page.dart b/lib/page/wallet/wallet_page.dart index 592784a..27a632e 100644 --- a/lib/page/wallet/wallet_page.dart +++ b/lib/page/wallet/wallet_page.dart @@ -1,5 +1,4 @@ import 'package:dio/dio.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:xdag/common/color.dart'; @@ -100,6 +99,7 @@ class _WalletPageState extends State { fee: 0, remark: item["remark"] ?? "", )); + // ignore: empty_catches } catch (e) {} } List allList = currentPage == 1 ? newList : list + newList; diff --git a/lib/widget/create_wallet_widget.dart b/lib/widget/create_wallet_widget.dart index 2f22da8..b1dff3a 100644 --- a/lib/widget/create_wallet_widget.dart +++ b/lib/widget/create_wallet_widget.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:xdag/common/color.dart'; import 'package:xdag/common/helper.dart'; diff --git a/lib/widget/home_button.dart b/lib/widget/home_button.dart index eb6af00..0c74a06 100644 --- a/lib/widget/home_button.dart +++ b/lib/widget/home_button.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:xdag/common/color.dart'; import 'package:xdag/widget/desktop.dart'; diff --git a/lib/widget/home_transaction_item.dart b/lib/widget/home_transaction_item.dart index 346a0f3..e9fdac8 100644 --- a/lib/widget/home_transaction_item.dart +++ b/lib/widget/home_transaction_item.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:xdag/common/color.dart'; import 'package:xdag/common/helper.dart'; @@ -68,7 +67,7 @@ class WalletTransactionItem extends StatelessWidget { children: [ Text(isSnapshot ? AppLocalizations.of(context).snapshot : (isSend ? AppLocalizations.of(context).send : AppLocalizations.of(context).receive), style: const TextStyle(decoration: TextDecoration.none, fontSize: 14, fontFamily: 'RobotoMono', fontWeight: FontWeight.w500, color: Colors.white)), const SizedBox(height: 3), - Text(Helper.formatTime(transaction.time), style: const TextStyle(decoration: TextDecoration.none, fontSize: 12, fontFamily: 'RobotoMono', fontWeight: FontWeight.w400, color: Colors.white54)), + Text('${Helper.formatTime(transaction.time)} UTC', style: const TextStyle(decoration: TextDecoration.none, fontSize: 12, fontFamily: 'RobotoMono', fontWeight: FontWeight.w400, color: Colors.white54)), ], ), ), diff --git a/lib/widget/label_button.dart b/lib/widget/label_button.dart index 54b2d9d..0d20e52 100644 --- a/lib/widget/label_button.dart +++ b/lib/widget/label_button.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:xdag/common/color.dart'; import 'package:xdag/widget/desktop.dart'; diff --git a/lib/widget/modal_frame.dart b/lib/widget/modal_frame.dart index cfd6966..813f627 100644 --- a/lib/widget/modal_frame.dart +++ b/lib/widget/modal_frame.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:xdag/common/color.dart'; import 'package:xdag/common/helper.dart'; @@ -31,7 +30,8 @@ class ModalFrame extends StatelessWidget { final double? height; final bool? isHideLeftDownButton; final bool? isShowRightCloseButton; - const ModalFrame({super.key, required this.child, required this.title, this.height, this.isHideLeftDownButton, this.isShowRightCloseButton}); + final Widget? rightBtn; + const ModalFrame({super.key, required this.child, required this.title, this.height, this.isHideLeftDownButton, this.isShowRightCloseButton, this.rightBtn}); @override Widget build(BuildContext context) { @@ -39,7 +39,7 @@ class ModalFrame extends StatelessWidget { double screenHeight = ScreenHelper.screenHeight; double topPadding = ScreenHelper.topPadding; Widget leftButton = isHideLeftDownButton != null && isHideLeftDownButton == true ? const SizedBox(width: 40) : CircleButton(icon: Icons.expand_more, onPressed: () => Navigator.pop(context)); - Widget rightButton = isShowRightCloseButton != null && isShowRightCloseButton == true ? CircleButton(icon: Icons.close_rounded, onPressed: () => Navigator.pop(context)) : const SizedBox(width: 40); + Widget rightButton = rightBtn ?? (isShowRightCloseButton != null && isShowRightCloseButton == true ? CircleButton(icon: Icons.close_rounded, onPressed: () => Navigator.pop(context)) : const SizedBox(width: 40)); return Container( decoration: const BoxDecoration( color: DarkColors.bgColor, diff --git a/lib/widget/nav_header.dart b/lib/widget/nav_header.dart index ef6f30d..40c0df6 100644 --- a/lib/widget/nav_header.dart +++ b/lib/widget/nav_header.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:xdag/common/color.dart'; import 'package:xdag/common/helper.dart'; diff --git a/lib/widget/security.dart b/lib/widget/security.dart index 379c67e..734223d 100644 --- a/lib/widget/security.dart +++ b/lib/widget/security.dart @@ -1,6 +1,4 @@ import 'dart:io'; - -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; diff --git a/lib/widget/wallet_header.dart b/lib/widget/wallet_header.dart index f182123..cd33d99 100644 --- a/lib/widget/wallet_header.dart +++ b/lib/widget/wallet_header.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; diff --git a/macos/Podfile.lock b/macos/Podfile.lock index ff457c1..a8312d8 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -7,19 +7,25 @@ PODS: - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS + - screen_retriever (0.0.1): + - FlutterMacOS - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS - url_launcher_macos (0.0.1): - FlutterMacOS + - window_manager (0.2.0): + - FlutterMacOS DEPENDENCIES: - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`) + - screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) + - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`) EXTERNAL SOURCES: flutter_secure_storage_macos: @@ -30,18 +36,24 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos path_provider_foundation: :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos + screen_retriever: + :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos shared_preferences_foundation: :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos url_launcher_macos: :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos + window_manager: + :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos SPEC CHECKSUMS: flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 + screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38 shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472 url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451 + window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7