mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 19:49:22 +00:00
Cw 372 improve monero haven account selection picker (#939)
* refactor: Improve Monero/Haven account selection picker * feat: If the amount would be wrapped, instead display it under the account name * fix: balance str * refactor: add theme changes * refactor: remove duplicate observer
This commit is contained in:
parent
c01321008b
commit
cb0ca169fb
3 changed files with 182 additions and 172 deletions
|
@ -1,176 +1,94 @@
|
|||
import 'package:cake_wallet/src/widgets/picker_inner_wrapper_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/section_divider.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart';
|
||||
import 'package:cake_wallet/src/screens/monero_accounts/widgets/account_tile.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_background.dart';
|
||||
import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
|
||||
|
||||
class MoneroAccountListPage extends StatelessWidget {
|
||||
MoneroAccountListPage({required this.accountListViewModel})
|
||||
: backgroundHeight = 194,
|
||||
thumbHeight = 72,
|
||||
isAlwaysShowScrollThumb = false,
|
||||
controller = ScrollController() {
|
||||
controller.addListener(() {
|
||||
final scrollOffsetFromTop = controller.hasClients
|
||||
? (controller.offset / controller.position.maxScrollExtent * (backgroundHeight - thumbHeight))
|
||||
: 0.0;
|
||||
accountListViewModel.setScrollOffsetFromTop(scrollOffsetFromTop);
|
||||
});
|
||||
}
|
||||
MoneroAccountListPage({required this.accountListViewModel});
|
||||
|
||||
final MoneroAccountListViewModel accountListViewModel;
|
||||
|
||||
ScrollController controller;
|
||||
double backgroundHeight;
|
||||
double thumbHeight;
|
||||
bool isAlwaysShowScrollThumb;
|
||||
final ScrollController controller = ScrollController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertBackground(
|
||||
child: Column(
|
||||
double itemHeight = 80;
|
||||
double buttonHeight = 62;
|
||||
|
||||
return Observer(builder: (_) {
|
||||
final accounts = accountListViewModel.accounts;
|
||||
|
||||
return PickerInnerWrapperWidget(
|
||||
title: S.of(context).choose_account,
|
||||
itemsHeight: (itemHeight * accounts.length) + buttonHeight,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
child: Scrollbar(
|
||||
controller: controller,
|
||||
child: ListView.separated(
|
||||
padding: EdgeInsets.zero,
|
||||
controller: controller,
|
||||
separatorBuilder: (context, index) => const SectionDivider(),
|
||||
itemCount: accounts.length,
|
||||
itemBuilder: (context, index) {
|
||||
final account = accounts[index];
|
||||
|
||||
return AccountTile(
|
||||
isCurrent: account.isSelected,
|
||||
accountName: account.label,
|
||||
accountBalance: account.balance ?? '0.00',
|
||||
currency: accountListViewModel.currency.toString(),
|
||||
onTap: () {
|
||||
if (account.isSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
accountListViewModel.select(account);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
onEdit: () async => await Navigator.of(context)
|
||||
.pushNamed(Routes.accountCreation, arguments: account));
|
||||
},
|
||||
),
|
||||
)),
|
||||
GestureDetector(
|
||||
onTap: () async =>
|
||||
await Navigator.of(context).pushNamed(Routes.accountCreation),
|
||||
child: Container(
|
||||
height: buttonHeight,
|
||||
color: Theme.of(context).cardColor,
|
||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
child: Text(
|
||||
S.of(context).choose_account,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: 'Lato',
|
||||
decoration: TextDecoration.none,
|
||||
color: Colors.white
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.add,
|
||||
color: Colors.white,
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
|
||||
child: GestureDetector(
|
||||
onTap: () => null,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(14)),
|
||||
child: Container(
|
||||
height: 296,
|
||||
color: Theme.of(context).textTheme!.displayLarge!.decorationColor!,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Observer(
|
||||
builder: (_) {
|
||||
final accounts = accountListViewModel.accounts;
|
||||
isAlwaysShowScrollThumb = accounts == null
|
||||
? false
|
||||
: accounts.length > 3;
|
||||
|
||||
return Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.zero,
|
||||
controller: controller,
|
||||
separatorBuilder: (context, index) =>
|
||||
const SectionDivider(),
|
||||
itemCount: accounts.length ?? 0,
|
||||
itemBuilder: (context, index) {
|
||||
final account = accounts[index];
|
||||
|
||||
return AccountTile(
|
||||
isCurrent: account.isSelected,
|
||||
accountName: account.label,
|
||||
accountBalance: account.balance ?? '0.00',
|
||||
currency: accountListViewModel
|
||||
.currency.toString(),
|
||||
onTap: () {
|
||||
if (account.isSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
accountListViewModel
|
||||
.select(account);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
onEdit: () async =>
|
||||
await Navigator.of(context)
|
||||
.pushNamed(
|
||||
Routes.accountCreation,
|
||||
arguments: account));
|
||||
},
|
||||
),
|
||||
isAlwaysShowScrollThumb
|
||||
? CakeScrollbar(
|
||||
backgroundHeight: backgroundHeight,
|
||||
thumbHeight: thumbHeight,
|
||||
fromTop: accountListViewModel
|
||||
.scrollOffsetFromTop
|
||||
)
|
||||
: Offstage(),
|
||||
],
|
||||
);
|
||||
}
|
||||
)
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () async => await Navigator.of(context)
|
||||
.pushNamed(Routes.accountCreation),
|
||||
child: Container(
|
||||
height: 62,
|
||||
color: Theme.of(context).cardColor,
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
Icons.add,
|
||||
color: Colors.white,
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 5),
|
||||
child: Text(
|
||||
S.of(context).create_new_account,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.only(left: 5),
|
||||
child: Text(
|
||||
S.of(context).create_new_account,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: ResponsiveLayoutUtil.kPopupSpaceHeight),
|
||||
AlertCloseButton()
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class AccountTile extends StatelessWidget {
|
||||
AccountTile({
|
||||
required this.isCurrent,
|
||||
required this.accountName,
|
||||
this.accountBalance,
|
||||
required this.currency,
|
||||
required this.onTap,
|
||||
required this.onEdit
|
||||
});
|
||||
AccountTile(
|
||||
{required this.isCurrent,
|
||||
required this.accountName,
|
||||
this.accountBalance,
|
||||
required this.currency,
|
||||
required this.onTap,
|
||||
required this.onEdit});
|
||||
|
||||
final bool isCurrent;
|
||||
final String accountName;
|
||||
|
@ -32,11 +31,13 @@ class AccountTile extends StatelessWidget {
|
|||
height: 77,
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
color: color,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
child: Wrap(
|
||||
direction: Axis.horizontal,
|
||||
alignment: WrapAlignment.spaceBetween,
|
||||
runAlignment: WrapAlignment.center,
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
Container(
|
||||
child: Text(
|
||||
accountName,
|
||||
style: TextStyle(
|
||||
|
@ -49,19 +50,19 @@ class AccountTile extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
if (accountBalance != null)
|
||||
Expanded(
|
||||
child: Text(
|
||||
'${accountBalance.toString()} $currency',
|
||||
textAlign: TextAlign.end,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).textTheme!.headlineMedium!.color!,
|
||||
decoration: TextDecoration.none,
|
||||
Container(
|
||||
child: Text(
|
||||
'${accountBalance.toString()} $currency',
|
||||
textAlign: TextAlign.end,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).textTheme!.headlineMedium!.color!,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -80,4 +81,4 @@ class AccountTile extends StatelessWidget {
|
|||
// onTap: () => onEdit?.call())
|
||||
// ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
91
lib/src/widgets/picker_inner_wrapper_widget.dart
Normal file
91
lib/src/widgets/picker_inner_wrapper_widget.dart
Normal file
|
@ -0,0 +1,91 @@
|
|||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
|
||||
|
||||
class PickerInnerWrapperWidget extends StatelessWidget {
|
||||
PickerInnerWrapperWidget(
|
||||
{required this.children, this.title, this.itemsHeight});
|
||||
|
||||
final List<Widget> children;
|
||||
final String? title;
|
||||
final double? itemsHeight;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final mq = MediaQuery.of(context);
|
||||
final bottom = mq.viewInsets.bottom;
|
||||
final height = mq.size.height - bottom;
|
||||
|
||||
double containerHeight = height * 0.65;
|
||||
if (bottom > 0) {
|
||||
// increase a bit or it gets too squished in the top
|
||||
containerHeight = height * 0.75;
|
||||
}
|
||||
|
||||
if (title != null) {
|
||||
return PickerWrapperWidget(
|
||||
hasTitle: true,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Text(
|
||||
title!,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: 'Lato',
|
||||
decoration: TextDecoration.none,
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(14)),
|
||||
child: Container(
|
||||
color: Theme.of(context).textTheme.displayLarge!.decorationColor!,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight:
|
||||
itemsHeight != null && itemsHeight! <= containerHeight
|
||||
? itemsHeight!
|
||||
: containerHeight,
|
||||
maxWidth: ResponsiveLayoutUtil.kPopupWidth,
|
||||
),
|
||||
child: Column(
|
||||
children: children,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return PickerWrapperWidget(
|
||||
hasTitle: false,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(14)),
|
||||
child: Container(
|
||||
color: Theme.of(context).textTheme.displayLarge!.decorationColor!,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: containerHeight,
|
||||
maxWidth: ResponsiveLayoutUtil.kPopupWidth,
|
||||
),
|
||||
child: Column(
|
||||
children: children,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue