diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart index 4c3c4c968..ae615bd96 100644 --- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart +++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart @@ -11,6 +11,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:share_plus/share_plus.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/utilities/address_utils.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/clipboard_interface.dart'; import 'package:stackwallet/utilities/constants.dart'; @@ -101,25 +102,28 @@ class _GenerateUriQrCodeViewState extends State { return null; } - String query = ""; + Map queryParams = {}; if (amountString.isNotEmpty) { - query += "amount=$amountString"; + queryParams["amount"] = amountString; } if (noteString.isNotEmpty) { - if (query.isNotEmpty) { - query += "&"; - } - query += "message=$noteString"; + queryParams["message"] = noteString; } - final uri = Uri( - scheme: widget.coin.uriScheme, - host: widget.receivingAddress, - query: query.isNotEmpty ? query : null, - ); + String receivingAddress = widget.receivingAddress; + if ((widget.coin == Coin.bitcoincash || + widget.coin == Coin.bitcoincashTestnet) && + receivingAddress.contains(":")) { + // remove cash addr prefix + receivingAddress = receivingAddress.split(":").sublist(1).join(); + } - final uriString = uri.toString().replaceFirst("://", ":"); + final uriString = AddressUtils.buildUriString( + widget.coin, + receivingAddress, + queryParams, + ); Logging.instance.log("Generated receiving QR code for: $uriString", level: LogLevel.Info); @@ -229,10 +233,21 @@ class _GenerateUriQrCodeViewState extends State { @override void initState() { isDesktop = Util.isDesktop; - _uriString = Uri( - scheme: widget.coin.uriScheme, - host: widget.receivingAddress, - ).toString().replaceFirst("://", ":"); + + String receivingAddress = widget.receivingAddress; + if ((widget.coin == Coin.bitcoincash || + widget.coin == Coin.bitcoincashTestnet) && + receivingAddress.contains(":")) { + // remove cash addr prefix + receivingAddress = receivingAddress.split(":").sublist(1).join(); + } + + _uriString = AddressUtils.buildUriString( + widget.coin, + receivingAddress, + {}, + ); + amountController = TextEditingController(); noteController = TextEditingController(); super.initState(); diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart index a237d9ea9..dbf46c729 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart @@ -20,6 +20,8 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/loading_indicator.dart'; @@ -500,14 +502,73 @@ class _RestoreFromFileViewState extends ConsumerState { return; } - await Navigator.of(context).push( - RouteGenerator.getRoute( - builder: (_) => - StackRestoreProgressView( - jsonString: jsonString, - ), - ), - ); + await showDialog( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return DesktopDialog( + maxHeight: 750, + maxWidth: 600, + child: LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: + constraints.maxHeight, + ), + child: IntrinsicHeight( + child: Column( + mainAxisAlignment: + MainAxisAlignment + .start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Padding( + padding: + const EdgeInsets + .all(32), + child: Text( + "Restoring Stack Wallet", + style: STextStyles + .desktopH3( + context), + textAlign: + TextAlign + .center, + ), + ), + const DesktopDialogCloseButton(), + ], + ), + const SizedBox( + height: 30, + ), + Padding( + padding: EdgeInsets + .symmetric( + horizontal: + 32), + child: + StackRestoreProgressView( + jsonString: + jsonString, + ), + ), + ], + ), + ), + ), + ); + }, + ), + ); + }); } }, ), diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart index 3097ec72a..4e8d60662 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart @@ -3,7 +3,6 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:stackwallet/pages/home_view/home_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/dialogs/cancel_stack_restore_dialog.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart'; @@ -18,6 +17,8 @@ import 'package:stackwallet/utilities/enums/stack_restoring_status.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart'; import 'package:stackwallet/widgets/loading_indicator.dart'; @@ -40,6 +41,8 @@ class StackRestoreProgressView extends ConsumerStatefulWidget { class _StackRestoreProgressViewState extends ConsumerState { + bool isDesktop = Util.isDesktop; + Future _cancel() async { bool shouldPop = false; unawaited(showDialog( @@ -80,10 +83,15 @@ class _StackRestoreProgressViewState await SWB.cancelRestore(); shouldPop = true; + + int count = 0; + if (mounted) { - Navigator.of(context).popUntil(ModalRoute.withName(widget.fromFile - ? RestoreFromEncryptedStringView.routeName - : StackBackupView.routeName)); + !isDesktop + ? Navigator.of(context).popUntil(ModalRoute.withName(widget.fromFile + ? RestoreFromEncryptedStringView.routeName + : StackBackupView.routeName)) + : Navigator.of(context).popUntil((_) => count++ >= 2); } } @@ -181,281 +189,289 @@ class _StackRestoreProgressViewState @override Widget build(BuildContext context) { - return WillPopScope( - onWillPop: _onWillPop, - child: Scaffold( - backgroundColor: Theme.of(context).extension()!.background, - appBar: AppBar( - leading: AppBarBackButton( - onPressed: () async { - if (FocusScope.of(context).hasFocus) { - FocusScope.of(context).unfocus(); - await Future.delayed(const Duration(milliseconds: 75)); - } - if (_success) { - _addWalletsToHomeView(); - if (mounted) { - Navigator.of(context).pop(); - } - } else { - if (await _requestCancel()) { - await _cancel(); - } - } - }, - ), - title: Text( - "Restoring Stack wallet", - style: STextStyles.navBarTitle(context), - ), - ), - body: Padding( - padding: const EdgeInsets.only( - left: 12, - top: 12, - right: 12, - ), - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.only( - left: 4, - top: 4, - right: 4, - bottom: 0, + bool isDesktop = Util.isDesktop; + + return ConditionalParent( + condition: !isDesktop, + builder: (child) { + return WillPopScope( + onWillPop: _onWillPop, + child: Scaffold( + backgroundColor: + Theme.of(context).extension()!.background, + appBar: AppBar( + leading: AppBarBackButton( + onPressed: () async { + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future.delayed( + const Duration(milliseconds: 75)); + } + if (_success) { + _addWalletsToHomeView(); + if (mounted) { + Navigator.of(context).pop(); + } + } else { + if (await _requestCancel()) { + await _cancel(); + } + } + }, ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Settings", - style: STextStyles.itemSubtitle(context), - ), - const SizedBox( - height: 12, - ), - Consumer( - builder: (_, ref, __) { - final state = ref.watch(stackRestoringUIStateProvider - .select((value) => value.preferences)); - return RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), + title: Text( + "Restoring Stack wallet", + style: STextStyles.navBarTitle(context), + ), + ), + body: Padding( + padding: const EdgeInsets.only( + left: 12, + top: 12, + right: 12, + ), + child: child, + ), + ), + ); + }, + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.only( + left: 4, + top: 4, + right: 4, + bottom: 0, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Settings", + style: STextStyles.itemSubtitle(context), + ), + const SizedBox( + height: 12, + ), + Consumer( + builder: (_, ref, __) { + final state = ref.watch(stackRestoringUIStateProvider + .select((value) => value.preferences)); + return RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.gear, + width: 16, + height: 16, color: Theme.of(context) .extension()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.gear, - width: 16, - height: 16, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Preferences", - subTitle: state == StackRestoringStatus.failed - ? Text( - "Something went wrong", - style: STextStyles.errorSmall(context), - ) - : null, - ); - }, - ), - const SizedBox( - height: 12, - ), - Consumer( - builder: (_, ref, __) { - final state = ref.watch(stackRestoringUIStateProvider - .select((value) => value.addressBook)); - return RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension()! - .buttonBackSecondary, - child: Center( - child: AddressBookIcon( - width: 16, - height: 16, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Address book", - subTitle: state == StackRestoringStatus.failed - ? Text( - "Something went wrong", - style: STextStyles.errorSmall(context), - ) - : null, - ); - }, - ), - const SizedBox( - height: 12, - ), - Consumer( - builder: (_, ref, __) { - final state = ref.watch(stackRestoringUIStateProvider - .select((value) => value.nodes)); - return RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.node, - width: 16, - height: 16, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Nodes", - subTitle: state == StackRestoringStatus.failed - ? Text( - "Something went wrong", - style: STextStyles.errorSmall(context), - ) - : null, - ); - }, - ), - const SizedBox( - height: 12, - ), - Consumer( - builder: (_, ref, __) { - final state = ref.watch(stackRestoringUIStateProvider - .select((value) => value.trades)); - return RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.arrowRotate2, - width: 16, - height: 16, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Exchange history", - subTitle: state == StackRestoringStatus.failed - ? Text( - "Something went wrong", - style: STextStyles.errorSmall(context), - ) - : null, - ); - }, - ), - const SizedBox( - height: 16, - ), - Text( - "Wallets", - style: STextStyles.itemSubtitle(context), - ), - const SizedBox( - height: 8, - ), - ...ref - .watch(stackRestoringUIStateProvider - .select((value) => value.walletStateProviders)) - .values - .map( - (provider) => Padding( - padding: const EdgeInsets.symmetric(vertical: 4), - child: RestoringWalletCard( - provider: provider, + .accentColorDark, ), ), ), - const SizedBox( - height: 80, + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Preferences", + subTitle: state == StackRestoringStatus.failed + ? Text( + "Something went wrong", + style: STextStyles.errorSmall(context), + ) + : null, + ); + }, + ), + const SizedBox( + height: 12, + ), + Consumer( + builder: (_, ref, __) { + final state = ref.watch(stackRestoringUIStateProvider + .select((value) => value.addressBook)); + return RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + child: Center( + child: AddressBookIcon( + width: 16, + height: 16, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Address book", + subTitle: state == StackRestoringStatus.failed + ? Text( + "Something went wrong", + style: STextStyles.errorSmall(context), + ) + : null, + ); + }, + ), + const SizedBox( + height: 12, + ), + Consumer( + builder: (_, ref, __) { + final state = ref.watch(stackRestoringUIStateProvider + .select((value) => value.nodes)); + return RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.node, + width: 16, + height: 16, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Nodes", + subTitle: state == StackRestoringStatus.failed + ? Text( + "Something went wrong", + style: STextStyles.errorSmall(context), + ) + : null, + ); + }, + ), + const SizedBox( + height: 12, + ), + Consumer( + builder: (_, ref, __) { + final state = ref.watch(stackRestoringUIStateProvider + .select((value) => value.trades)); + return RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.arrowRotate2, + width: 16, + height: 16, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Exchange history", + subTitle: state == StackRestoringStatus.failed + ? Text( + "Something went wrong", + style: STextStyles.errorSmall(context), + ) + : null, + ); + }, + ), + const SizedBox( + height: 16, + ), + Text( + "Wallets", + style: STextStyles.itemSubtitle(context), + ), + const SizedBox( + height: 8, + ), + ...ref + .watch(stackRestoringUIStateProvider + .select((value) => value.walletStateProviders)) + .values + .map( + (provider) => Padding( + padding: const EdgeInsets.symmetric(vertical: 4), + child: RestoringWalletCard( + provider: provider, + ), + ), ), - ], + const SizedBox( + height: 30, ), - ), - ), - ), - floatingActionButton: SizedBox( - width: MediaQuery.of(context).size.width - 32, - child: TextButton( - onPressed: () async { - if (_success) { - _addWalletsToHomeView(); - Navigator.of(context) - .popUntil(ModalRoute.withName(HomeView.routeName)); - } else { - if (await _requestCancel()) { - await _cancel(); - } - } - }, - style: Theme.of(context) - .extension()! - .getPrimaryEnabledButtonColor(context), - child: Text( - _success ? "OK" : "Cancel restore process", - style: STextStyles.button(context).copyWith( - color: Theme.of(context) - .extension()! - .buttonTextPrimary, + SizedBox( + width: MediaQuery.of(context).size.width - 32, + child: TextButton( + onPressed: () async { + if (_success) { + Navigator.of(context).pop(); + } else { + if (await _requestCancel()) { + await _cancel(); + } + } + }, + style: Theme.of(context) + .extension()! + .getPrimaryEnabledButtonColor(context), + child: Text( + _success ? "OK" : "Cancel restore process", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension()! + .buttonTextPrimary, + ), + ), + ), ), - ), + ], ), ), ), diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart deleted file mode 100644 index 7f944847d..000000000 --- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart +++ /dev/null @@ -1,171 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:stackwallet/utilities/assets.dart'; -import 'package:stackwallet/utilities/text_styles.dart'; -import 'package:stackwallet/utilities/theme/stack_colors.dart'; -import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; -import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; -import 'package:stackwallet/widgets/desktop/secondary_button.dart'; -import 'package:stackwallet/widgets/rounded_white_container.dart'; - -class RestoreBackupDialog extends StatelessWidget { - const RestoreBackupDialog({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return DesktopDialog( - maxHeight: 750, - maxWidth: 600, - child: LayoutBuilder( - builder: (context, constraints) { - return SingleChildScrollView( - child: ConstrainedBox( - constraints: BoxConstraints( - minHeight: constraints.maxHeight, - ), - child: IntrinsicHeight( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.all(32), - child: Text( - "Restoring Stack Wallet", - style: STextStyles.desktopH3(context), - textAlign: TextAlign.center, - ), - ), - const DesktopDialogCloseButton(), - ], - ), - const SizedBox( - height: 30, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 32), - child: Row( - children: [ - Text( - "Settings", - style: STextStyles.desktopTextExtraSmall(context) - .copyWith( - color: Theme.of(context) - .extension()! - .textDark3, - ), - textAlign: TextAlign.left, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 32, vertical: 12), - child: RoundedWhiteContainer( - borderColor: Theme.of(context) - .extension()! - .background, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - SvgPicture.asset( - Assets.svg.framedAddressBook, - width: 40, - height: 40, - ), - const SizedBox(width: 12), - Text( - "Address Book", - style: - STextStyles.desktopTextSmall(context), - ), - ], - ), - - ///TODO: CHECKMARK ANIMATION - ], - ), - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 32, vertical: 12), - child: RoundedWhiteContainer( - borderColor: Theme.of(context) - .extension()! - .background, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - SvgPicture.asset( - Assets.svg.framedGear, - width: 40, - height: 40, - ), - const SizedBox(width: 12), - Text( - "Preferences", - style: - STextStyles.desktopTextSmall(context), - ), - ], - ), - - ///TODO: CHECKMARK ANIMATION - ], - ), - ), - ), - const SizedBox( - height: 30, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 32), - child: Row( - children: [ - Text( - "Wallets", - style: STextStyles.desktopTextExtraSmall(context) - .copyWith( - color: Theme.of(context) - .extension()! - .textDark3, - ), - textAlign: TextAlign.left, - ), - ], - ), - ), - const Spacer(), - Padding( - padding: const EdgeInsets.all(32), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - SecondaryButton( - desktopMed: true, - width: 200, - label: "Cancel restore process", - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ), - ), - ], - ), - ), - ), - ); - }, - )); - } -} diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart index 95294c8aa..48212bde8 100644 --- a/lib/utilities/enums/coin_enum.dart +++ b/lib/utilities/enums/coin_enum.dart @@ -132,7 +132,7 @@ extension CoinExt on Coin { case Coin.litecoinTestNet: return "litecoin"; case Coin.bitcoincashTestnet: - return "bitcoincash"; + return "bchtest"; case Coin.firoTestNet: return "firo"; case Coin.dogecoinTestNet: diff --git a/pubspec.yaml b/pubspec.yaml index 86f24330b..19d38ca4f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.14+86 +version: 1.5.16+88 environment: sdk: ">=2.17.0 <3.0.0"