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( child: PrimaryButton(
onPressed: () { onPressed: () {
sendViewModel.addOutput(); sendViewModel.addOutput();
Future.delayed(const Duration(milliseconds: 250), () {
controller.jumpToPage(sendViewModel.outputs.length - 1);
});
}, },
text: S.of(context).add_receiver, text: S.of(context).add_receiver,
color: Colors.green, color: Colors.transparent,
textColor: Colors.white, textColor: Theme.of(context)
.accentTextTheme
.display2
.decorationColor,
isDottedBorder: true,
borderColor: Theme.of(context)
.primaryTextTheme
.display2
.decorationColor,
) )
), ),
Observer(builder: (_) { Observer(builder: (_) {

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

@ -1,3 +1,4 @@
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -8,18 +9,22 @@ class PrimaryButton extends StatelessWidget {
@required this.color, @required this.color,
@required this.textColor, @required this.textColor,
this.isDisabled = false, this.isDisabled = false,
this.isDottedBorder = false,
this.borderColor = Colors.black,
this.onDisabledPressed}); this.onDisabledPressed});
final VoidCallback onPressed; final VoidCallback onPressed;
final VoidCallback onDisabledPressed; final VoidCallback onDisabledPressed;
final Color color; final Color color;
final Color textColor; final Color textColor;
final Color borderColor;
final String text; final String text;
final bool isDisabled; final bool isDisabled;
final bool isDottedBorder;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ButtonTheme( final content = ButtonTheme(
minWidth: double.infinity, minWidth: double.infinity,
height: 52.0, height: 52.0,
child: FlatButton( child: FlatButton(
@ -27,6 +32,8 @@ class PrimaryButton extends StatelessWidget {
? (onDisabledPressed != null ? onDisabledPressed : null) ? (onDisabledPressed != null ? onDisabledPressed : null)
: onPressed, : onPressed,
color: isDisabled ? color.withOpacity(0.5) : color, color: isDisabled ? color.withOpacity(0.5) : color,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
disabledColor: color.withOpacity(0.5), disabledColor: color.withOpacity(0.5),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26.0), borderRadius: BorderRadius.circular(26.0),
@ -40,6 +47,16 @@ class PrimaryButton extends StatelessWidget {
? textColor.withOpacity(0.5) ? textColor.withOpacity(0.5)
: textColor)), : 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 @action
void removeOutput(Output output) { void removeOutput(Output output) {
outputs.remove(output); if (isBatchSending) {
outputs.remove(output);
}
} }
@action @action

@ -494,5 +494,5 @@
"address_detected" : "Adresse erkannt", "address_detected" : "Adresse erkannt",
"address_from_domain" : "Sie haben die Adresse von der unaufhaltsamen Domain ${domain} erhalten", "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_detected" : "Address detected",
"address_from_domain" : "You got address from unstoppable domain ${domain}", "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_detected" : "Dirección detectada",
"address_from_domain" : "Tienes la dirección de unstoppable domain ${domain}", "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_detected" : "पता लग गया",
"address_from_domain" : "आपको अजेय डोमेन ${domain} से पता मिला है", "address_from_domain" : "आपको अजेय डोमेन ${domain} से पता मिला है",
"add_receiver" : "रिसीवर जोड़ें" "add_receiver" : "एक और रिसीवर जोड़ें (वैकल्पिक)"
} }

@ -494,5 +494,5 @@
"address_detected" : "Adresa je otkrivena", "address_detected" : "Adresa je otkrivena",
"address_from_domain" : "Dobili ste adresu od unstoppable domain ${domain}", "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_detected" : "Indirizzo rilevato",
"address_from_domain" : "Hai l'indirizzo da unstoppable domain ${domain}", "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_detected" : "アドレスが検出されました",
"address_from_domain" : "あなたはからアドレスを得ました unstoppable domain ${domain}", "address_from_domain" : "あなたはからアドレスを得ました unstoppable domain ${domain}",
"add_receiver" : "レシーバーを追加" "add_receiver" : "別のレシーバーを追加します(オプション)"
} }

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

@ -494,5 +494,5 @@
"address_detected" : "Adres gedetecteerd", "address_detected" : "Adres gedetecteerd",
"address_from_domain" : "Je adres is van unstoppable domain ${domain}", "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_detected" : "Wykryto adres",
"address_from_domain" : "Dostałeś adres od unstoppable domain ${domain}", "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_detected" : "Endereço detectado",
"address_from_domain" : "Você obteve o endereço de unstoppable domain ${domain}", "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_detected" : "Обнаружен адрес",
"address_from_domain" : "Вы получили адрес из unstoppable domain ${domain}", "address_from_domain" : "Вы получили адрес из unstoppable domain ${domain}",
"add_receiver" : "Добавить получателя" "add_receiver" : "Добавить получателя (необязательно)"
} }

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

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