CAKE-345 | fixed add receiver button; applied dotted borders to primary button; applied localization to add receiver button; added scrollbar to confirm_sending_alert.dart

wownero
OleksandrSobol 3 years ago
parent bcf853170a
commit 30a32ab071

@ -264,10 +264,21 @@ class SendPage extends BasePage {
child: PrimaryButton(
onPressed: () {
sendViewModel.addOutput();
Future.delayed(const Duration(milliseconds: 250), () {
controller.jumpToPage(sendViewModel.outputs.length - 1);
});
},
text: S.of(context).add_receiver,
color: Colors.green,
textColor: Colors.white,
color: Colors.transparent,
textColor: Theme.of(context)
.accentTextTheme
.display2
.decorationColor,
isDottedBorder: true,
borderColor: Theme.of(context)
.primaryTextTheme
.display2
.decorationColor,
)
),
Observer(builder: (_) {

@ -3,6 +3,7 @@ import 'package:cake_wallet/view_model/send/output.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
class ConfirmSendingAlert extends BaseAlertDialog {
ConfirmSendingAlert({
@ -18,13 +19,7 @@ class ConfirmSendingAlert extends BaseAlertDialog {
@required this.rightButtonText,
@required this.actionLeftButton,
@required this.actionRightButton,
this.alertBarrierDismissible = true
}) {
itemCount = outputs.length;
recipientTitle = itemCount > 1
? S.current.transaction_details_recipient_address
: S.current.recipient_address;
}
this.alertBarrierDismissible = true});
final String alertTitle;
final String amount;
@ -40,9 +35,6 @@ class ConfirmSendingAlert extends BaseAlertDialog {
final VoidCallback actionRightButton;
final bool alertBarrierDismissible;
String recipientTitle;
int itemCount;
@override
String get titleText => alertTitle;
@ -65,131 +57,184 @@ class ConfirmSendingAlert extends BaseAlertDialog {
bool get barrierDismissible => alertBarrierDismissible;
@override
Widget content(BuildContext context) {
return Container(
height: 200,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
amount,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme.title.color,
decoration: TextDecoration.none,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
amountValue,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme.title.color,
decoration: TextDecoration.none,
),
),
Text(
fiatAmountValue,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: PaletteDark.pigeonBlue,
decoration: TextDecoration.none,
),
)
],
)
],
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
Widget content(BuildContext context) => ConfirmSendingAlertContent(
amount: amount,
amountValue: amountValue,
fiatAmountValue: fiatAmountValue,
fee: fee,
feeValue: feeValue,
feeFiatAmount: feeFiatAmount,
outputs: outputs
);
}
class ConfirmSendingAlertContent extends StatefulWidget {
ConfirmSendingAlertContent({
@required this.amount,
@required this.amountValue,
@required this.fiatAmountValue,
@required this.fee,
@required this.feeValue,
@required this.feeFiatAmount,
@required this.outputs});
final String amount;
final String amountValue;
final String fiatAmountValue;
final String fee;
final String feeValue;
final String feeFiatAmount;
final List<Output> outputs;
@override
ConfirmSendingAlertContentState createState() => ConfirmSendingAlertContentState(
amount: amount,
amountValue: amountValue,
fiatAmountValue: fiatAmountValue,
fee: fee,
feeValue: feeValue,
feeFiatAmount: feeFiatAmount,
outputs: outputs
);
}
class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent> {
ConfirmSendingAlertContentState({
@required this.amount,
@required this.amountValue,
@required this.fiatAmountValue,
@required this.fee,
@required this.feeValue,
@required this.feeFiatAmount,
@required this.outputs}) {
itemCount = outputs.length;
recipientTitle = itemCount > 1
? S.current.transaction_details_recipient_address
: S.current.recipient_address;
}
final String amount;
final String amountValue;
final String fiatAmountValue;
final String fee;
final String feeValue;
final String feeFiatAmount;
final List<Output> outputs;
final double backgroundHeight = 160;
final double thumbHeight = 72;
ScrollController controller = ScrollController();
double fromTop = 0;
String recipientTitle;
int itemCount;
@override
Widget build(BuildContext context) {
controller.addListener(() {
fromTop = controller.hasClients
? (controller.offset / controller.position.maxScrollExtent *
(backgroundHeight - thumbHeight))
: 0;
setState(() {});
});
return Stack(
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Container(
height: 200,
child: SingleChildScrollView(
controller: controller,
child: Column(
children: <Widget>[
Text(
fee,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme.title.color,
decoration: TextDecoration.none,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
feeValue,
amount,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
fontSize: 16,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context)
.primaryTextTheme
.title
.color,
decoration: TextDecoration.none,
),
),
Text(
feeFiatAmount,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: PaletteDark.pigeonBlue,
decoration: TextDecoration.none,
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
amountValue,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: Theme.of(context)
.primaryTextTheme
.title
.color,
decoration: TextDecoration.none,
),
),
Text(
fiatAmountValue,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: PaletteDark.pigeonBlue,
decoration: TextDecoration.none,
),
)
],
)
],
)
],
)
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Column(
children: [
Text(
'$recipientTitle:',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme.title.color,
decoration: TextDecoration.none,
),
),
itemCount > 1
? ListView.builder(
padding: EdgeInsets.only(top: 0),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: itemCount,
itemBuilder: (context, index) {
final item = outputs[index];
final _address = item.address;
final _amount =
item.cryptoAmount.replaceAll(',', '.');
return Column(
children: [
Padding(
padding: EdgeInsets.only(top: 8),
child: Text(
_address,
Padding(
padding: EdgeInsets.only(top: 16),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
fee,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: Theme.of(context)
.primaryTextTheme
.title
.color,
decoration: TextDecoration.none,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
feeValue,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: Theme.of(context)
.primaryTextTheme
.title
.color,
decoration: TextDecoration.none,
),
),
Text(
feeFiatAmount,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
@ -198,49 +243,104 @@ class ConfirmSendingAlert extends BaseAlertDialog {
decoration: TextDecoration.none,
),
)
],
)
],
)
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Column(
children: [
Text(
'$recipientTitle:',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: Theme.of(context)
.primaryTextTheme
.title
.color,
decoration: TextDecoration.none,
),
Padding(
padding: EdgeInsets.only(top: 8),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
),
itemCount > 1
? ListView.builder(
padding: EdgeInsets.only(top: 0),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: itemCount,
itemBuilder: (context, index) {
final item = outputs[index];
final _address = item.address;
final _amount =
item.cryptoAmount.replaceAll(',', '.');
return Column(
children: [
Text(
_amount,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: PaletteDark.pigeonBlue,
decoration: TextDecoration.none,
),
Padding(
padding: EdgeInsets.only(top: 8),
child: Text(
_address,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: PaletteDark.pigeonBlue,
decoration: TextDecoration.none,
),
)
),
Padding(
padding: EdgeInsets.only(top: 8),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
_amount,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: PaletteDark.pigeonBlue,
decoration: TextDecoration.none,
),
)
],
)
)
],
)
)
],
);
}
)
: Padding(
padding: EdgeInsets.only(top: 8),
child: Text(
outputs.first.address,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: PaletteDark.pigeonBlue,
decoration: TextDecoration.none,
);
})
: Padding(
padding: EdgeInsets.only(top: 8),
child: Text(
outputs.first.address,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: PaletteDark.pigeonBlue,
decoration: TextDecoration.none,
),
),
)
],
),
),
)
],
),
)
],
)
)
],
)
)
),
if (itemCount > 1) CakeScrollbar(
backgroundHeight: backgroundHeight,
thumbHeight: thumbHeight,
fromTop: fromTop,
rightOffset: -15
)
]
);
}
}

