mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-22 06:28:39 +02:00
CW-1125-d-euro-ui-enhancements (#2369)
* feat: enhance dEuro Savings UI and functionality with fiat support and tooltips * feat: add "Reinvest Interest" feature and improve dEuro Savings functionality - Implemented the "Reinvest Interest" feature for dEuro Savings. - Updated localized strings for multiple languages. - Enhanced error handling for insufficient gas fees. - Incorporated loading state and tooltips in Savings Card and Interest Card. - Improved UI responsiveness and button state management. * feat: localize deuro tooltips * feat: enhance dEuro Savings with reinvestment feature and localized strings - Added "Reinvest Interest" functionality for dEuro Savings. - Updated localized strings across multiple languages. - Improved modal bottom sheet handling for savings add/remove operations. - Enhanced tooltips and UI responsiveness. * feat: improve dEuro Savings page with info chips and localized strings * Update res/values/strings_de.arb * fix: update dEuro action type reset in transaction handling
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/info_chip.dart';
|
||||
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/interest_card_widget.dart';
|
||||
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/savings_card_widget.dart';
|
||||
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/savings_edit_sheet.dart';
|
||||
@@ -14,9 +15,11 @@ import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
class DEuroSavingsPage extends BasePage {
|
||||
final DEuroViewModel _dEuroViewModel;
|
||||
@@ -44,8 +47,7 @@ class DEuroSavingsPage extends BasePage {
|
||||
child: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: Theme.of(context).colorScheme.onSurface,
|
||||
overlayColor: WidgetStateColor.resolveWith(
|
||||
(states) => Colors.transparent),
|
||||
overlayColor: WidgetStateColor.resolveWith((states) => Colors.transparent),
|
||||
),
|
||||
onPressed: _dEuroViewModel.reloadSavingsUserData,
|
||||
child: Icon(
|
||||
@@ -61,8 +63,7 @@ class DEuroSavingsPage extends BasePage {
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
WidgetsBinding.instance
|
||||
.addPostFrameCallback((_) => _setReactions(context, _dEuroViewModel));
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _setReactions(context, _dEuroViewModel));
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
@@ -73,19 +74,50 @@ class DEuroSavingsPage extends BasePage {
|
||||
isDarkTheme: currentTheme.isDark,
|
||||
interestRate: "${_dEuroViewModel.interestRate}%",
|
||||
savingsBalance: _dEuroViewModel.savingsBalance,
|
||||
fiatSavingsBalance: _dEuroViewModel.fiatSavingsBalance,
|
||||
currency: CryptoCurrency.deuro,
|
||||
fiatCurrency: _dEuroViewModel.isFiatDisabled ? null : _dEuroViewModel.fiat,
|
||||
onAddSavingsPressed: () => _onSavingsAdd(context),
|
||||
onRemoveSavingsPressed: () => _onSavingsRemove(context),
|
||||
onApproveSavingsPressed: _dEuroViewModel.prepareApproval,
|
||||
onTooltipPressed: () => _onSavingsTooltipPressed(context),
|
||||
isEnabled: _dEuroViewModel.isEnabled,
|
||||
isLoading: _dEuroViewModel.isLoading,
|
||||
),
|
||||
),
|
||||
Observer(
|
||||
builder: (_) => InterestCardWidget(
|
||||
isDarkTheme: currentTheme.isDark,
|
||||
title: S.of(context).deuro_savings_collect_interest,
|
||||
collectedInterest: _dEuroViewModel.accruedInterest,
|
||||
fiatAccruedInterest: _dEuroViewModel.fiatAccruedInterest,
|
||||
fiatCurrency: _dEuroViewModel.isFiatDisabled ? null : _dEuroViewModel.fiat,
|
||||
accruedInterest: _dEuroViewModel.accruedInterest,
|
||||
onCollectInterest: _dEuroViewModel.prepareCollectInterest,
|
||||
onReinvestInterest: _dEuroViewModel.prepareReinvestInterest,
|
||||
onTooltipPressed: () => _onInterestTooltipPressed(context),
|
||||
isEnabled: _dEuroViewModel.isEnabled,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(bottom: 30),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
InfoChip(
|
||||
label: S.of(context).deuro_about_deuro,
|
||||
icon: CupertinoIcons.info,
|
||||
onPressed: () => _showWelcomeTooltip(context),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
InfoChip(
|
||||
label: S.of(context).website,
|
||||
icon: CupertinoIcons.globe,
|
||||
onPressed: () => launchUrlString("https://deuro.com/"),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -94,14 +126,12 @@ class DEuroSavingsPage extends BasePage {
|
||||
}
|
||||
|
||||
Future<void> _onSavingsAdd(BuildContext context) async {
|
||||
final amount = await Navigator.of(context).push(MaterialPageRoute<String>(
|
||||
builder: (BuildContext context) => SavingEditPage(isAdding: true)));
|
||||
final amount = await _showEditBottomSheet(context, isAdding: true);
|
||||
if (amount != null) _dEuroViewModel.prepareSavingsEdit(amount, true);
|
||||
}
|
||||
|
||||
Future<void> _onSavingsRemove(BuildContext context) async {
|
||||
final amount = await Navigator.of(context).push(MaterialPageRoute<String>(
|
||||
builder: (BuildContext context) => SavingEditPage(isAdding: false)));
|
||||
final amount = await _showEditBottomSheet(context, isAdding: false);
|
||||
if (amount != null) _dEuroViewModel.prepareSavingsEdit(amount, false);
|
||||
}
|
||||
|
||||
@@ -112,20 +142,41 @@ class DEuroSavingsPage extends BasePage {
|
||||
|
||||
reaction((_) => dEuroViewModel.transaction, (PendingTransaction? tx) async {
|
||||
if (tx == null) return;
|
||||
String title;
|
||||
|
||||
switch (_dEuroViewModel.actionType) {
|
||||
case DEuroActionType.deposit:
|
||||
title = S.of(context).deuro_savings_add;
|
||||
break;
|
||||
case DEuroActionType.withdraw:
|
||||
title = S.of(context).deuro_savings_remove;
|
||||
break;
|
||||
case DEuroActionType.reinvest:
|
||||
title = S.of(context).deuro_reinvest_interest;
|
||||
break;
|
||||
default:
|
||||
title = S.of(context).confirm_transaction;
|
||||
break;
|
||||
}
|
||||
|
||||
final result = await showModalBottomSheet<bool>(
|
||||
context: context,
|
||||
isDismissible: false,
|
||||
isScrollControlled: true,
|
||||
builder: (BuildContext bottomSheetContext) => ConfirmSendingBottomSheet(
|
||||
key: ValueKey('savings_page_confirm_sending_dialog_key'),
|
||||
titleText: S.of(bottomSheetContext).confirm_transaction,
|
||||
titleText: title,
|
||||
currentTheme: currentTheme,
|
||||
walletType: WalletType.ethereum,
|
||||
titleIconPath: CryptoCurrency.deuro.iconPath,
|
||||
currency: CryptoCurrency.deuro,
|
||||
amount: S.of(bottomSheetContext).send_amount,
|
||||
amountValue: tx.amountFormatted,
|
||||
fiatAmountValue: _dEuroViewModel.pendingTransactionFiatAmountFormatted,
|
||||
amountValue: _dEuroViewModel.actionType == DEuroActionType.reinvest
|
||||
? _dEuroViewModel.accruedInterest
|
||||
: tx.amountFormatted,
|
||||
fiatAmountValue: _dEuroViewModel.actionType == DEuroActionType.reinvest
|
||||
? _dEuroViewModel.fiatAccruedInterest
|
||||
: _dEuroViewModel.pendingTransactionFiatAmountFormatted,
|
||||
fee: S.of(bottomSheetContext).send_estimated_fee,
|
||||
feeValue: tx.feeFormatted,
|
||||
feeFiatAmount: _dEuroViewModel.pendingTransactionFeeFiatAmountFormatted,
|
||||
@@ -166,6 +217,7 @@ class DEuroSavingsPage extends BasePage {
|
||||
dEuroViewModel.commitApprovalTransaction();
|
||||
},
|
||||
change: tx.change,
|
||||
explanation: S.of(context).deuro_savings_approve_app_description,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -186,27 +238,29 @@ class DEuroSavingsPage extends BasePage {
|
||||
contentImage: 'assets/images/birthday_cake.png',
|
||||
content: S.of(bottomSheetContext).deuro_tx_commited_content,
|
||||
actionButtonText: S.of(bottomSheetContext).close,
|
||||
actionButtonKey: ValueKey('send_page_sent_dialog_ok_button_key'),
|
||||
actionButtonKey: ValueKey('savings_page_sent_dialog_ok_button_key'),
|
||||
actionButton: () => Navigator.of(bottomSheetContext).pop(),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (state is NoEtherState) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async => await _showNoEthTooltip(context));
|
||||
}
|
||||
|
||||
if (state is FailureState) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
if (!context.mounted) return;
|
||||
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext popupContext) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(popupContext).error,
|
||||
alertContent: state.error,
|
||||
buttonText: S.of(popupContext).ok,
|
||||
buttonAction: () => Navigator.of(popupContext).pop(),
|
||||
);
|
||||
},
|
||||
builder: (BuildContext popupContext) => AlertWithOneAction(
|
||||
alertTitle: S.of(popupContext).error,
|
||||
alertContent: state.error,
|
||||
buttonText: S.of(popupContext).ok,
|
||||
buttonAction: () => Navigator.of(popupContext).pop(),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -214,4 +268,107 @@ class DEuroSavingsPage extends BasePage {
|
||||
|
||||
_isReactionsSet = true;
|
||||
}
|
||||
|
||||
void _onSavingsTooltipPressed(BuildContext context) => _showTooltip(
|
||||
context,
|
||||
title: S.of(context).deuro_savings_balance,
|
||||
content: S.of(context).deuro_savings_balance_tooltip,
|
||||
key: 'savings_tooltip',
|
||||
onLearnMorePressed: () {}, //ToDo
|
||||
);
|
||||
|
||||
void _onInterestTooltipPressed(BuildContext context) => _showTooltip(
|
||||
context,
|
||||
title: S.of(context).deuro_savings_collect_interest,
|
||||
content: S.of(context).deuro_savings_collect_interest_tooltip,
|
||||
key: 'interest_tooltip',
|
||||
onLearnMorePressed: () {}, //ToDo
|
||||
);
|
||||
|
||||
void _showTooltip(
|
||||
BuildContext context, {
|
||||
required String title,
|
||||
required String content,
|
||||
required String key,
|
||||
required VoidCallback onLearnMorePressed,
|
||||
}) {
|
||||
if (!context.mounted) return;
|
||||
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
builder: (BuildContext bottomSheetContext) => InfoBottomSheet(
|
||||
currentTheme: currentTheme,
|
||||
titleText: title,
|
||||
titleIconPath: CryptoCurrency.deuro.iconPath,
|
||||
content: content,
|
||||
isTwoAction: true,
|
||||
rightButtonText: S.of(context).close,
|
||||
rightActionButtonKey: ValueKey('deuro_page_tooltip_dialog_${key}_ok_button_key'),
|
||||
actionRightButton: () => Navigator.of(bottomSheetContext).pop(),
|
||||
leftButtonText: S.of(context).learn_more,
|
||||
leftActionButtonKey: ValueKey('deuro_page_tooltip_dialog_${key}_learn_more_button_key'),
|
||||
actionLeftButton: onLearnMorePressed,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showWelcomeTooltip(BuildContext context) async {
|
||||
if (!context.mounted) return;
|
||||
|
||||
return showModalBottomSheet<void>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (BuildContext bottomSheetContext) => InfoBottomSheet(
|
||||
currentTheme: currentTheme,
|
||||
height: 350,
|
||||
titleText: "dEURO",
|
||||
titleIconPath: CryptoCurrency.deuro.iconPath,
|
||||
contentImage: 'assets/images/deuro_hero.png',
|
||||
contentImageSize: 200,
|
||||
content: S.of(context).deuro_savings_welcome_description,
|
||||
isTwoAction: true,
|
||||
rightButtonText: S.of(context).close,
|
||||
rightActionButtonKey: ValueKey('deuro_page_tooltip_dialog_welcome_ok_button_key'),
|
||||
actionRightButton: () => Navigator.of(bottomSheetContext).pop(),
|
||||
leftButtonText: S.of(context).learn_more,
|
||||
leftActionButtonKey: ValueKey('deuro_page_tooltip_dialog_welcome_learn_more_button_key'),
|
||||
actionLeftButton: () => Navigator.of(bottomSheetContext).pop(), // ToDo
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showNoEthTooltip(BuildContext context) async {
|
||||
if (!context.mounted) return;
|
||||
|
||||
return showModalBottomSheet<void>(
|
||||
context: context,
|
||||
builder: (BuildContext bottomSheetContext) => InfoBottomSheet(
|
||||
currentTheme: currentTheme,
|
||||
titleText: title,
|
||||
titleIconPath: CryptoCurrency.deuro.iconPath,
|
||||
contentImage: 'assets/images/deuro_not_enough_eth.png',
|
||||
content: S.of(context).deuro_tooltip_no_eth,
|
||||
actionButtonKey: ValueKey('deuro_page_tooltip_dialog_no_eth_ok_button_key'),
|
||||
actionButtonText: S.of(context).close,
|
||||
actionButton: () => Navigator.of(bottomSheetContext).pop(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<String?> _showEditBottomSheet(BuildContext context, {bool isAdding = false}) async {
|
||||
if (!context.mounted) return null;
|
||||
|
||||
return showModalBottomSheet<String?>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (BuildContext bottomSheetContext) => SavingsEditSheet(
|
||||
titleText: isAdding ? S.of(context).deuro_savings_add : S.of(context).deuro_savings_remove,
|
||||
titleIconPath: CryptoCurrency.deuro.iconPath,
|
||||
balanceTitle: isAdding
|
||||
? S.of(context).deuro_savings_available_to_add
|
||||
: S.of(context).deuro_savings_available_to_remove,
|
||||
balance: isAdding ? _dEuroViewModel.accountBalance : _dEuroViewModel.savingsBalance,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class InfoChip extends StatelessWidget {
|
||||
final String label;
|
||||
final IconData icon;
|
||||
final VoidCallback onPressed;
|
||||
|
||||
const InfoChip({
|
||||
super.key,
|
||||
required this.label,
|
||||
required this.icon,
|
||||
required this.onPressed,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
),
|
||||
padding: const EdgeInsets.fromLTRB(12, 6, 12, 6),
|
||||
child: InkWell(
|
||||
onTap: onPressed,
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 5),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
label,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/savings_card_widget.dart';
|
||||
import 'package:cake_wallet/themes/utils/custom_theme_colors.dart';
|
||||
@@ -5,63 +6,91 @@ import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class InterestCardWidget extends StatelessWidget {
|
||||
InterestCardWidget({
|
||||
const InterestCardWidget({
|
||||
required this.title,
|
||||
required this.collectedInterest,
|
||||
super.key,
|
||||
required this.accruedInterest,
|
||||
required this.isDarkTheme,
|
||||
required this.isEnabled,
|
||||
required this.onCollectInterest,
|
||||
required this.onReinvestInterest,
|
||||
required this.onTooltipPressed,
|
||||
this.fiatAccruedInterest,
|
||||
this.fiatCurrency,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String collectedInterest;
|
||||
final String accruedInterest;
|
||||
final String? fiatAccruedInterest;
|
||||
final FiatCurrency? fiatCurrency;
|
||||
final bool isDarkTheme;
|
||||
final bool isEnabled;
|
||||
final VoidCallback onCollectInterest;
|
||||
final VoidCallback onReinvestInterest;
|
||||
final VoidCallback onTooltipPressed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(children: [
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 16),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
isDarkTheme
|
||||
? CustomThemeColors.cardGradientColorPrimaryDark
|
||||
: CustomThemeColors.cardGradientColorPrimaryLight,
|
||||
isDarkTheme
|
||||
? CustomThemeColors.cardGradientColorSecondaryDark
|
||||
: CustomThemeColors.cardGradientColorSecondaryLight,
|
||||
],
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
Widget build(BuildContext context) => Stack(children: [
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 16),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
isDarkTheme
|
||||
? CustomThemeColors.cardGradientColorPrimaryDark
|
||||
: CustomThemeColors.cardGradientColorPrimaryLight,
|
||||
isDarkTheme
|
||||
? CustomThemeColors.cardGradientColorSecondaryDark
|
||||
: CustomThemeColors.cardGradientColorSecondaryLight,
|
||||
],
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
SavingsCard.getAssetBalanceRow(
|
||||
context,
|
||||
title: title,
|
||||
amount: accruedInterest,
|
||||
fiatAmount: fiatAccruedInterest,
|
||||
currency: CryptoCurrency.deuro,
|
||||
fiatCurrency: fiatCurrency,
|
||||
hideSymbol: false,
|
||||
onTooltipPressed: onTooltipPressed
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Expanded(
|
||||
child: SavingsCard.getButton(
|
||||
context,
|
||||
imagePath: 'assets/images/collect_interest.png',
|
||||
label: S.of(context).deuro_collect_interest,
|
||||
onPressed: onCollectInterest,
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
enabled: isEnabled,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: SavingsCard.getButton(
|
||||
context,
|
||||
label: S.of(context).deuro_reinvest_interest,
|
||||
icon: Icons.account_balance_outlined,
|
||||
onPressed: onReinvestInterest,
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
color: Theme.of(context).colorScheme.onSecondaryContainer,
|
||||
enabled: isEnabled,
|
||||
),
|
||||
),
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
SavingsCard.getAssetBalanceRow(
|
||||
context,
|
||||
title: title,
|
||||
subtitle: collectedInterest,
|
||||
currency: CryptoCurrency.deuro,
|
||||
hideSymbol: true,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
SavingsCard.getButton(
|
||||
context,
|
||||
label: S.of(context).deuro_collect_interest,
|
||||
onPressed: onCollectInterest,
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
]);
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
|
||||
import 'package:cake_wallet/themes/utils/custom_theme_colors.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SavingsCard extends StatelessWidget {
|
||||
final bool isDarkTheme;
|
||||
final bool isEnabled;
|
||||
final bool isLoading;
|
||||
final String interestRate;
|
||||
final String savingsBalance;
|
||||
final String? fiatSavingsBalance;
|
||||
final FiatCurrency? fiatCurrency;
|
||||
final CryptoCurrency currency;
|
||||
final VoidCallback onAddSavingsPressed;
|
||||
final VoidCallback onRemoveSavingsPressed;
|
||||
final VoidCallback onApproveSavingsPressed;
|
||||
final VoidCallback onTooltipPressed;
|
||||
|
||||
const SavingsCard({
|
||||
super.key,
|
||||
@@ -26,162 +32,187 @@ class SavingsCard extends StatelessWidget {
|
||||
required this.onAddSavingsPressed,
|
||||
required this.onRemoveSavingsPressed,
|
||||
required this.onApproveSavingsPressed,
|
||||
required this.onTooltipPressed,
|
||||
this.isEnabled = true,
|
||||
this.isLoading = false,
|
||||
this.fiatSavingsBalance,
|
||||
this.fiatCurrency,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Container(
|
||||
margin: const EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
isDarkTheme
|
||||
? CustomThemeColors.cardGradientColorPrimaryDark
|
||||
: CustomThemeColors.cardGradientColorPrimaryLight,
|
||||
isDarkTheme
|
||||
? CustomThemeColors.cardGradientColorSecondaryDark
|
||||
: CustomThemeColors.cardGradientColorSecondaryLight,
|
||||
],
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
margin: const EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
color: Theme.of(context).colorScheme.surfaceContainerLowest,
|
||||
),
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
getAssetBalanceRow(context,
|
||||
title: S.of(context).deuro_savings_balance,
|
||||
subtitle: savingsBalance,
|
||||
currency: currency),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Current APR',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color:
|
||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
softWrap: true,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
interestRate,
|
||||
child: Column(children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 10, left: 20, right: 20),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Current APR', // ToDo: Localize
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
softWrap: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: isEnabled
|
||||
? [
|
||||
Expanded(
|
||||
child: getButton(
|
||||
context,
|
||||
label: S.of(context).deuro_savings_add,
|
||||
imagePath: 'assets/images/received.png',
|
||||
onPressed: onAddSavingsPressed,
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.primary,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: getButton(
|
||||
context,
|
||||
label: S.of(context).deuro_savings_remove,
|
||||
imagePath: 'assets/images/upload.png',
|
||||
onPressed: onRemoveSavingsPressed,
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.surface,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSecondaryContainer,
|
||||
),
|
||||
),
|
||||
]
|
||||
: [
|
||||
Expanded(
|
||||
child: getButton(
|
||||
context,
|
||||
label: S.of(context).deuro_savings_set_approval,
|
||||
onPressed: onApproveSavingsPressed,
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.primary,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
|
||||
static Widget getButton(
|
||||
BuildContext context, {
|
||||
required String label,
|
||||
String? imagePath,
|
||||
required VoidCallback onPressed,
|
||||
required Color backgroundColor,
|
||||
required Color color,
|
||||
}) =>
|
||||
Semantics(
|
||||
label: label,
|
||||
child: OutlinedButton(
|
||||
onPressed: onPressed,
|
||||
style: OutlinedButton.styleFrom(
|
||||
backgroundColor: backgroundColor,
|
||||
side: BorderSide(
|
||||
color: Theme.of(context).colorScheme.outlineVariant.withAlpha(0),
|
||||
width: 0,
|
||||
),
|
||||
shape:
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (imagePath != null) ...[
|
||||
Image.asset(
|
||||
imagePath,
|
||||
height: 30,
|
||||
width: 30,
|
||||
color: color,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
label,
|
||||
interestRate,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: color,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
softWrap: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
isDarkTheme
|
||||
? CustomThemeColors.cardGradientColorPrimaryDark
|
||||
: CustomThemeColors.cardGradientColorPrimaryLight,
|
||||
isDarkTheme
|
||||
? CustomThemeColors.cardGradientColorSecondaryDark
|
||||
: CustomThemeColors.cardGradientColorSecondaryLight,
|
||||
],
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 20),
|
||||
child: getAssetBalanceRow(
|
||||
context,
|
||||
title: S.of(context).deuro_savings_balance,
|
||||
amount: savingsBalance,
|
||||
fiatAmount: fiatSavingsBalance,
|
||||
currency: currency,
|
||||
fiatCurrency: fiatCurrency,
|
||||
hideSymbol: false,
|
||||
onTooltipPressed: onTooltipPressed,
|
||||
),
|
||||
),
|
||||
isLoading
|
||||
? CupertinoActivityIndicator(color: Theme.of(context).colorScheme.onSurface)
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: isEnabled
|
||||
? [
|
||||
Expanded(
|
||||
child: getButton(
|
||||
context,
|
||||
label: S.of(context).deuro_savings_add,
|
||||
imagePath: 'assets/images/received.png',
|
||||
onPressed: onAddSavingsPressed,
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: getButton(
|
||||
context,
|
||||
label: S.of(context).deuro_savings_remove,
|
||||
imagePath: 'assets/images/upload.png',
|
||||
onPressed: onRemoveSavingsPressed,
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
color: Theme.of(context).colorScheme.onSecondaryContainer,
|
||||
),
|
||||
),
|
||||
]
|
||||
: [
|
||||
Expanded(
|
||||
child: getButton(
|
||||
context,
|
||||
label: S.of(context).deuro_savings_approve_app,
|
||||
onPressed: onApproveSavingsPressed,
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
icon: Icons.check,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
]),
|
||||
);
|
||||
|
||||
static Widget getButton(
|
||||
BuildContext context, {
|
||||
required String label,
|
||||
required VoidCallback onPressed,
|
||||
required Color backgroundColor,
|
||||
required Color color,
|
||||
String? imagePath,
|
||||
IconData? icon,
|
||||
bool enabled = true,
|
||||
double iconSize = 24,
|
||||
}) {
|
||||
backgroundColor = enabled ? backgroundColor : backgroundColor.withAlpha(130);
|
||||
color = enabled ? color : color.withAlpha(130);
|
||||
|
||||
return Semantics(
|
||||
label: label,
|
||||
child: OutlinedButton(
|
||||
onPressed: enabled ? onPressed : null,
|
||||
style: OutlinedButton.styleFrom(
|
||||
backgroundColor: backgroundColor,
|
||||
side: BorderSide(
|
||||
color: Theme.of(context).colorScheme.outlineVariant.withAlpha(0),
|
||||
width: 0,
|
||||
),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (imagePath != null) ...[
|
||||
Image.asset(imagePath, height: iconSize, width: iconSize, color: color),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
if (icon != null) ...[
|
||||
Icon(icon, size: iconSize, color: color),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
Text(
|
||||
label,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: color,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static Widget getAssetBalanceRow(
|
||||
BuildContext context, {
|
||||
required String title,
|
||||
required String subtitle,
|
||||
required String amount,
|
||||
required CryptoCurrency currency,
|
||||
bool hideSymbol = true,
|
||||
VoidCallback? onTooltipPressed,
|
||||
FiatCurrency? fiatCurrency,
|
||||
String? fiatAmount,
|
||||
}) =>
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
@@ -190,16 +221,32 @@ class SavingsCard extends StatelessWidget {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
height: 1,
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
if (onTooltipPressed != null)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 4),
|
||||
child: InkWell(
|
||||
onTap: onTooltipPressed,
|
||||
child: Icon(
|
||||
CupertinoIcons.question_circle,
|
||||
size: 13,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 6),
|
||||
AutoSizeText(
|
||||
subtitle,
|
||||
amount,
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
fontWeight: FontWeight.w900,
|
||||
@@ -209,10 +256,21 @@ class SavingsCard extends StatelessWidget {
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.start,
|
||||
),
|
||||
if (fiatCurrency != null)
|
||||
AutoSizeText(
|
||||
"${fiatCurrency.title} $fiatAmount",
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 16,
|
||||
height: 1.5,
|
||||
),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.start,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
//width: min(MediaQuery.of(context).size.width * 0.2, 100),
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -225,15 +283,11 @@ class SavingsCard extends StatelessWidget {
|
||||
width: 30.0,
|
||||
child: Center(
|
||||
child: Text(
|
||||
currency.title
|
||||
.substring(0, min(currency.title.length, 2)),
|
||||
style:
|
||||
Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
fontSize: 11,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurfaceVariant,
|
||||
),
|
||||
currency.title.substring(0, min(currency.title.length, 2)),
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
fontSize: 11,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
@@ -243,7 +297,7 @@ class SavingsCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
if (!hideSymbol) ...[
|
||||
const SizedBox(height: 10),
|
||||
const SizedBox(height: 3),
|
||||
Text(
|
||||
currency.title,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
|
||||
@@ -1,24 +1,39 @@
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/numpad.dart';
|
||||
import 'package:cake_wallet/src/widgets/bottom_sheet/base_bottom_sheet_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SavingEditPage extends BasePage {
|
||||
final bool isAdding;
|
||||
class SavingsEditSheet extends BaseBottomSheet {
|
||||
final String? balance;
|
||||
final String? balanceTitle;
|
||||
|
||||
SavingEditPage({required this.isAdding});
|
||||
|
||||
String get title =>
|
||||
isAdding ? S.current.deuro_savings_add : S.current.deuro_savings_remove;
|
||||
const SavingsEditSheet({
|
||||
required super.titleText,
|
||||
super.titleIconPath,
|
||||
this.balance,
|
||||
this.balanceTitle,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) => _SavingsEditBody();
|
||||
Widget contentWidget(BuildContext context) => SizedBox(
|
||||
height: 600,
|
||||
child: _SavingsEditBody(
|
||||
balance: balance,
|
||||
balanceTitle: balanceTitle,
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
Widget footerWidget(BuildContext context) => SizedBox.shrink();
|
||||
}
|
||||
|
||||
class _SavingsEditBody extends StatefulWidget {
|
||||
const _SavingsEditBody();
|
||||
final String? balance;
|
||||
final String? balanceTitle;
|
||||
|
||||
const _SavingsEditBody({this.balance, this.balanceTitle});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _SavingsEditBodyState();
|
||||
@@ -27,8 +42,7 @@ class _SavingsEditBody extends StatefulWidget {
|
||||
class _SavingsEditBodyState extends State<_SavingsEditBody> {
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance
|
||||
.addPostFrameCallback((_) => _numpadFocusNode.requestFocus());
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _numpadFocusNode.requestFocus());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@@ -51,31 +65,36 @@ class _SavingsEditBodyState extends State<_SavingsEditBody> {
|
||||
child: AutoSizeText(
|
||||
"${amount.toString()} dEuro",
|
||||
maxLines: 1,
|
||||
maxFontSize: 60,
|
||||
maxFontSize: 32,
|
||||
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 60,
|
||||
fontSize: 32,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
)),
|
||||
if (widget.balance != null && widget.balanceTitle != null) ...[
|
||||
Divider(),
|
||||
AssetBalanceRow(
|
||||
title: widget.balanceTitle!,
|
||||
amount: widget.balance!,
|
||||
onAllPressed: () => setState(() => amount = widget.balance!),
|
||||
),
|
||||
],
|
||||
NumberPad(
|
||||
focusNode: _numpadFocusNode,
|
||||
onNumberPressed: (i) => setState(
|
||||
() => amount = amount == '0' ? i.toString() : '${amount}${i}',
|
||||
),
|
||||
onDeletePressed: () => setState(
|
||||
() => amount = amount.length > 1
|
||||
? amount.substring(0, amount.length - 1)
|
||||
: '0',
|
||||
() => amount = amount.length > 1 ? amount.substring(0, amount.length - 1) : '0',
|
||||
),
|
||||
onDecimalPressed: () =>
|
||||
setState(() => amount = '${amount.replaceAll('.', '')}.'),
|
||||
onDecimalPressed: () => setState(() => amount = '${amount.replaceAll('.', '')}.'),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 34),
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
|
||||
child: LoadingPrimaryButton(
|
||||
onPressed: () => Navigator.pop(context, amount),
|
||||
text: S.of(context).confirm,
|
||||
@@ -88,3 +107,74 @@ class _SavingsEditBodyState extends State<_SavingsEditBody> {
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
class AssetBalanceRow extends StatelessWidget {
|
||||
final String title;
|
||||
final String amount;
|
||||
final VoidCallback onAllPressed;
|
||||
|
||||
const AssetBalanceRow({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.amount,
|
||||
required this.onAllPressed,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 10, 20, 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 6),
|
||||
AutoSizeText(
|
||||
amount,
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
fontWeight: FontWeight.w400,
|
||||
height: 1,
|
||||
),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.start,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
child: Center(
|
||||
child: InkWell(
|
||||
onTap: onAllPressed,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
),
|
||||
padding: EdgeInsets.fromLTRB(15, 10, 15, 10),
|
||||
child: Text(
|
||||
S.of(context).all,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,9 @@ import 'package:flutter/material.dart';
|
||||
abstract class BaseBottomSheet extends StatelessWidget {
|
||||
final String titleText;
|
||||
final String? titleIconPath;
|
||||
final double maxHeight;
|
||||
|
||||
const BaseBottomSheet({required this.titleText, this.titleIconPath});
|
||||
const BaseBottomSheet({required this.titleText, this.titleIconPath, this.maxHeight = 900});
|
||||
|
||||
Widget headerWidget(BuildContext context) {
|
||||
return Column(
|
||||
@@ -59,7 +60,7 @@ abstract class BaseBottomSheet extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ConstrainedBox(
|
||||
constraints: BoxConstraints(maxHeight: 600),
|
||||
constraints: BoxConstraints(maxHeight: maxHeight),
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0)),
|
||||
|
||||
@@ -22,6 +22,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
|
||||
final String fee;
|
||||
final String feeValue;
|
||||
final String feeFiatAmount;
|
||||
final String? explanation;
|
||||
final List<Output> outputs;
|
||||
final VoidCallback onSlideComplete;
|
||||
final WalletType walletType;
|
||||
@@ -46,6 +47,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
|
||||
required this.onSlideComplete,
|
||||
required this.walletType,
|
||||
this.change,
|
||||
this.explanation,
|
||||
this.isOpenCryptoPay = false,
|
||||
Key? key,
|
||||
}) : showScrollbar = outputs.length > 3,
|
||||
@@ -87,9 +89,18 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
|
||||
tileBackgroundColor: tileBackgroundColor,
|
||||
),
|
||||
),
|
||||
if (explanation != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8),
|
||||
child: StandardInfoTile(
|
||||
value: explanation!,
|
||||
itemTitleTextStyle: itemTitleTextStyle,
|
||||
tileBackgroundColor: tileBackgroundColor,
|
||||
),
|
||||
),
|
||||
StandardTile(
|
||||
itemTitle: amount,
|
||||
itemValue: amountValue + ' ${currency.title}',
|
||||
itemValue: '$amountValue ${currency.title}',
|
||||
itemTitleTextStyle: itemTitleTextStyle,
|
||||
itemSubTitle: fiatAmountValue,
|
||||
itemSubTitleTextStyle: itemSubTitleTextStyle,
|
||||
@@ -260,6 +271,34 @@ class StandardTile extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class StandardInfoTile extends StatelessWidget {
|
||||
const StandardInfoTile({
|
||||
super.key,
|
||||
required this.value,
|
||||
required this.itemTitleTextStyle,
|
||||
required this.tileBackgroundColor,
|
||||
});
|
||||
|
||||
final String value;
|
||||
final TextStyle itemTitleTextStyle;
|
||||
final Color tileBackgroundColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Semantics(
|
||||
container: true,
|
||||
label: value,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: tileBackgroundColor,
|
||||
),
|
||||
width: double.infinity,
|
||||
child: Text(value, style: itemTitleTextStyle),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class AddressTile extends StatelessWidget {
|
||||
const AddressTile({
|
||||
super.key,
|
||||
|
||||
@@ -39,6 +39,8 @@ class InfoBottomSheet extends BaseBottomSheet {
|
||||
final VoidCallback? actionRightButton;
|
||||
final Key? rightActionButtonKey;
|
||||
final Key? leftActionButtonKey;
|
||||
final double height;
|
||||
final double? contentImageSize;
|
||||
|
||||
InfoBottomSheet({
|
||||
required String titleText,
|
||||
@@ -46,9 +48,11 @@ class InfoBottomSheet extends BaseBottomSheet {
|
||||
required this.currentTheme,
|
||||
this.contentImage,
|
||||
this.contentImageColor,
|
||||
this.contentImageSize,
|
||||
this.content,
|
||||
this.isTwoAction = false,
|
||||
this.showDontAskMeCheckbox = false,
|
||||
this.height = 200,
|
||||
this.onCheckboxChanged,
|
||||
this.actionButtonText,
|
||||
this.actionButton,
|
||||
@@ -59,18 +63,22 @@ class InfoBottomSheet extends BaseBottomSheet {
|
||||
this.actionRightButton,
|
||||
this.rightActionButtonKey,
|
||||
this.leftActionButtonKey,
|
||||
}) : super(titleText: titleText, titleIconPath: titleIconPath);
|
||||
double maxHeight = 900,
|
||||
}) : super(titleText: titleText, titleIconPath: titleIconPath, maxHeight: maxHeight);
|
||||
|
||||
@override
|
||||
Widget contentWidget(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 200,
|
||||
height: height,
|
||||
child: Column(
|
||||
children: [
|
||||
if (contentImage != null)
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: getImage(contentImage!, imageColor: contentImageColor),
|
||||
child: SizedBox(
|
||||
width: contentImageSize,
|
||||
child: getImage(contentImage!, imageColor: contentImageColor),
|
||||
),
|
||||
)
|
||||
else
|
||||
Container(),
|
||||
|
||||
Reference in New Issue
Block a user