CWA-201 | added wallet tiles to wallet list page; added colors and images to wallet menu

This commit is contained in:
Oleksandr Sobol 2020-04-23 21:36:52 +03:00
parent f5e1635380
commit 07aaf77167
11 changed files with 286 additions and 84 deletions

BIN
assets/images/2.0x/load.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

BIN
assets/images/3.0x/load.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
assets/images/load.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 B

BIN
assets/images/scanner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

BIN
assets/images/trash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

View file

@ -6,22 +6,15 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/domain/common/wallet_description.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/src/stores/wallet_list/wallet_list_store.dart'; import 'package:cake_wallet/src/stores/wallet_list/wallet_list_store.dart';
import 'package:cake_wallet/src/screens/wallet_list/wallet_menu.dart'; import 'package:cake_wallet/src/screens/wallet_list/wallet_menu.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
class WalletListPage extends BasePage { class WalletListPage extends BasePage {
@override
bool get isModalBackButton => true;
@override @override
String get title => S.current.wallet_list_title; ObstructingPreferredSizeWidget appBar(BuildContext context) => null;
@override
AppBarStyle get appBarStyle => AppBarStyle.withShadow;
@override @override
Widget body(BuildContext context) => WalletListBody(); Widget body(BuildContext context) => WalletListBody();
@ -33,92 +26,265 @@ class WalletListBody extends StatefulWidget {
} }
class WalletListBodyState extends State<WalletListBody> { class WalletListBodyState extends State<WalletListBody> {
final moneroIcon = Image.asset('assets/images/monero.png', height: 24, width: 24);
WalletListStore _walletListStore; WalletListStore _walletListStore;
void presetMenuForWallet(WalletDescription wallet, bool isCurrentWallet,
BuildContext bodyContext) {
final walletMenu = WalletMenu(bodyContext);
final items = walletMenu.generateItemsForWalletMenu(isCurrentWallet);
showDialog<void>(
context: bodyContext,
builder: (_) => Picker(
items: items,
selectedAtIndex: -1,
title: S.of(context).wallet_menu,
onItemSelected: (String item) => walletMenu.action(
walletMenu.listItems.indexOf(item), wallet, isCurrentWallet)),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_walletListStore = Provider.of<WalletListStore>(context); _walletListStore = Provider.of<WalletListStore>(context);
return ScrollableWithBottomSection( return SafeArea(
content: Container( child: Container(
padding: EdgeInsets.all(20), padding: EdgeInsets.only(top: 32),
child: Observer( color: PaletteDark.menuHeader,
builder: (_) => ListView.separated( child: ScrollableWithBottomSection(
shrinkWrap: true, contentPadding: EdgeInsets.only(bottom: 20),
physics: const NeverScrollableScrollPhysics(), content: Container(
separatorBuilder: (_, index) => Divider( child: Observer(
color: Theme.of(context).dividerTheme.color, height: 1.0), builder: (_) => ListView.separated(
itemCount: _walletListStore.wallets.length, shrinkWrap: true,
itemBuilder: (__, index) { physics: const NeverScrollableScrollPhysics(),
final wallet = _walletListStore.wallets[index]; separatorBuilder: (_, index) => Divider(
final isCurrentWallet = color: PaletteDark.menuHeader, height: 16),
itemCount: _walletListStore.wallets.length,
itemBuilder: (__, index) {
final wallet = _walletListStore.wallets[index];
final screenWidth = MediaQuery.of(context).size.width;
final isCurrentWallet =
_walletListStore.isCurrentWallet(wallet); _walletListStore.isCurrentWallet(wallet);
return InkWell( final walletMenu = WalletMenu(context);
onTap: () => final items = walletMenu.generateItemsForWalletMenu(isCurrentWallet);
presetMenuForWallet(wallet, isCurrentWallet, context), final colors = walletMenu.generateColorsForWalletMenu(isCurrentWallet);
child: Container( final images = walletMenu.generateImagesForWalletMenu(isCurrentWallet);
padding: EdgeInsets.only(left: 10.0, right: 10.0),
child: ListTile( return Container(
title: Text( height: 108,
wallet.name, width: double.infinity,
style: TextStyle( child: CustomScrollView(
color: isCurrentWallet scrollDirection: Axis.horizontal,
? Palette.cakeGreen slivers: <Widget>[
: Theme.of(context) SliverPersistentHeader(
.primaryTextTheme pinned: false,
.headline floating: true,
.color, delegate: WalletTile(
fontSize: 18.0, min: screenWidth - 228,
fontWeight: FontWeight.w600), max: screenWidth,
image: moneroIcon,
walletName: wallet.name,
walletAddress: '',
isCurrent: isCurrentWallet
), ),
trailing: isCurrentWallet ),
? Icon( SliverList(
Icons.check, delegate: SliverChildBuilderDelegate(
color: Palette.cakeGreen, (context, index) {
size: 20.0,
) final item = items[index];
: null))); final color = colors[index];
}), final image = images[index];
),
), final content = Center(
bottomSection: Column(children: <Widget>[ child: Column(
PrimaryIconButton( mainAxisSize: MainAxisSize.min,
onPressed: () => Navigator.of(context).pushNamed(Routes.newWallet), children: <Widget>[
iconData: Icons.add, image,
color: Theme.of(context).primaryTextTheme.button.backgroundColor, SizedBox(height: 5),
borderColor: Text(
item,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
color: Colors.white
),
)
],
),
);
if (index == 0) {
return GestureDetector(
onTap: () => walletMenu.action(
walletMenu.listItems.indexOf(item), wallet, isCurrentWallet),
child: Container(
height: 108,
width: 108,
color: PaletteDark.menuHeader,
child: Container(
padding: EdgeInsets.only(left: 5, right: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
bottomLeft: Radius.circular(12)
),
color: color
),
child: content,
),
),
);
}
return GestureDetector(
onTap: () => walletMenu.action(
walletMenu.listItems.indexOf(item), wallet, isCurrentWallet),
child: Container(
height: 108,
width: 108,
padding: EdgeInsets.only(left: 5, right: 5),
color: color,
child: content,
),
);
},
childCount: items.length
)
)
],
),
);
}),
),
),
bottomSection: Column(children: <Widget>[
PrimaryIconButton(
onPressed: () => Navigator.of(context).pushNamed(Routes.newWallet),
iconData: Icons.add,
color: Theme.of(context).primaryTextTheme.button.backgroundColor,
borderColor:
Theme.of(context).primaryTextTheme.button.decorationColor, Theme.of(context).primaryTextTheme.button.decorationColor,
iconColor: Palette.violet, iconColor: Palette.violet,
iconBackgroundColor: Theme.of(context).primaryIconTheme.color, iconBackgroundColor: Theme.of(context).primaryIconTheme.color,
text: S.of(context).wallet_list_create_new_wallet), text: S.of(context).wallet_list_create_new_wallet),
SizedBox(height: 10.0), SizedBox(height: 10.0),
PrimaryIconButton( PrimaryIconButton(
onPressed: () => onPressed: () =>
Navigator.of(context).pushNamed(Routes.restoreWalletOptions), Navigator.of(context).pushNamed(Routes.restoreWalletOptions),
iconData: Icons.refresh, iconData: Icons.refresh,
text: S.of(context).wallet_list_restore_wallet, text: S.of(context).wallet_list_restore_wallet,
color: Theme.of(context).accentTextTheme.button.backgroundColor, color: Theme.of(context).accentTextTheme.button.backgroundColor,
borderColor: borderColor:
Theme.of(context).accentTextTheme.button.decorationColor, Theme.of(context).accentTextTheme.button.decorationColor,
iconColor: Theme.of(context).primaryTextTheme.caption.color, iconColor: Theme.of(context).primaryTextTheme.caption.color,
iconBackgroundColor: Theme.of(context).accentIconTheme.color) iconBackgroundColor: Theme.of(context).accentIconTheme.color)
])); ])),
)
);
} }
} }
class WalletTile extends SliverPersistentHeaderDelegate {
WalletTile({
@required this.min,
@required this.max,
@required this.image,
@required this.walletName,
@required this.walletAddress,
@required this.isCurrent
});
final double min;
final double max;
final Image image;
final String walletName;
final String walletAddress;
final bool isCurrent;
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
double opacity = 1 - shrinkOffset / (max - min);
opacity = opacity >= 0 ? opacity : 0;
double panelWidth = 12 * opacity;
panelWidth = panelWidth < 12 ? 0 : 12;
final currentColor = isCurrent
? Colors.white
: PaletteDark.menuHeader;
return Stack(
fit: StackFit.expand,
overflow: Overflow.visible,
children: <Widget>[
Positioned(
top: 0,
right: max - 4,
child: Container(
height: 108,
width: 4,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topRight: Radius.circular(4), bottomRight: Radius.circular(4)),
color: currentColor
),
),
),
Positioned(
top: 0,
right: 12,
child: Container(
height: 108,
width: max - 16,
padding: EdgeInsets.only(left: 20, right: 20),
color: PaletteDark.menuHeader,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
image,
SizedBox(width: 10),
Text(
walletName,
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Colors.white
),
)
],
)
],
),
),
),
Positioned(
top: 0,
right: 0,
child: Opacity(
opacity: opacity,
child: Container(
height: 108,
width: panelWidth,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(12), bottomLeft: Radius.circular(12)),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
PaletteDark.walletCardTopEndSync,
PaletteDark.walletCardBottomEndSync
]
)
),
),
)
),
],
);
}
@override
double get maxExtent => max;
@override
double get minExtent => min;
@override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
}

