diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml index 2dbedcba9..64adea1e7 100644 --- a/android/app/src/main/AndroidManifestBase.xml +++ b/android/app/src/main/AndroidManifestBase.xml @@ -46,8 +46,14 @@ + + + + + + map) : this.id = map['id'] == null ? 0 : int.parse(map['id'] as String), - this.label = (map['label'] ?? '') as String; + this.label = (map['label'] ?? '') as String, + this.balance = (map['balance'] ?? '0.00') as String; final int id; final String label; + final String? balance; } \ No newline at end of file diff --git a/cw_monero/lib/monero_account_list.dart b/cw_monero/lib/monero_account_list.dart index f618cf57a..2fd11b3ba 100644 --- a/cw_monero/lib/monero_account_list.dart +++ b/cw_monero/lib/monero_account_list.dart @@ -1,6 +1,8 @@ +import 'package:cw_core/monero_amount_format.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/account.dart'; import 'package:cw_monero/api/account_list.dart' as account_list; +import 'package:cw_monero/api/wallet.dart' as monero_wallet; part 'monero_account_list.g.dart'; @@ -41,12 +43,16 @@ abstract class MoneroAccountListBase with Store { } } - List getAll() => account_list - .getAllAccount() - .map((accountRow) => Account( - id: accountRow.getId(), - label: accountRow.getLabel())) - .toList(); + List getAll() => account_list.getAllAccount().map((accountRow) { + final accountIndex = accountRow.getId(); + final balance = monero_wallet.getFullBalance(accountIndex: accountIndex); + + return Account( + id: accountRow.getId(), + label: accountRow.getLabel(), + balance: moneroAmountToString(amount: balance), + ); + }).toList(); Future addAccount({required String label}) async { await account_list.addAccount(label: label); @@ -54,8 +60,7 @@ abstract class MoneroAccountListBase with Store { } Future setLabelAccount({required int accountIndex, required String label}) async { - await account_list.setLabelForAccount( - accountIndex: accountIndex, label: label); + await account_list.setLabelForAccount(accountIndex: accountIndex, label: label); update(); } diff --git a/ios/Runner/InfoBase.plist b/ios/Runner/InfoBase.plist index 794391665..13a2c24df 100644 --- a/ios/Runner/InfoBase.plist +++ b/ios/Runner/InfoBase.plist @@ -42,6 +42,26 @@ bitcoin + + CFBundleTypeRole + Editor + CFBundleURLName + bitcoin-wallet + CFBundleURLSchemes + + bitcoin-wallet + + + + CFBundleTypeRole + Editor + CFBundleURLName + bitcoin_wallet + CFBundleURLSchemes + + bitcoin_wallet + + CFBundleTypeRole Editor @@ -52,6 +72,26 @@ monero + + CFBundleTypeRole + Editor + CFBundleURLName + monero-wallet + CFBundleURLSchemes + + monero-wallet + + + + CFBundleTypeRole + Editor + CFBundleURLName + monero_wallet + CFBundleURLSchemes + + monero_wallet + + CFBundleTypeRole Editor @@ -62,6 +102,26 @@ litecoin + + CFBundleTypeRole + Viewer + CFBundleURLName + litecoin-wallet + CFBundleURLSchemes + + litecoin-wallet + + + + CFBundleTypeRole + Viewer + CFBundleURLName + litecoin_wallet + CFBundleURLSchemes + + litecoin_wallet + + CFBundleVersion $(CURRENT_PROJECT_VERSION) diff --git a/lib/monero/cw_monero.dart b/lib/monero/cw_monero.dart index 48c0c51a4..5dfe2e467 100644 --- a/lib/monero/cw_monero.dart +++ b/lib/monero/cw_monero.dart @@ -10,7 +10,7 @@ class CWMoneroAccountList extends MoneroAccountList { final moneroWallet = _wallet as MoneroWallet; final accounts = moneroWallet.walletAddresses.accountList .accounts - .map((acc) => Account(id: acc.id, label: acc.label)) + .map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance)) .toList(); return ObservableList.of(accounts); } @@ -32,7 +32,7 @@ class CWMoneroAccountList extends MoneroAccountList { final moneroWallet = wallet as MoneroWallet; return moneroWallet.walletAddresses.accountList .getAll() - .map((acc) => Account(id: acc.id, label: acc.label)) + .map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance)) .toList(); } @@ -122,7 +122,7 @@ class CWMoneroWalletDetails extends MoneroWalletDetails { Account get account { final moneroWallet = _wallet as MoneroWallet; final acc = moneroWallet.walletAddresses.account; - return Account(id: acc!.id, label: acc.label); + return Account(id: acc!.id, label: acc.label, balance: acc.balance); } @computed @@ -316,13 +316,13 @@ class CWMonero extends Monero { Account getCurrentAccount(Object wallet) { final moneroWallet = wallet as MoneroWallet; final acc = moneroWallet.walletAddresses.account; - return Account(id: acc!.id, label: acc.label); + return Account(id: acc!.id, label: acc.label, balance: acc.balance); } @override - void setCurrentAccount(Object wallet, int id, String label) { + void setCurrentAccount(Object wallet, int id, String label, String? balance) { final moneroWallet = wallet as MoneroWallet; - moneroWallet.walletAddresses.account = monero_account.Account(id: id, label: label); + moneroWallet.walletAddresses.account = monero_account.Account(id: id, label: label, balance: balance); } @override diff --git a/lib/src/screens/dashboard/widgets/address_page.dart b/lib/src/screens/dashboard/widgets/address_page.dart index 82430f0c6..465c494d1 100644 --- a/lib/src/screens/dashboard/widgets/address_page.dart +++ b/lib/src/screens/dashboard/widgets/address_page.dart @@ -59,17 +59,16 @@ class AddressPage extends BasePage { bool effectsInstalled = false; - @override - Color get titleColor => Colors.white; - @override Widget? leading(BuildContext context) { - final _backButton = Icon(Icons.arrow_back_ios, - color: titleColor, + final _backButton = Icon( + Icons.arrow_back_ios, + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!, size: 16, ); final _closeButton = currentTheme.type == ThemeType.dark - ? closeButtonImageDarkTheme : closeButtonImage; + ? closeButtonImageDarkTheme + : closeButtonImage; bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context); @@ -84,7 +83,7 @@ class AddressPage extends BasePage { child: TextButton( style: ButtonStyle( overlayColor: MaterialStateColor.resolveWith( - (states) => Colors.transparent), + (states) => Colors.transparent), ), onPressed: () => onClose(context), child: !isMobileView ? _closeButton : _backButton, diff --git a/lib/src/screens/monero_accounts/monero_account_list_page.dart b/lib/src/screens/monero_accounts/monero_account_list_page.dart index cb2fe0f2d..09a08a425 100644 --- a/lib/src/screens/monero_accounts/monero_account_list_page.dart +++ b/lib/src/screens/monero_accounts/monero_account_list_page.dart @@ -88,13 +88,16 @@ class MoneroAccountListPage extends StatelessWidget { itemBuilder: (context, index) { final account = accounts[index]; - return AccountTile( - isCurrent: account.isSelected, - accountName: account.label, - onTap: () { - if (account.isSelected) { - return; - } + return AccountTile( + isCurrent: account.isSelected, + accountName: account.label, + accountBalance: account.balance ?? '0.00', + currency: accountListViewModel + .currency.toString(), + onTap: () { + if (account.isSelected) { + return; + } accountListViewModel .select(account); diff --git a/lib/src/screens/monero_accounts/widgets/account_tile.dart b/lib/src/screens/monero_accounts/widgets/account_tile.dart index 5e50c7f75..c214fa4e2 100644 --- a/lib/src/screens/monero_accounts/widgets/account_tile.dart +++ b/lib/src/screens/monero_accounts/widgets/account_tile.dart @@ -1,45 +1,68 @@ import 'package:flutter/material.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:cake_wallet/generated/i18n.dart'; class AccountTile extends StatelessWidget { AccountTile({ required this.isCurrent, required this.accountName, + this.accountBalance, + required this.currency, required this.onTap, required this.onEdit }); final bool isCurrent; final String accountName; + final String? accountBalance; + final String currency; final Function() onTap; final Function() onEdit; @override Widget build(BuildContext context) { final color = isCurrent - ? Theme.of(context).textTheme!.subtitle2!.decorationColor! - : Theme.of(context).textTheme!.headline1!.decorationColor!; + ? Theme.of(context).textTheme.subtitle2!.decorationColor! + : Theme.of(context).textTheme.headline1!.decorationColor!; final textColor = isCurrent - ? Theme.of(context).textTheme!.subtitle2!.color! - : Theme.of(context).textTheme!.headline1!.color!; + ? Theme.of(context).textTheme.subtitle2!.color! + : Theme.of(context).textTheme.headline1!.color!; final Widget cell = GestureDetector( onTap: onTap, child: Container( height: 77, padding: EdgeInsets.only(left: 24, right: 24), - alignment: Alignment.centerLeft, color: color, - child: Text( - accountName, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - fontFamily: 'Lato', - color: textColor, - decoration: TextDecoration.none, - ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 2, + child: Text( + accountName, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + fontFamily: 'Lato', + color: textColor, + decoration: TextDecoration.none, + ), + ), + ), + if (accountBalance != null) + Expanded( + child: Text( + '${accountBalance.toString()} $currency', + textAlign: TextAlign.end, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w600, + fontFamily: 'Lato', + color: Theme.of(context).textTheme.headline4!.color!, + decoration: TextDecoration.none, + ), + ), + ), + ], ), ), ); diff --git a/lib/src/screens/receive/fullscreen_qr_page.dart b/lib/src/screens/receive/fullscreen_qr_page.dart index 4bde38710..2fcc24e2c 100644 --- a/lib/src/screens/receive/fullscreen_qr_page.dart +++ b/lib/src/screens/receive/fullscreen_qr_page.dart @@ -71,7 +71,10 @@ class FullscreenQRPage extends BasePage { padding: EdgeInsets.all(10), decoration: BoxDecoration( border: Border.all(width: 3, color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!)), - child: QrImage(data: qrViewData.data, version: qrViewData.version), + child: Container( + decoration: BoxDecoration( + border: Border.all(width: 3, color: Colors.white)), + child: QrImage(data: qrViewData.data, version: qrViewData.version)), ), ), ), diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart index 00a157d97..1dd4b8585 100644 --- a/lib/src/screens/receive/receive_page.dart +++ b/lib/src/screens/receive/receive_page.dart @@ -53,7 +53,8 @@ class ReceivePage extends BasePage { final FocusNode _cryptoAmountFocus; @override - Color get titleColor => Colors.white; + Color? get titleColor => + currentTheme.type == ThemeType.bright ? Colors.white : null; @override Widget middle(BuildContext context) { diff --git a/lib/src/screens/receive/widgets/qr_image.dart b/lib/src/screens/receive/widgets/qr_image.dart index c8cc622c4..c624ad3c0 100644 --- a/lib/src/screens/receive/widgets/qr_image.dart +++ b/lib/src/screens/receive/widgets/qr_image.dart @@ -16,7 +16,7 @@ class QrImage extends StatelessWidget { @override Widget build(BuildContext context) { - return qr.QrImage( + return qr.QrImageView( data: data, errorCorrectionLevel: errorCorrectionLevel, version: version ?? 9, // Previous value: 7 something happened after flutter upgrade monero wallets addresses are longer than ver. 7 ??? diff --git a/lib/src/screens/receive/widgets/qr_widget.dart b/lib/src/screens/receive/widgets/qr_widget.dart index fc58d4cec..33cc3d598 100644 --- a/lib/src/screens/receive/widgets/qr_widget.dart +++ b/lib/src/screens/receive/widgets/qr_widget.dart @@ -86,7 +86,14 @@ class QRWidget extends StatelessWidget { Theme.of(context).accentTextTheme.headline2!.backgroundColor!, ), ), - child: QrImage(data: addressListViewModel.uri.toString()), + child: Container( + decoration: BoxDecoration( + border: Border.all( + width: 3, + color:Colors.white, + ), + ), + child: QrImage(data: addressListViewModel.uri.toString())), ), ), ), diff --git a/lib/src/screens/restore/restore_options_page.dart b/lib/src/screens/restore/restore_options_page.dart index c08d2b7e4..93a44c752 100644 --- a/lib/src/screens/restore/restore_options_page.dart +++ b/lib/src/screens/restore/restore_options_page.dart @@ -25,7 +25,7 @@ class RestoreOptionsPage extends BasePage { final bool isNewInstall; final imageSeedKeys = Image.asset('assets/images/restore_wallet_image.png'); final imageBackup = Image.asset('assets/images/backup.png'); - final qrCode = Image.asset('assets/images/qr_code_icon.png'); + final qrCode = Image.asset('assets/images/restore_qr.png'); @override Widget body(BuildContext context) { diff --git a/lib/src/screens/send/widgets/confirm_sending_alert.dart b/lib/src/screens/send/widgets/confirm_sending_alert.dart index a034d801e..3d5f5c928 100644 --- a/lib/src/screens/send/widgets/confirm_sending_alert.dart +++ b/lib/src/screens/send/widgets/confirm_sending_alert.dart @@ -142,10 +142,8 @@ class ConfirmSendingAlertContentState extends State required this.feeValue, required this.feeFiatAmount, required this.outputs}) - : itemCount = 0, - recipientTitle = '' { - itemCount = outputs.length; - recipientTitle = itemCount > 1 + : recipientTitle = '' { + recipientTitle = outputs.length > 1 ? S.current.transaction_details_recipient_address : S.current.recipient_address; } @@ -165,7 +163,6 @@ class ConfirmSendingAlertContentState extends State ScrollController controller = ScrollController(); double fromTop = 0; String recipientTitle; - int itemCount; bool showScrollbar = false; @override @@ -342,12 +339,12 @@ class ConfirmSendingAlertContentState extends State decoration: TextDecoration.none, ), ), - itemCount > 1 + outputs.length > 1 ? ListView.builder( padding: EdgeInsets.only(top: 0), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), - itemCount: itemCount, + itemCount: outputs.length, itemBuilder: (context, index) { final item = outputs[index]; final _address = item.isParsedAddress diff --git a/lib/src/screens/wallet_keys/wallet_keys_page.dart b/lib/src/screens/wallet_keys/wallet_keys_page.dart index da58c4b31..c1c2e6fb5 100644 --- a/lib/src/screens/wallet_keys/wallet_keys_page.dart +++ b/lib/src/screens/wallet_keys/wallet_keys_page.dart @@ -11,6 +11,7 @@ import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/widgets/list_row.dart'; import 'package:cake_wallet/view_model/wallet_keys_view_model.dart'; import 'package:cake_wallet/routes.dart'; +import 'package:qr_flutter/qr_flutter.dart'; class WalletKeysPage extends BasePage { WalletKeysPage(this.walletKeysViewModel); @@ -32,7 +33,7 @@ class WalletKeysPage extends BasePage { await Navigator.pushNamed( context, Routes.fullscreenQR, - arguments: QrViewData(data: url.toString()), + arguments: QrViewData(data: url.toString(), version: QrVersions.auto), ); // ignore: unawaited_futures DeviceDisplayBrightness.setBrightness(brightness); diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart index bf36b129b..dce7e2ccf 100644 --- a/lib/src/screens/wallet_list/wallet_list_page.dart +++ b/lib/src/screens/wallet_list/wallet_list_page.dart @@ -24,6 +24,9 @@ class WalletListPage extends BasePage { final WalletListViewModel walletListViewModel; final AuthService authService; + @override + String get title => S.current.wallets; + @override Widget body(BuildContext context) => WalletListBody(walletListViewModel: walletListViewModel, authService: authService); diff --git a/lib/view_model/monero_account_list/account_list_item.dart b/lib/view_model/monero_account_list/account_list_item.dart index e6fc17252..10b2480c3 100644 --- a/lib/view_model/monero_account_list/account_list_item.dart +++ b/lib/view_model/monero_account_list/account_list_item.dart @@ -1,10 +1,9 @@ -import 'package:flutter/foundation.dart'; - class AccountListItem { AccountListItem( - {required this.label, required this.id, this.isSelected = false}); + {required this.label, required this.id, this.balance, this.isSelected = false}); final String label; final int id; final bool isSelected; + final String? balance; } diff --git a/lib/view_model/monero_account_list/monero_account_list_view_model.dart b/lib/view_model/monero_account_list/monero_account_list_view_model.dart index c9caa118e..4cbf95bab 100644 --- a/lib/view_model/monero_account_list/monero_account_list_view_model.dart +++ b/lib/view_model/monero_account_list/monero_account_list_view_model.dart @@ -1,3 +1,4 @@ +import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/wallet_base.dart'; @@ -21,6 +22,8 @@ abstract class MoneroAccountListViewModelBase with Store { this.scrollOffsetFromTop = scrollOffsetFromTop; } + CryptoCurrency get currency => _wallet.currency; + @computed List get accounts { if (_wallet.type == WalletType.haven) { @@ -39,6 +42,7 @@ abstract class MoneroAccountListViewModelBase with Store { .accounts.map((acc) => AccountListItem( label: acc.label, id: acc.id, + balance: acc.balance, isSelected: acc.id == monero!.getCurrentAccount(_wallet).id)) .toList(); } @@ -53,7 +57,9 @@ abstract class MoneroAccountListViewModelBase with Store { monero!.setCurrentAccount( _wallet, item.id, - item.label); + item.label, + item.balance, + ); } if (_wallet.type == WalletType.haven) { diff --git a/lib/view_model/restore/wallet_restore_from_qr_code.dart b/lib/view_model/restore/wallet_restore_from_qr_code.dart index 9ebf01429..c4b772f9c 100644 --- a/lib/view_model/restore/wallet_restore_from_qr_code.dart +++ b/lib/view_model/restore/wallet_restore_from_qr_code.dart @@ -51,6 +51,7 @@ class WalletRestoreFromQRCode { static String getFormattedUri(String code) { final index = code.indexOf(':'); + if (index == -1) return throw Exception('Unexpected wallet type: $code, try to scan again'); final scheme = code.substring(0, index).replaceAll('_', '-'); final query = code.substring(index + 1).replaceAll('?', '&'); final formattedUri = '$scheme:?$query'; diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 58de6edab..0d6aa36e8 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -6,7 +6,11 @@ dependencies: flutter_cupertino_localizations: ^1.0.1 intl: ^0.17.0 url_launcher: ^6.1.4 - qr_flutter: ^4.0.0 + qr_flutter: + git: + url: https://github.com/cake-tech/qr.flutter.git + ref: cake-4.0.2 + version: 4.0.2 uuid: 3.0.6 shared_preferences: ^2.0.15 flutter_secure_storage: diff --git a/tool/configure.dart b/tool/configure.dart index c556f2f86..8dcb0f0d7 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -158,9 +158,10 @@ import 'package:cw_monero/pending_monero_transaction.dart'; const moneroCwPart = "part 'cw_monero.dart';"; const moneroContent = """ class Account { - Account({required this.id, required this.label}); + Account({required this.id, required this.label, this.balance}); final int id; final String label; + final String? balance; } class Subaddress { @@ -246,7 +247,7 @@ abstract class Monero { double formatterMoneroAmountToDouble({required int amount}); int formatterMoneroParseAmount({required String amount}); Account getCurrentAccount(Object wallet); - void setCurrentAccount(Object wallet, int id, String label); + void setCurrentAccount(Object wallet, int id, String label, String? balance); void onStartup(); int getTransactionInfoAccountId(TransactionInfo tx); WalletService createMoneroWalletService(Box walletInfoSource);