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/generated/i18n.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/widgets/scollable_with_bottom_section.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/widgets/picker.dart';
class WalletListPage extends BasePage {
@override
bool get isModalBackButton => true;
@override
String get title => S.current.wallet_list_title;
@override
AppBarStyle get appBarStyle => AppBarStyle.withShadow;
ObstructingPreferredSizeWidget appBar(BuildContext context) => null;
@override
Widget body(BuildContext context) => WalletListBody();
@ -33,92 +26,265 @@ class WalletListBody extends StatefulWidget {
}
class WalletListBodyState extends State<WalletListBody> {
final moneroIcon = Image.asset('assets/images/monero.png', height: 24, width: 24);
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
Widget build(BuildContext context) {
_walletListStore = Provider.of<WalletListStore>(context);
return ScrollableWithBottomSection(
content: Container(
padding: EdgeInsets.all(20),
child: Observer(
builder: (_) => ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
separatorBuilder: (_, index) => Divider(
color: Theme.of(context).dividerTheme.color, height: 1.0),
itemCount: _walletListStore.wallets.length,
itemBuilder: (__, index) {
final wallet = _walletListStore.wallets[index];
final isCurrentWallet =
return SafeArea(
child: Container(
padding: EdgeInsets.only(top: 32),
color: PaletteDark.menuHeader,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 20),
content: Container(
child: Observer(
builder: (_) => ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
separatorBuilder: (_, index) => Divider(
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);
return InkWell(
onTap: () =>
presetMenuForWallet(wallet, isCurrentWallet, context),
child: Container(
padding: EdgeInsets.only(left: 10.0, right: 10.0),
child: ListTile(
title: Text(
wallet.name,
style: TextStyle(
color: isCurrentWallet
? Palette.cakeGreen
: Theme.of(context)
.primaryTextTheme
.headline
.color,
fontSize: 18.0,
fontWeight: FontWeight.w600),
final walletMenu = WalletMenu(context);
final items = walletMenu.generateItemsForWalletMenu(isCurrentWallet);
final colors = walletMenu.generateColorsForWalletMenu(isCurrentWallet);
final images = walletMenu.generateImagesForWalletMenu(isCurrentWallet);
return Container(
height: 108,
width: double.infinity,
child: CustomScrollView(
scrollDirection: Axis.horizontal,
slivers: <Widget>[
SliverPersistentHeader(
pinned: false,
floating: true,
delegate: WalletTile(
min: screenWidth - 228,
max: screenWidth,
image: moneroIcon,
walletName: wallet.name,
walletAddress: '',
isCurrent: isCurrentWallet
),
trailing: isCurrentWallet
? Icon(
Icons.check,
color: Palette.cakeGreen,
size: 20.0,
)
: null)));
}),
),
),
bottomSection: Column(children: <Widget>[
PrimaryIconButton(
onPressed: () => Navigator.of(context).pushNamed(Routes.newWallet),
iconData: Icons.add,
color: Theme.of(context).primaryTextTheme.button.backgroundColor,
borderColor:
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
final item = items[index];
final color = colors[index];
final image = images[index];
final content = Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
image,
SizedBox(height: 5),
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,
iconColor: Palette.violet,
iconBackgroundColor: Theme.of(context).primaryIconTheme.color,
text: S.of(context).wallet_list_create_new_wallet),
SizedBox(height: 10.0),
PrimaryIconButton(
onPressed: () =>
Navigator.of(context).pushNamed(Routes.restoreWalletOptions),
iconData: Icons.refresh,
text: S.of(context).wallet_list_restore_wallet,
color: Theme.of(context).accentTextTheme.button.backgroundColor,
borderColor:
iconColor: Palette.violet,
iconBackgroundColor: Theme.of(context).primaryIconTheme.color,
text: S.of(context).wallet_list_create_new_wallet),
SizedBox(height: 10.0),
PrimaryIconButton(
onPressed: () =>
Navigator.of(context).pushNamed(Routes.restoreWalletOptions),
iconData: Icons.refresh,
text: S.of(context).wallet_list_restore_wallet,
color: Theme.of(context).accentTextTheme.button.backgroundColor,
borderColor:
Theme.of(context).accentTextTheme.button.decorationColor,
iconColor: Theme.of(context).primaryTextTheme.caption.color,
iconBackgroundColor: Theme.of(context).accentIconTheme.color)
]));
iconColor: Theme.of(context).primaryTextTheme.caption.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
];
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) {
final items = List<String>();
@ -29,6 +43,28 @@ class WalletMenu {
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) {
final _walletListStore = Provider.of<WalletListStore>(context);