Merge branch 'CAKE-329-unspent-coins-list-UI' into CAKE-330-unspent-coins-details-UI

# Conflicts:
#	lib/src/screens/unspent_coins/unspent_coins_list_page.dart
wownero
OleksandrSobol 3 years ago
commit febb446c96

@ -44,6 +44,7 @@ class Palette {
static const Color dullGray = Color.fromRGBO(98, 98, 98, 1.0);
static const Color protectiveBlue = Color.fromRGBO(33, 148, 255, 1.0);
static const Color darkBlue = Color.fromRGBO(109, 128, 178, 1.0);
static const Color paleCornflowerBlue = Color.fromRGBO(185, 196, 237, 1.0);
}
class PaletteDark {

@ -425,7 +425,31 @@ class SendPage extends BasePage {
],
),
),
))
)),
if (sendViewModel.isBitcoinWallet) Padding(
padding: EdgeInsets.only(top: 6),
child: GestureDetector(
onTap: () => Navigator.of(context)
.pushNamed(Routes.unspentCoinsList),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Coin control (optional)',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Colors.white)),
Icon(
Icons.arrow_forward_ios,
size: 12,
color: Colors.white,
)
],
)
)
)
],
),
)
@ -558,35 +582,22 @@ class SendPage extends BasePage {
),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Column(
children: [
Observer(builder: (_) {
return LoadingPrimaryButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
await sendViewModel.createTransaction();
}
},
text: S.of(context).send,
color: Theme.of(context).accentTextTheme.body2.color,
textColor: Colors.white,
isLoading: sendViewModel.state is IsExecutingState ||
sendViewModel.state is TransactionCommitting,
isDisabled:
false // FIXME !(syncStore.status is SyncedSyncStatus),
);
}),
Padding(
padding: EdgeInsets.only(top: 12),
child: PrimaryButton(
onPressed: () => Navigator.of(context).pushNamed(Routes.unspentCoinsList),
text: 'Unspent coins',
color: Colors.green,
textColor: Colors.white,
)
)
],
)),
bottomSection: Observer(builder: (_) {
return LoadingPrimaryButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
await sendViewModel.createTransaction();
}
},
text: S.of(context).send,
color: Theme.of(context).accentTextTheme.body2.color,
textColor: Colors.white,
isLoading: sendViewModel.state is IsExecutingState ||
sendViewModel.state is TransactionCommitting,
isDisabled:
false // FIXME !(syncStore.status is SyncedSyncStatus),
);
})),
));
}

@ -1,11 +1,13 @@
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
class UnspentCoinsListPage extends BasePage {
UnspentCoinsListPage({this.unspentCoinsListViewModel});
@ -13,29 +15,95 @@ class UnspentCoinsListPage extends BasePage {
@override
String get title => 'Unspent coins';
@override
Widget trailing(BuildContext context) {
final questionImage = Image.asset('assets/images/question_mark.png',
color: Theme.of(context).primaryTextTheme.title.color);
return SizedBox(
height: 20.0,
width: 20.0,
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
onPressed: () => showUnspentCoinsAlert(context),
child: questionImage),
),
);
}
final UnspentCoinsListViewModel unspentCoinsListViewModel;
@override
Widget body(BuildContext context) =>
UnspentCoinsListForm(unspentCoinsListViewModel);
}
class UnspentCoinsListForm extends StatefulWidget {
UnspentCoinsListForm(this.unspentCoinsListViewModel);
final UnspentCoinsListViewModel unspentCoinsListViewModel;
@override
UnspentCoinsListFormState createState() =>
UnspentCoinsListFormState(unspentCoinsListViewModel);
}
class UnspentCoinsListFormState extends State<UnspentCoinsListForm> {
UnspentCoinsListFormState(this.unspentCoinsListViewModel);
final UnspentCoinsListViewModel unspentCoinsListViewModel;
@override
Widget body(BuildContext context) {
return Observer(builder: (_) => SectionStandardList(
sectionCount: 1,
itemCounter: (int _) => unspentCoinsListViewModel.items.length,
itemBuilder: (_, __, index) {
final item = unspentCoinsListViewModel.items[index];
return GestureDetector(
onTap: () =>
Navigator.of(context).pushNamed(Routes.unspentCoinsDetails,
arguments: item),
child: UnspentCoinsListItem(
address: item.address,
amount: item.amount,
isFrozen: item.isFrozen,
note: item.note,
isSending: item.isSending,
onCheckBoxTap: (value) {print('CheckBox taped');},
));
}));
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback(afterLayout);
}
void afterLayout(dynamic _) {
showUnspentCoinsAlert(context);
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.fromLTRB(24, 12, 24, 24),
child: Observer(
builder: (_) => ListView.separated(
itemCount: unspentCoinsListViewModel.items.length,
separatorBuilder: (_, __) =>
SizedBox(height: 15),
itemBuilder: (_, int index) {
final item = unspentCoinsListViewModel.items[index];
return GestureDetector(
onTap: () =>
Navigator.of(context).pushNamed(Routes.unspentCoinsDetails,
arguments: item),
child: UnspentCoinsListItem(
address: item.address,
amount: item.amount,
isSending: item.isSending,
onCheckBoxTap: (value) {},
));
}
)
)
);
}
}
void showUnspentCoinsAlert(BuildContext context) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: '',
alertContent: 'Information about unspent coins',
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
}

