mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-26 06:08:40 +01:00
cw-1584-ironwood-migration-modal (#3481)
* ironwood migration modal * auto-show when migration begins * remove restricted import * new condition * string fix * only activate if ironwood is active * reaction safeguards * migration*
This commit is contained in:
@@ -145,4 +145,5 @@ class PreferencesKey {
|
||||
static const backgroundImage = 'background_image';
|
||||
static const mwebAdDismissed = "mweb_ad_dismissed";
|
||||
static const balanceHideCounter = "balance_hide_counter";
|
||||
static const zcashMigrationModalViewed = "zcash_migration_modal_viewed";
|
||||
}
|
||||
|
||||
@@ -13,10 +13,14 @@ import 'package:cake_wallet/new-ui/widgets/coins_page/mweb_ad.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/top_bar_widget/top_bar.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/unconfirmed_balance_widget.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/coins_page/wallet_info.dart';
|
||||
import "package:cake_wallet/new-ui/widgets/coins_page/zcash_migration_modal.dart";
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart';
|
||||
import "package:cw_core/amount/money.dart";
|
||||
import "package:cw_core/crypto_currency.dart";
|
||||
import "package:cw_core/transaction_direction.dart";
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@@ -48,6 +52,24 @@ class _NewHomePageState extends State<NewHomePage> {
|
||||
_lightningMode = false;
|
||||
});
|
||||
});
|
||||
|
||||
reaction((_) => widget.dashboardViewModel.isMigratingToIronwood, (val) {
|
||||
if (val && !widget.dashboardViewModel.settingsStore.zcashMigrationModalViewed) {
|
||||
if(!context.mounted) {
|
||||
return;
|
||||
}
|
||||
widget.dashboardViewModel.settingsStore.zcashMigrationModalViewed = true;
|
||||
showMaterialModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) => ZcashMigrationModal(
|
||||
hasContinue: true,
|
||||
balance: widget.dashboardViewModel.wallet.balance.values.first.unavailable
|
||||
.toStringWithSymbol(),
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _setAccountViewModel() {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import "package:cake_wallet/new-ui/widgets/coins_page/zcash_migration_modal.dart";
|
||||
import 'package:cake_wallet/new-ui/widgets/new_primary_button.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
|
||||
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
|
||||
@@ -21,6 +23,7 @@ class UnconfirmedBalanceWidget extends StatelessWidget {
|
||||
return Observer(builder: (_) {
|
||||
final show = dashboardViewModel.balanceViewModel
|
||||
.hasAdditionalBalance(dashboardViewModel.wallet.currency);
|
||||
final isIronwoodMigration = dashboardViewModel.isMigratingToIronwood;
|
||||
|
||||
return AnimatedSize(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
@@ -44,13 +47,17 @@ class UnconfirmedBalanceWidget extends StatelessWidget {
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
final modal = isIronwoodMigration
|
||||
? ZcashMigrationModal(
|
||||
hasContinue: false, balance: "${balance} ${currency.symbol}")
|
||||
: UnconfirmedBalanceModal(
|
||||
balance: balance.toStringWithSymbol(),
|
||||
currencyIconPath: currency.iconPath ?? "",
|
||||
);
|
||||
showMaterialModalBottomSheet(
|
||||
backgroundColor: Colors.transparent,
|
||||
context: context,
|
||||
builder: (context) => UnconfirmedBalanceModal(
|
||||
balance: balance.toStringWithSymbol(),
|
||||
currencyIconPath: currency.iconPath ?? "",
|
||||
));
|
||||
builder: (context) => modal);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
@@ -63,8 +70,12 @@ class UnconfirmedBalanceWidget extends StatelessWidget {
|
||||
SizedBox(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
child: isIronwoodMigration
|
||||
? CupertinoActivityIndicator(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
)
|
||||
: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.primary.withAlpha(50),
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
@@ -80,7 +91,7 @@ class UnconfirmedBalanceWidget extends StatelessWidget {
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
Text(S.of(context).confirming),
|
||||
Text(isIronwoodMigration ? S.of(context).migrating_to_ironwood : S.of(context).confirming),
|
||||
],
|
||||
)
|
||||
],
|
||||
@@ -172,3 +183,4 @@ class UnconfirmedBalanceModal extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
import "package:cake_wallet/generated/i18n.dart";
|
||||
import "package:cake_wallet/new-ui/widgets/new_primary_button.dart";
|
||||
import "package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart";
|
||||
import "package:cake_wallet/src/widgets/cake_image_widget.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:url_launcher/url_launcher.dart";
|
||||
|
||||
class ZcashMigrationModal extends StatelessWidget {
|
||||
const ZcashMigrationModal({required this.hasContinue, required this.balance, super.key});
|
||||
|
||||
final String balance;
|
||||
final bool hasContinue;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => SafeArea(
|
||||
bottom: false,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),),
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: Column(
|
||||
children: [
|
||||
ModalTopBar(
|
||||
title: S.of(context).zcash_network_upgrade,
|
||||
trailingIcon: const Icon(Icons.close),
|
||||
onTrailingPressed: Navigator.of(context).pop,
|
||||
trailingSemanticLabel: S.of(context).close,
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
spacing: 40,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 146,
|
||||
height: 79,
|
||||
child: Stack(
|
||||
children: [
|
||||
const Positioned(
|
||||
left: 67,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: CakeImageWidget(
|
||||
imageUrl: "assets/new-ui/ironwood_migration.svg",
|
||||
width: 75,
|
||||
height: 75,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
child: Container(
|
||||
width: 79,
|
||||
height: 79,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(99999999),
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
width: 4,),),
|
||||
child: const CakeImageWidget(
|
||||
imageUrl: "assets/new-ui/crypto_full_icons/zcash.svg",
|
||||
height: 75,
|
||||
width: 75,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Text(
|
||||
balance,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.primary,),
|
||||
),
|
||||
Text(S.of(context).is_currently_being_migrated),
|
||||
],
|
||||
),
|
||||
),),
|
||||
RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: "${S.of(context).zcash_network_upgrade_desc_1}\n\n",
|
||||
style: Theme.of(context).textTheme.bodyMedium,),
|
||||
TextSpan(
|
||||
text: "${S.of(context).zcash_network_upgrade_desc_2}\n\n",
|
||||
style: Theme.of(context).textTheme.bodyMedium,),
|
||||
TextSpan(
|
||||
text: "${S.of(context).zcash_network_upgrade_desc_3}\n\n",
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: const Color(0xFFF9C03C),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
NewPrimaryButton(
|
||||
onPressed: _launchDocs,
|
||||
text: S.of(context).learn_more,
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
textColor: Theme.of(context).colorScheme.primary,),
|
||||
if (hasContinue)
|
||||
NewPrimaryButton(
|
||||
onPressed: Navigator.of(context).pop,
|
||||
text: S.of(context).continue_text,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
textColor: Theme.of(context).colorScheme.onPrimary,),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
void _launchDocs() {
|
||||
try {
|
||||
launchUrl(Uri.parse("https://docs.cakewallet.com/cryptos/zcash/ironwood-migration"));
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
@@ -151,6 +151,7 @@ abstract class SettingsStoreBase with Store {
|
||||
required this.mwebNodeUri,
|
||||
required this.mwebAdDismissed,
|
||||
required this.balanceHideCounter,
|
||||
required this.zcashMigrationModalViewed,
|
||||
required bool initialEnableAutomaticNodeSwitching,
|
||||
required String initialBackgroundImage,
|
||||
TransactionPriority? initialBitcoinTransactionPriority,
|
||||
@@ -766,6 +767,9 @@ abstract class SettingsStoreBase with Store {
|
||||
(int balanceHideCounter) =>
|
||||
_sharedPreferences.setInt(PreferencesKey.balanceHideCounter, balanceHideCounter));
|
||||
|
||||
reaction((_) => zcashMigrationModalViewed,
|
||||
(val) => _sharedPreferences.setBool(PreferencesKey.zcashMigrationModalViewed, val));
|
||||
|
||||
this.nodes.observe((change) {
|
||||
if (change.newValue != null && change.key != null) {
|
||||
_saveCurrentNode(change.newValue!, change.key!);
|
||||
@@ -1075,6 +1079,9 @@ abstract class SettingsStoreBase with Store {
|
||||
@observable
|
||||
bool mwebAdDismissed;
|
||||
|
||||
@observable
|
||||
bool zcashMigrationModalViewed;
|
||||
|
||||
final SecureStorage _secureStorage;
|
||||
final SharedPreferences _sharedPreferences;
|
||||
|
||||
@@ -1350,6 +1357,7 @@ abstract class SettingsStoreBase with Store {
|
||||
final enableAutomaticNodeSwitching =
|
||||
sharedPreferences.getBool(PreferencesKey.enableAutomaticNodeSwitching) ?? true;
|
||||
final backgroundImage = sharedPreferences.getString(PreferencesKey.backgroundImage) ?? '';
|
||||
final zcashMigrationModalViewed = sharedPreferences.getBool(PreferencesKey.zcashMigrationModalViewed) ?? false;
|
||||
|
||||
// If no value
|
||||
if (pinLength == null || pinLength == 0) {
|
||||
@@ -1762,6 +1770,7 @@ abstract class SettingsStoreBase with Store {
|
||||
initialBuiltinTor: builtinTor,
|
||||
mwebAdDismissed: mwebAdDismissed,
|
||||
balanceHideCounter: balanceHideCounter,
|
||||
zcashMigrationModalViewed: zcashMigrationModalViewed
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
isShowFirstYatIntroduction = false,
|
||||
isShowSecondYatIntroduction = false,
|
||||
isShowThirdYatIntroduction = false,
|
||||
isMigratingToIronwood = false,
|
||||
filterItems = [],
|
||||
exchangeFilterItems = [],
|
||||
subname = '',
|
||||
@@ -250,6 +251,8 @@ abstract class DashboardViewModelBase with Store {
|
||||
|
||||
reaction((_) => tradesStore.trades, (_) => tradeMonitor.monitorActiveTrades(wallet.id));
|
||||
|
||||
addZcashMigrationReaction();
|
||||
|
||||
tradeMonitor.monitorActiveTrades(wallet.id);
|
||||
}
|
||||
|
||||
@@ -374,6 +377,22 @@ abstract class DashboardViewModelBase with Store {
|
||||
);
|
||||
}
|
||||
|
||||
@observable
|
||||
ReactionDisposer? zcashMigrationReactionDisposer;
|
||||
|
||||
@action
|
||||
void addZcashMigrationReaction() {
|
||||
zcashMigrationReactionDisposer?.reaction.dispose();
|
||||
zcashMigrationReactionDisposer = null;
|
||||
|
||||
if (wallet.type == WalletType.zcash) {
|
||||
zcashMigrationReactionDisposer = reaction((_) => wallet.balance.values.first, (_) async {
|
||||
isMigratingToIronwood =
|
||||
wallet.type == WalletType.zcash && await zcash!.hasOrchardMigratableBalance(wallet);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@computed
|
||||
bool get isSyncHeavy {
|
||||
if ([
|
||||
@@ -1270,6 +1289,8 @@ abstract class DashboardViewModelBase with Store {
|
||||
name = wallet.name;
|
||||
loadFilterItems();
|
||||
|
||||
addZcashMigrationReaction();
|
||||
|
||||
if (wallet.type == WalletType.monero) {
|
||||
subname = monero!.getCurrentAccount(wallet).label;
|
||||
|
||||
@@ -1551,6 +1572,9 @@ abstract class DashboardViewModelBase with Store {
|
||||
}
|
||||
}
|
||||
|
||||
@observable
|
||||
bool isMigratingToIronwood;
|
||||
|
||||
String getTransactionType(TransactionInfo tx) {
|
||||
if (wallet.type == WalletType.bitcoin) {
|
||||
if (tx.isReplaced == true) return ' (replaced)';
|
||||
|
||||
@@ -213,6 +213,11 @@ class CWZcash extends Zcash {
|
||||
bool ironwoodActive(WalletAddresses walletAddresses) {
|
||||
return (walletAddresses as ZcashWalletAddresses).ironwoodActive;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> hasOrchardMigratableBalance(WalletBase wallet) {
|
||||
return (wallet as ZcashWallet).hasOrchardMigratableBalance();
|
||||
}
|
||||
}
|
||||
|
||||
const wordList = [
|
||||
|
||||
Reference in New Issue
Block a user