feat: add enable sp card and make setting wallet specific

This commit is contained in:
Rafael Saes 2025-04-28 16:32:36 -03:00
parent ebe7e3e94f
commit fe7e419b42
7 changed files with 158 additions and 15 deletions

View file

@ -36,6 +36,12 @@ part 'bitcoin_wallet.g.dart';
class BitcoinWallet = BitcoinWalletBase with _$BitcoinWallet;
abstract class BitcoinWalletBase extends ElectrumWallet<BitcoinWalletAddresses> with Store {
@observable
bool silentPaymentsIntroDisplay;
@observable
bool silentPaymentsCardDisplay;
@observable
bool nodeSupportsSilentPayments = false;
@ -70,8 +76,12 @@ abstract class BitcoinWalletBase extends ElectrumWallet<BitcoinWalletAddresses>
super.passphrase,
super.initialUnspentCoins,
bool? alwaysScan,
bool? silentPaymentsIntroDisplay,
bool? silentPaymentsCardDisplay,
Map<String, dynamic>? walletAddressesSnapshot,
}) : _alwaysScan = alwaysScan ?? false,
silentPaymentsIntroDisplay = silentPaymentsIntroDisplay ?? true,
silentPaymentsCardDisplay = silentPaymentsCardDisplay ?? true,
super(
currency: network == BitcoinNetwork.testnet ? CryptoCurrency.tbtc : CryptoCurrency.btc,
) {
@ -324,6 +334,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet<BitcoinWalletAddresses>
encryptionFileUtils: encryptionFileUtils,
network: network,
alwaysScan: snp?.alwaysScan,
silentPaymentsIntroDisplay: snp?.silentPaymentsIntroDisplay,
silentPaymentsCardDisplay: snp?.silentPaymentsCardDisplay,
initialUnspentCoins: snp?.unspentCoins,
walletAddressesSnapshot: snp?.walletAddressesSnapshot,
hdWallets: hdWallets,
@ -1482,6 +1494,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet<BitcoinWalletAddresses>
String toJSON() {
final json = jsonDecode(super.toJSON());
json['alwaysScan'] = _alwaysScan;
json['silentPaymentsIntroDisplay'] = silentPaymentsIntroDisplay;
json['silentPaymentsCardDisplay'] = silentPaymentsCardDisplay;
return jsonEncode(json);
}
}

View file

@ -15,6 +15,8 @@ class BitcoinWalletSnapshot extends ElectrumWalletSnapshot {
required super.xpub,
required super.balance,
required this.alwaysScan,
required this.silentPaymentsIntroDisplay,
required this.silentPaymentsCardDisplay,
required super.unspentCoins,
required super.walletAddressesSnapshot,
super.passphrase,
@ -23,6 +25,8 @@ class BitcoinWalletSnapshot extends ElectrumWalletSnapshot {
}) : super();
bool alwaysScan;
bool silentPaymentsIntroDisplay;
bool silentPaymentsCardDisplay;
static Future<BitcoinWalletSnapshot> load(
EncryptionFileUtils encryptionFileUtils,
@ -45,6 +49,8 @@ class BitcoinWalletSnapshot extends ElectrumWalletSnapshot {
);
final alwaysScan = data['alwaysScan'] as bool? ?? false;
final silentPaymentsIntroDisplay = data['silentPaymentsIntroDisplay'] as bool? ?? true;
final silentPaymentsCardDisplay = data['silentPaymentsCardDisplay'] as bool? ?? true;
final walletAddressesSnapshot = data['walletAddresses'] as Map<String, dynamic>? ??
BitcoinWalletAddressesBase.fromSnapshot(data);
@ -61,6 +67,8 @@ class BitcoinWalletSnapshot extends ElectrumWalletSnapshot {
derivationPath: electrumWalletSnapshot.derivationPath,
unspentCoins: electrumWalletSnapshot.unspentCoins,
alwaysScan: alwaysScan,
silentPaymentsIntroDisplay: silentPaymentsIntroDisplay,
silentPaymentsCardDisplay: silentPaymentsCardDisplay,
walletAddressesSnapshot: walletAddressesSnapshot,
);
}

View file

@ -770,4 +770,26 @@ class CWBitcoin extends Bitcoin {
return null;
}
}
bool getSilentPaymentsIntroDisplay(Object wallet) {
final bitcoinWallet = wallet as BitcoinWallet;
return bitcoinWallet.silentPaymentsIntroDisplay;
}
void setSilentPaymentsIntroDisplay(Object wallet, bool val) {
final bitcoinWallet = wallet as BitcoinWallet;
bitcoinWallet.silentPaymentsIntroDisplay = val;
bitcoinWallet.save();
}
bool getSilentPaymentsCardDisplay(Object wallet) {
final bitcoinWallet = wallet as BitcoinWallet;
return bitcoinWallet.silentPaymentsCardDisplay;
}
void setSilentPaymentsCardDisplay(Object wallet, bool val) {
final bitcoinWallet = wallet as BitcoinWallet;
bitcoinWallet.silentPaymentsCardDisplay = val;
bitcoinWallet.save();
}
}

View file