@ -1,74 +1,101 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
class UnspentCoinsListItem extends StatelessWidget {
class UnspentCoinsListItem extends StatefulWidget {
UnspentCoinsListItem({
@required this.address,
@required this.amount,
@required this.isFrozen,
@required this.note,
@required this.isSending,
@required this.onCheckBoxTap,
});
});
final String address;
final String amount;
final bool isFrozen;
final String note;
final bool isSending;
final Function(bool) onCheckBoxTap;
@override UnspentCoinsListItemState createState() =>
UnspentCoinsListItemState(
address: address,
amount: amount,
isSending: isSending,
onCheckBoxTap: onCheckBoxTap
);
}
class UnspentCoinsListItemState extends State<UnspentCoinsListItem> {
UnspentCoinsListItemState({
@required this.address,
@required this.amount,
@required this.isSending,
@required this.onCheckBoxTap,
}) : checkBoxValue = isSending;
static const amountColor = Palette.darkBlueCraiola;
static const addressColor = Palette.darkGray;
static const selectedItemColor = Palette.paleCornflowerBlue;
static const unselectedItemColor = Palette.moderateLavender;
final String address;
final String amount;
final bool isSending;
final Function(bool) onCheckBoxTap;
bool checkBoxValue;
@override
Widget build(BuildContext context) {
final textStyle = TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.primaryTextTheme
.title
.color);
final itemColor = checkBoxValue? selectedItemColor : unselectedItemColor;
return Container(
padding: EdgeInsets.fromLTRB(24, 16, 24, 16),
color: Theme.of(context).backgroundColor,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
height: 62,
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12)),
color: itemColor),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
address ?? 'Address',
style: textStyle,
),
Padding(
padding: EdgeInsets.only(top: 12),
child: Text(
amount ?? 'Amount',
style: textStyle,
)
),
if (isFrozen ?? false) Padding(
padding: EdgeInsets.only(top: 12),
child: Text(
'Freeze',
style: textStyle,
)
),
if (note?.isNotEmpty ?? false) Padding(
padding: EdgeInsets.only(top: 12),
child: AutoSizeText(
note,
style: textStyle,
maxLines: 1
)
),
Padding(
padding: EdgeInsets.only(top: 12),
padding: EdgeInsets.only(right: 12),
child: StandardCheckbox(
value: isSending,
caption: 'Sending',
onChanged: onCheckBoxTap
value: checkBoxValue,
onChanged: (value) {
onCheckBoxTap(value);
checkBoxValue = value;
setState(() {});
}
)
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(
amount ?? 'Amount',
style: TextStyle(
color: amountColor,
fontSize: 16,
fontWeight: FontWeight.w600
),
maxLines: 1,
),
AutoSizeText(
address ?? 'Address',
style: TextStyle(
color: addressColor,
fontSize: 12,
),
maxLines: 1,
)
]
)
)
],
)

@ -44,9 +44,6 @@ class StandardCheckboxState extends State<StandardCheckbox> {
Container(
height: 24.0,
width: 24.0,
margin: EdgeInsets.only(
right: 10.0,
),
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context)
@ -65,14 +62,17 @@ class StandardCheckboxState extends State<StandardCheckbox> {
)
: Offstage(),
),
Text(
caption,
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
if (caption.isNotEmpty) Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
caption,
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
)
)
],
),

@ -55,6 +55,8 @@ abstract class SendViewModelBase with Store {
_settingsStore.priority[_wallet.type] = priorities.first;
}
isBitcoinWallet = _wallet is BitcoinWallet;
_setCryptoNumMaximumFractionDigits();
}
@ -182,6 +184,9 @@ abstract class SendViewModelBase with Store {
@observable
PendingTransaction pendingTransaction;
@observable
bool isBitcoinWallet;
@computed
String get balance => _wallet.balance.formattedAvailableBalance ?? '0.0';

@ -5,32 +5,45 @@ part 'unspent_coins_list_view_model.g.dart';
const List<Map<String, dynamic>> unspentCoinsMap = [
<String, dynamic>{
"address" : "11111111111111121111132432432432432432432443124324324234324324324324332424",
"amount" : "222",
"address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
"amount" : "0.00358 BTC",
"isFrozen" : true,
"note" : "333cvgf23132132132132131321321314rwrtdggfdddewq ewqasfdxgdhgfgfszczcxgbhhhbcgbc"},
<String, dynamic>{
"address" : "444",
"amount" : "555",
"address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
"amount" : "0.00567894 BTC",
"note" : "sfjskf"},
<String, dynamic>{
"address" : "777",
"amount" : "888",
"address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
"amount" : "0.00087 BTC",
"isFrozen" : false},
<String, dynamic>{
"address" : "11111111111111121111132432432432432432432443124324324234324324324324332424",
"amount" : "222",
"address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
"amount" : "0.00012 BTC",
"isFrozen" : true,
"note" : "333cvgf23132132132132131321321314rwrtdggfdddewq ewqasfdxgdhgfgfszczcxgbhhhbcgbc"},
<String, dynamic>{
"address" : "444",
"amount" : "555",
"address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
"amount" : "0.00574 BTC",
"note" : "sffsfsdsgs"},
<String, dynamic>{
"address" : "777",
"amount" : "888",
"address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
"amount" : "0.000482 BTC",
"isFrozen" : false},
<String, dynamic>{},
<String, dynamic>{
"address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
"amount" : "0.00012 BTC",
"isFrozen" : true,
"note" : "333cvgf23132132132132131321321314rwrtdggfdddewq ewqasfdxgdhgfgfszczcxgbhhhbcgbc"},
<String, dynamic>{
"address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
"amount" : "0.00574 BTC",
"note" : "sffsfsdsgs"},
<String, dynamic>{
"address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
"amount" : "0.000482 BTC",
"isFrozen" : false},
];
class UnspentCoinsListViewModel = UnspentCoinsListViewModelBase with _$UnspentCoinsListViewModel;

Loading…
Cancel
Save