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

This commit is contained in:
OleksandrSobol 2021-08-12 17:56:34 +03:00
parent bcf853170a
commit 30a32ab071
19 changed files with 316 additions and 184 deletions

View file

@ -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: (_) {

View file

@ -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,10 +57,96 @@ 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,
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, height: 200,
child: SingleChildScrollView( child: SingleChildScrollView(
controller: controller,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Row( Row(
@ -82,7 +160,10 @@ class ConfirmSendingAlert extends BaseAlertDialog {
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.normal, 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,
), ),
), ),
@ -95,7 +176,10 @@ class ConfirmSendingAlert extends BaseAlertDialog {
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontFamily: 'Lato', fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme.title.color, color: Theme.of(context)
.primaryTextTheme
.title
.color,
decoration: TextDecoration.none, decoration: TextDecoration.none,
), ),
), ),
@ -126,7 +210,10 @@ class ConfirmSendingAlert extends BaseAlertDialog {
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.normal, 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,
), ),
), ),
@ -139,7 +226,10 @@ class ConfirmSendingAlert extends BaseAlertDialog {
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontFamily: 'Lato', fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme.title.color, color: Theme.of(context)
.primaryTextTheme
.title
.color,
decoration: TextDecoration.none, decoration: TextDecoration.none,
), ),
), ),
@ -168,7 +258,10 @@ class ConfirmSendingAlert extends BaseAlertDialog {
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.normal, 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,
), ),
), ),
@ -220,8 +313,7 @@ class ConfirmSendingAlert extends BaseAlertDialog {
) )
], ],
); );
} })
)
: Padding( : Padding(
padding: EdgeInsets.only(top: 8), padding: EdgeInsets.only(top: 8),
child: Text( child: Text(
@ -241,6 +333,14 @@ class ConfirmSendingAlert extends BaseAlertDialog {
], ],
) )
) )
),
if (itemCount > 1) CakeScrollbar(
backgroundHeight: backgroundHeight,
thumbHeight: thumbHeight,
fromTop: fromTop,
rightOffset: -15
)
]
); );
} }
} }

View file

@ -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,

View file

@ -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;
} }
} }

View file

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

View file

@ -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)"
} }

View file

@ -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)"
} }

View file

@ -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)"
} }

View file

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

View file

@ -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)"
} }

View file

@ -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)"
} }

View file

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

View file

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

View file

@ -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)"
} }

View file

@ -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)"
} }

View file

@ -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)"
} }

View file

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

View file

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

View file

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