Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cat-voices): wallet link details empty balance #907

Merged
merged 4 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:catalyst_cardano/catalyst_cardano.dart';
import 'package:catalyst_cardano_serialization/catalyst_cardano_serialization.dart';
import 'package:catalyst_voices/widgets/widgets.dart';
import 'package:catalyst_voices_assets/catalyst_voices_assets.dart';
import 'package:catalyst_voices_blocs/catalyst_voices_blocs.dart';
Expand All @@ -10,15 +11,19 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class WalletDetailsPanel extends StatelessWidget {
final Coin minAdaForRegistration;
final CardanoWalletDetails details;

const WalletDetailsPanel({
super.key,
required this.minAdaForRegistration,
required this.details,
});

@override
Widget build(BuildContext context) {
final hasEnoughBalance = details.balance >= minAdaForRegistration;

return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expand All @@ -35,9 +40,12 @@ class WalletDetailsPanel extends StatelessWidget {
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 24),
_WalletSummary(details: details),
_WalletSummary(details: details, hasEnoughBalance: hasEnoughBalance),
const Spacer(),
const _Navigation(),
if (hasEnoughBalance)
const _Navigation()
else
const _NotEnoughBalanceNavigation(),
],
);
}
Expand Down Expand Up @@ -71,8 +79,12 @@ class _WalletExtension extends StatelessWidget {

class _WalletSummary extends StatelessWidget {
final CardanoWalletDetails details;
final bool hasEnoughBalance;

const _WalletSummary({required this.details});
const _WalletSummary({
required this.details,
required this.hasEnoughBalance,
});

@override
Widget build(BuildContext context) {
Expand All @@ -92,27 +104,106 @@ class _WalletSummary extends StatelessWidget {
context.l10n.walletDetectionSummary,
style: Theme.of(context).textTheme.titleSmall,
),
const SizedBox(height: 16),
_WalletSummaryItem(
label: Text(context.l10n.walletBalance),
value: Text(CryptocurrencyFormatter.formatAmount(details.balance)),
const SizedBox(height: 12),
_WalletSummaryBalance(
details: details,
hasEnoughBalance: hasEnoughBalance,
),
const SizedBox(height: 12),
_WalletSummaryItem(
label: Text(context.l10n.walletAddress),
value: Row(
children: [
Text(WalletAddressFormatter.formatShort(details.address)),
const SizedBox(width: 6),
InkWell(
onTap: () async {
await Clipboard.setData(
ClipboardData(text: details.address.toBech32()),
);
},
child: VoicesAssets.icons.clipboardCopy.buildIcon(size: 16),
),
],
_WalletSummaryAddress(details: details),
if (!hasEnoughBalance) ...[
const SizedBox(height: 12),
Text(
context.l10n.notice,
style: Theme.of(context).textTheme.labelSmall!.copyWith(
fontWeight: FontWeight.w800,
),
),
const SizedBox(height: 6),
Text(
context.l10n.walletLinkWalletDetailsNotice,
style: Theme.of(context).textTheme.labelSmall,
),
const SizedBox(height: 6),
Text(
context.l10n.walletLinkWalletDetailsNoticeTopUp,
style: Theme.of(context).textTheme.labelSmall!.copyWith(
fontWeight: FontWeight.w800,
),
),
const SizedBox(height: 6),
Text(
context.l10n.walletLinkWalletDetailsNoticeTopUpLink,
style: Theme.of(context).textTheme.labelSmall,
),
],
],
),
);
}
}

class _WalletSummaryBalance extends StatelessWidget {
final CardanoWalletDetails details;
final bool hasEnoughBalance;

const _WalletSummaryBalance({
required this.details,
required this.hasEnoughBalance,
});

@override
Widget build(BuildContext context) {
return _WalletSummaryItem(
label: Text(context.l10n.walletBalance),
value: Row(
children: [
Text(
CryptocurrencyFormatter.formatAmount(details.balance),
style: hasEnoughBalance
? null
: TextStyle(color: Theme.of(context).colors.iconsError),
),
if (!hasEnoughBalance) ...[
const SizedBox(width: 4),
Padding(
padding: const EdgeInsets.only(top: 2),
child: VoicesAssets.icons.exclamation.buildIcon(
color: Theme.of(context).colors.iconsError,
size: 16,
),
),
],
],
),
);
}
}

class _WalletSummaryAddress extends StatelessWidget {
final CardanoWalletDetails details;

const _WalletSummaryAddress({
required this.details,
});

@override
Widget build(BuildContext context) {
return _WalletSummaryItem(
label: Text(context.l10n.walletAddress),
value: Row(
children: [
Text(WalletAddressFormatter.formatShort(details.address)),
const SizedBox(width: 4),
InkWell(
onTap: () async {
await Clipboard.setData(
ClipboardData(text: details.address.toBech32()),
);
},
child: Padding(
padding: const EdgeInsets.only(top: 2),
child: VoicesAssets.icons.clipboardCopy.buildIcon(size: 16),
),
),
],
Expand All @@ -136,18 +227,15 @@ class _WalletSummaryItem extends StatelessWidget {
children: [
Expanded(
child: DefaultTextStyle(
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontWeight: FontWeight.bold,
height: 1,
style: Theme.of(context).textTheme.labelMedium!.copyWith(
fontWeight: FontWeight.w800,
),
child: label,
),
),
Expanded(
child: DefaultTextStyle(
style: Theme.of(context).textTheme.bodySmall!.copyWith(
height: 1,
),
style: Theme.of(context).textTheme.labelMedium!,
child: value,
),
),
Expand All @@ -156,6 +244,19 @@ class _WalletSummaryItem extends StatelessWidget {
}
}

class _NotEnoughBalanceNavigation extends StatelessWidget {
const _NotEnoughBalanceNavigation();

@override
Widget build(BuildContext context) {
return VoicesTextButton(
leading: VoicesAssets.icons.wallet.buildIcon(),
onTap: () => RegistrationCubit.of(context).previousStep(),
child: Text(context.l10n.chooseOtherWallet),
);
}
}

class _Navigation extends StatelessWidget {
const _Navigation();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ class WalletLinkPanel extends StatelessWidget {
WalletLinkStage.selectWallet => SelectWalletPanel(
walletsResult: stateData.wallets,
),
WalletLinkStage.walletDetails =>
WalletDetailsPanel(details: stateData.selectedWallet!),
WalletLinkStage.walletDetails => WalletDetailsPanel(
minAdaForRegistration: stateData.minAdaForRegistration,
details: stateData.selectedWallet!,
),
WalletLinkStage.rolesChooser => const RolesChooserPanel(),
WalletLinkStage.rolesSummary => const RolesSummaryPanel(),
WalletLinkStage.rbacTransaction => const RbacTransactionPanel(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class WalletLinkCubit extends Cubit<WalletLink> {

_stateData = _stateData.copyWith(wallets: Optional(Success(wallets)));
} on Exception catch (error, stackTrace) {
_logger.severe(error, stackTrace);
_logger.severe('refreshWallets', error, stackTrace);
_stateData = _stateData.copyWith(wallets: Optional(Failure(error)));
}
}
Expand All @@ -59,7 +59,7 @@ final class WalletLinkCubit extends Cubit<WalletLink> {

emit(nextState);
} catch (error, stackTrace) {
_logger.severe(error, stackTrace);
_logger.severe('selectWallet', error, stackTrace);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:catalyst_cardano/catalyst_cardano.dart';
import 'package:catalyst_cardano_serialization/catalyst_cardano_serialization.dart';
import 'package:catalyst_voices_models/catalyst_voices_models.dart';
import 'package:equatable/equatable.dart';
import 'package:result_type/result_type.dart';
Expand All @@ -12,6 +13,9 @@ final class WalletLinkStateData extends Equatable {
this.selectedWallet,
});

/// Returns the minimum required ADA in user balance to register.
Coin get minAdaForRegistration => CardanoWalletDetails.minAdaForRegistration;

WalletLinkStateData copyWith({
Optional<Result<List<CardanoWallet>, Exception>>? wallets,
Optional<CardanoWalletDetails>? selectedWallet,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,12 @@ abstract class VoicesLocalizations {
/// **'Choose Cardano Wallet'**
String get chooseCardanoWallet;

/// A button label to select another cardano wallet.
///
/// In en, this message translates to:
/// **'Choose other wallet'**
String get chooseOtherWallet;

/// A label on a clickable element that can show more content.
///
/// In en, this message translates to:
Expand Down Expand Up @@ -736,6 +742,24 @@ abstract class VoicesLocalizations {
/// **'{wallet} connected successfully!'**
String walletLinkWalletDetailsContent(String wallet);

/// A message in link wallet flow on wallet details screen when a user wallet doesn't have enough balance.
///
/// In en, this message translates to:
/// **'Wallet and role registrations require a minimal transaction fee. You can setup your default dApp connector wallet in your browser extension settings.'**
String get walletLinkWalletDetailsNotice;

/// A message recommending the user to top up ADA in wallet link on wallet details screen.
///
/// In en, this message translates to:
/// **'Top up ADA'**
String get walletLinkWalletDetailsNoticeTopUp;

/// A link to top-up provide when the user doesn't have enough balance on wallet link screen
///
/// In en, this message translates to:
/// **'• Link to top-up provider'**
String get walletLinkWalletDetailsNoticeTopUpLink;

/// Message shown when redirecting to external content that describes which wallets are supported.
///
/// In en, this message translates to:
Expand Down Expand Up @@ -982,6 +1006,12 @@ abstract class VoicesLocalizations {
/// **'Close'**
String get close;

/// No description provided for @notice.
///
/// In en, this message translates to:
/// **'Notice'**
String get notice;

/// A title on keychain deleted dialog
///
/// In en, this message translates to:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,9 @@ class VoicesLocalizationsEn extends VoicesLocalizations {
@override
String get chooseCardanoWallet => 'Choose Cardano Wallet';

@override
String get chooseOtherWallet => 'Choose other wallet';

@override
String get learnMore => 'Learn More';

Expand Down Expand Up @@ -384,6 +387,15 @@ class VoicesLocalizationsEn extends VoicesLocalizations {
return '$wallet connected successfully!';
}

@override
String get walletLinkWalletDetailsNotice => 'Wallet and role registrations require a minimal transaction fee. You can setup your default dApp connector wallet in your browser extension settings.';

@override
String get walletLinkWalletDetailsNoticeTopUp => 'Top up ADA';

@override
String get walletLinkWalletDetailsNoticeTopUpLink => '• Link to top-up provider';

@override
String get seeAllSupportedWallets => 'See all supported wallets';

Expand Down Expand Up @@ -507,6 +519,9 @@ class VoicesLocalizationsEn extends VoicesLocalizations {
@override
String get close => 'Close';

@override
String get notice => 'Notice';

@override
String get keychainDeletedDialogTitle => 'Catalyst keychain removed';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,9 @@ class VoicesLocalizationsEs extends VoicesLocalizations {
@override
String get chooseCardanoWallet => 'Choose Cardano Wallet';

@override
String get chooseOtherWallet => 'Choose other wallet';

@override
String get learnMore => 'Learn More';

Expand Down Expand Up @@ -384,6 +387,15 @@ class VoicesLocalizationsEs extends VoicesLocalizations {
return '$wallet connected successfully!';
}

@override
String get walletLinkWalletDetailsNotice => 'Wallet and role registrations require a minimal transaction fee. You can setup your default dApp connector wallet in your browser extension settings.';

@override
String get walletLinkWalletDetailsNoticeTopUp => 'Top up ADA';

@override
String get walletLinkWalletDetailsNoticeTopUpLink => '• Link to top-up provider';

@override
String get seeAllSupportedWallets => 'See all supported wallets';

Expand Down Expand Up @@ -507,6 +519,9 @@ class VoicesLocalizationsEs extends VoicesLocalizations {
@override
String get close => 'Close';

@override
String get notice => 'Notice';

@override
String get keychainDeletedDialogTitle => 'Catalyst keychain removed';

Expand Down
Loading
Loading