@ -208,6 +208,44 @@ class CryptoBalanceWidget extends StatelessWidget {
"\n\nPlease restart your wallet and if it doesn't help contact our support.",
))
],
if (dashboardViewModel.showSilentPaymentsEnable) ...[
SizedBox(height: 16),
Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
child: InfoCard(
title: S.of(context).silent_payments,
description: S.of(context).silent_payments_description,
leftButtonTitle: S.of(context).litecoin_mweb_dismiss,
rightButtonTitle: S.of(context).enable,
icon: Icon(
Icons.lock,
color:
Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
size: 50,
),
leftButtonAction: () => _dismissSilentPayments(context),
rightButtonAction: () => _enableSilentPayments(context),
hintWidget: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => launchUrl(
Uri.parse("https://docs.cakewallet.com/cryptos/bitcoin#silent-payments"),
mode: LaunchMode.externalApplication,
),
child: Text(
S.of(context).learn_more,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
height: 1,
),
softWrap: true,
),
),
),
),
],
if (dashboardViewModel.showSilentPaymentsCard) ...[
SizedBox(height: 16),
Padding(
@ -353,7 +391,8 @@ class CryptoBalanceWidget extends StatelessWidget {
leftButtonTitle: S.of(context).litecoin_mweb_dismiss,
rightButtonTitle: S.of(context).learn_more,
leftButtonAction: () => dashboardViewModel.dismissDecredInfoCard(),
rightButtonAction: () => launchUrl(Uri.parse("https://docs.cakewallet.com/cryptos/decred/#spv-sync")),
rightButtonAction: () => launchUrl(
Uri.parse("https://docs.cakewallet.com/cryptos/decred/#spv-sync")),
),
),
],
@ -395,4 +434,22 @@ class CryptoBalanceWidget extends StatelessWidget {
));
dashboardViewModel.dismissMweb();
}
Future<void> _enableSilentPayments(BuildContext context) async {
dashboardViewModel.setSilentPaymentsEnabled();
}
Future<void> _dismissSilentPayments(BuildContext context) async {
await showPopUp<void>(
context: context,
builder: (BuildContext context) => AlertWithOneAction(
alertTitle: S.of(context).alert_notice,
alertContent: S.of(context).silent_payments_enable_later,
buttonText: S.of(context).understand,
buttonAction: () {
Navigator.of(context).pop();
},
));
dashboardViewModel.dismissSilentPayments();
}
}

View file

@ -7,7 +7,8 @@ class InfoCard extends StatelessWidget {
final String rightButtonTitle;
final String title;
final String description;
final String image;
final String? image;
final Icon? icon;
final Function() leftButtonAction;
final Function() rightButtonAction;
@ -22,7 +23,8 @@ class InfoCard extends StatelessWidget {
required this.rightButtonTitle,
required this.leftButtonAction,
required this.rightButtonAction,
required this.image,
this.image,
this.icon,
this.hintWidget,
}) : super(key: key);
@ -72,17 +74,18 @@ class InfoCard extends StatelessWidget {
],
),
onTap: () => {},
icon: Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: CakeImageWidget(
imageUrl: image,
height: 40,
width: 40,
),
),
icon: icon ??
Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: CakeImageWidget(
imageUrl: image!,
height: 40,
width: 40,
),
),
);
}
}

View file

@ -489,8 +489,43 @@ abstract class DashboardViewModelBase with Store {
@computed
bool get hasSilentPayments => wallet.type == WalletType.bitcoin && !wallet.isHardwareWallet;
@observable
bool? silentPaymentsEnabled;
@computed
bool get showSilentPaymentsCard => hasSilentPayments && settingsStore.silentPaymentsCardDisplay;
bool get showSilentPaymentsEnable =>
hasSilentPayments &&
silentPaymentsEnabled == null &&
bitcoin!.getSilentPaymentsIntroDisplay(wallet) &&
bitcoin!.getSilentPaymentsCardDisplay(wallet);
@computed
bool get showSilentPaymentsCard =>
hasSilentPayments &&
!showSilentPaymentsEnable &&
bitcoin!.getSilentPaymentsCardDisplay(wallet);
@action
void setSilentPaymentsEnabled() {
if (!hasSilentPayments) {
return;
}
silentPaymentsEnabled = true;
bitcoin!.setSilentPaymentsIntroDisplay(wallet, false);
bitcoin!.setSilentPaymentsCardDisplay(wallet, true);
}
@action
void dismissSilentPayments() {
if (!hasSilentPayments) {
return;
}
silentPaymentsEnabled = false;
bitcoin!.setSilentPaymentsIntroDisplay(wallet, false);
bitcoin!.setSilentPaymentsCardDisplay(wallet, false);
}
final KeyService keyService;
final SharedPreferences sharedPreferences;

View file

@ -295,6 +295,10 @@ abstract class Bitcoin {
bool getMwebEnabled(Object wallet);
String? getUnusedMwebAddress(Object wallet);
String? getUnusedSegwitAddress(Object wallet);
bool getSilentPaymentsIntroDisplay(Object wallet);
void setSilentPaymentsIntroDisplay(Object wallet, bool val);
bool getSilentPaymentsCardDisplay(Object wallet);
void setSilentPaymentsCardDisplay(Object wallet, bool val);
}
""";