View file

@ -18,6 +18,20 @@ class WalletMenu {
S.current.rescan S.current.rescan
]; ];
final List<Color> listColors = [
Colors.blue,
Colors.orange,
Colors.red,
Colors.green
];
final List<Image> listImages = [
Image.asset('assets/images/load.png', height: 32, width: 32, color: Colors.white),
Image.asset('assets/images/eye.png', height: 32, width: 32, color: Colors.white),
Image.asset('assets/images/trash.png', height: 32, width: 32, color: Colors.white),
Image.asset('assets/images/scanner.png', height: 32, width: 32, color: Colors.white)
];
List<String> generateItemsForWalletMenu(bool isCurrentWallet) { List<String> generateItemsForWalletMenu(bool isCurrentWallet) {
final items = List<String>(); final items = List<String>();
@ -29,6 +43,28 @@ class WalletMenu {
return items; return items;
} }
List<Color> generateColorsForWalletMenu(bool isCurrentWallet) {
final colors = List<Color>();
if (!isCurrentWallet) colors.add(listColors[0]);
if (isCurrentWallet) colors.add(listColors[1]);
if (!isCurrentWallet) colors.add(listColors[2]);
if (isCurrentWallet) colors.add(listColors[3]);
return colors;
}
List<Image> generateImagesForWalletMenu(bool isCurrentWallet) {
final images = List<Image>();
if (!isCurrentWallet) images.add(listImages[0]);
if (isCurrentWallet) images.add(listImages[1]);
if (!isCurrentWallet) images.add(listImages[2]);
if (isCurrentWallet) images.add(listImages[3]);
return images;
}
void action(int index, WalletDescription wallet, bool isCurrentWallet) { void action(int index, WalletDescription wallet, bool isCurrentWallet) {
final _walletListStore = Provider.of<WalletListStore>(context); final _walletListStore = Provider.of<WalletListStore>(context);