@ -4,17 +4,19 @@ class CakeScrollbar extends StatelessWidget {
CakeScrollbar({
@required this.backgroundHeight,
@required this.thumbHeight,
@required this.fromTop
@required this.fromTop,
this.rightOffset = 6
});
final double backgroundHeight;
final double thumbHeight;
final double fromTop;
final double rightOffset;
@override
Widget build(BuildContext context) {
return Positioned(
right: 6,
right: rightOffset,
child: Container(
height: backgroundHeight,
width: 6,

@ -1,3 +1,4 @@
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -8,18 +9,22 @@ class PrimaryButton extends StatelessWidget {
@required this.color,
@required this.textColor,
this.isDisabled = false,
this.isDottedBorder = false,
this.borderColor = Colors.black,
this.onDisabledPressed});
final VoidCallback onPressed;
final VoidCallback onDisabledPressed;
final Color color;
final Color textColor;
final Color borderColor;
final String text;
final bool isDisabled;
final bool isDottedBorder;
@override
Widget build(BuildContext context) {
return ButtonTheme(
final content = ButtonTheme(
minWidth: double.infinity,
height: 52.0,
child: FlatButton(
@ -27,6 +32,8 @@ class PrimaryButton extends StatelessWidget {
? (onDisabledPressed != null ? onDisabledPressed : null)
: onPressed,
color: isDisabled ? color.withOpacity(0.5) : color,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
disabledColor: color.withOpacity(0.5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26.0),
@ -40,6 +47,16 @@ class PrimaryButton extends StatelessWidget {
? textColor.withOpacity(0.5)
: textColor)),
));
return isDottedBorder
? DottedBorder(
borderType: BorderType.RRect,
dashPattern: [6, 4],
color: borderColor,
strokeWidth: 2,
radius: Radius.circular(26),
child: content)
: content;
}
}

@ -58,7 +58,9 @@ abstract class SendViewModelBase with Store {
@action
void removeOutput(Output output) {
outputs.remove(output);
if (isBatchSending) {
outputs.remove(output);
}
}
@action

@ -494,5 +494,5 @@
"address_detected" : "Adresse erkannt",
"address_from_domain" : "Sie haben die Adresse von der unaufhaltsamen Domain ${domain} erhalten",
"add_receiver" : "Empfänger hinzufügen"
"add_receiver" : "Fügen Sie einen weiteren Empfänger hinzu (optional)"
}

@ -494,5 +494,5 @@
"address_detected" : "Address detected",
"address_from_domain" : "You got address from unstoppable domain ${domain}",
"add_receiver" : "Add receiver"
"add_receiver" : "Add another receiver (optional)"
}

@ -494,5 +494,5 @@
"address_detected" : "Dirección detectada",
"address_from_domain" : "Tienes la dirección de unstoppable domain ${domain}",
"add_receiver" : "Agregar receptor"
"add_receiver" : "Agregar otro receptor (opcional)"
}

@ -494,5 +494,5 @@
"address_detected" : "पता लग गया",
"address_from_domain" : "आपको अजेय डोमेन ${domain} से पता मिला है",
"add_receiver" : "रिसीवर जोड़ें"
"add_receiver" : "एक और रिसीवर जोड़ें (वैकल्पिक)"
}

@ -494,5 +494,5 @@
"address_detected" : "Adresa je otkrivena",
"address_from_domain" : "Dobili ste adresu od unstoppable domain ${domain}",
"add_receiver" : "Dodajte prijamnik"
"add_receiver" : "Dodajte drugi prijemnik (izborno)"
}

@ -494,5 +494,5 @@
"address_detected" : "Indirizzo rilevato",
"address_from_domain" : "Hai l'indirizzo da unstoppable domain ${domain}",
"add_receiver" : "Aggiungi ricevitore"
"add_receiver" : "Aggiungi un altro ricevitore (opzionale)"
}

@ -494,5 +494,5 @@
"address_detected" : "アドレスが検出されました",
"address_from_domain" : "あなたはからアドレスを得ました unstoppable domain ${domain}",
"add_receiver" : "レシーバーを追加"
"add_receiver" : "別のレシーバーを追加します(オプション)"
}

@ -494,5 +494,5 @@
"address_detected" : "주소 감지",
"address_from_domain" : "주소는 unstoppable domain ${domain}",
"add_receiver" : "수신기 추가"
"add_receiver" : "다른 수신기 추가(선택 사항)"
}

@ -494,5 +494,5 @@
"address_detected" : "Adres gedetecteerd",
"address_from_domain" : "Je adres is van unstoppable domain ${domain}",
"add_receiver" : "Ontvanger toevoegen"
"add_receiver" : "Nog een ontvanger toevoegen (optioneel)"
}

@ -494,5 +494,5 @@
"address_detected" : "Wykryto adres",
"address_from_domain" : "Dostałeś adres od unstoppable domain ${domain}",
"add_receiver" : "Dodaj odbiorcę"
"add_receiver" : "Dodaj kolejny odbiornik (opcjonalnie)"
}

@ -494,5 +494,5 @@
"address_detected" : "Endereço detectado",
"address_from_domain" : "Você obteve o endereço de unstoppable domain ${domain}",
"add_receiver" : "Adicionar receptor"
"add_receiver" : "Adicione outro receptor (opcional)"
}

@ -494,5 +494,5 @@
"address_detected" : "Обнаружен адрес",
"address_from_domain" : "Вы получили адрес из unstoppable domain ${domain}",
"add_receiver" : "Добавить получателя"
"add_receiver" : "Добавить получателя (необязательно)"
}

@ -494,5 +494,5 @@
"address_detected" : "Виявлено адресу",
"address_from_domain" : "Ви отримали адресу від unstoppable domain ${domain}",
"add_receiver" : "Додати одержувача"
"add_receiver" : "Додати одержувача (необов'язково)"
}

@ -494,5 +494,5 @@
"address_detected" : "檢測到地址",
"address_from_domain" : "您有以下地址 unstoppable domain ${domain}",
"add_receiver" : "添加接收器"
"add_receiver" : "添加另一個接收器(可選)"
}
Loading…
Cancel
Save