CAKE-15 | implemented new design to dashboard page; created balance page; applied sync indicator to balance page; applied action buttons, page view and dots indicator to dashboard page; added colors of dashboard page to palette

This commit is contained in:
Oleksandr Sobol
2020-07-21 20:22:41 +03:00
parent f45875ba3a
commit 12ee8a519d
16 changed files with 400 additions and 133 deletions
+121 -108
View File
@@ -4,49 +4,43 @@ import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/view_model/dashboard_view_model.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/wallet_card.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/trade_history_panel.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/menu_widget.dart';
import 'package:cake_wallet/palette.dart';
import 'package:dots_indicator/dots_indicator.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/action_button.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
class DashboardPage extends BasePage {
DashboardPage({@required this.walletViewModel});
@override
Color get backgroundLightColor => Colors.transparent;
Color get backgroundLightColor => PaletteDark.backgroundColor;
@override
Color get backgroundDarkColor => Colors.transparent;
@override
Widget Function(BuildContext, Widget) get rootWrapper =>
(BuildContext context, Widget scaffold) => Container(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Theme.of(context).scaffoldBackgroundColor,
Theme.of(context).primaryColor
], begin: Alignment.topLeft, end: Alignment.bottomRight)),
child: scaffold);
Color get backgroundDarkColor => PaletteDark.backgroundColor;
@override
Widget trailing(BuildContext context) {
final menuButton = Image.asset('assets/images/header.png',
color: Theme.of(context).primaryTextTheme.title.color);
final menuButton = Image.asset('assets/images/menu.png',
color: Colors.white);
return Container(
alignment: Alignment.centerRight,
child: SizedBox(
width: 24,
width: 20,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
onPressed: () async {
await showDialog<void>(
builder: (_) => MenuWidget(
name: walletViewModel.name,
subname: walletViewModel.subname,
type: walletViewModel.type),
context: context);
builder: (_) => MenuWidget(
name: walletViewModel.name,
subname: walletViewModel.subname,
type: walletViewModel.type),
context: context);
},
child: menuButton),
),
@@ -54,97 +48,116 @@ class DashboardPage extends BasePage {
}
final DashboardViewModel walletViewModel;
final sendImage = Image.asset('assets/images/send.png');
final exchangeImage = Image.asset('assets/images/exchange.png');
final buyImage = Image.asset('assets/images/coins.png');
final sendImage = Image.asset('assets/images/upload.png');
final exchangeImage = Image.asset('assets/images/transfer.png');
final receiveImage = Image.asset('assets/images/download.png');
final controller = PageController(initialPage: 0);
var pages = <Widget>[];
bool _isEffectsInstalled = false;
@override
Widget body(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
final transactionListMinHeight =
constraints.heightConstraints().maxHeight - 345 - 32;
return SingleChildScrollView(
child: Column(children: [
Container(
height: 345,
child: Column(children: [
Padding(
padding: EdgeInsets.only(left: 24, top: 10),
child: WalletCard(walletVM: walletViewModel)),
Container(
padding: EdgeInsets.only(left: 44, right: 44, top: 32),
child: Row(
children: <Widget>[
Flexible(
child: actionButton(
context: context,
image: sendImage,
title: S.of(context).send,
route: Routes.send)),
Flexible(
child: actionButton(
context: context,
image: exchangeImage,
title: S.of(context).exchange,
route: Routes.exchange)),
],
),
_setEffects();
return SafeArea(
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: PageView.builder(
controller: controller,
itemCount: pages.length,
itemBuilder: (context, index) {
return pages[index];
}
)
])),
SizedBox(height: 32),
ConstrainedBox(
constraints: BoxConstraints(minHeight: transactionListMinHeight),
child: TradeHistoryPanel(dashboardViewModel: walletViewModel)),
// Column(children: [
// Text('1'),
// Text('2')
// ])
]));
),
Padding(
padding: EdgeInsets.only(
bottom: 24
),
child: Observer(
builder: (_) {
return DotsIndicator(
dotsCount: pages.length,
position: walletViewModel.currentPage,
decorator: DotsDecorator(
color: PaletteDark.cyanBlue,
activeColor: Colors.white,
size: Size(6, 6),
activeSize: Size(6, 6),
),
);
}
),
),
Container(
width: double.infinity,
padding: EdgeInsets.only(
left: 45,
right: 45,
bottom: 24
),
child: Row(
children: <Widget>[
Flexible(
child: ActionButton(
image: sendImage,
title: S.of(context).send,
route: Routes.send,
alignment: Alignment.centerLeft,
),
),
Flexible(
child: ActionButton(
image: exchangeImage,
title: S.of(context).exchange,
route: Routes.exchange
),
),
Flexible(
child: ActionButton(
image: receiveImage,
title: S.of(context).receive,
route: Routes.receive,
alignment: Alignment.centerRight,
),
)
],
),
)
],
)
);
}
void _setEffects() {
if (_isEffectsInstalled) {
return;
}
pages.add(BalancePage(dashboardViewModel: walletViewModel));
pages.add(Center(
child: Text(
'SECOND PAGE',
style: TextStyle(
color: Colors.white
),
),
));
controller.addListener(() {
walletViewModel.currentPage = controller.page;
});
reaction((_) => walletViewModel.currentPage, (double currentPage) {
if (controller.page != currentPage) {
controller.jumpTo(currentPage);
}
});
_isEffectsInstalled = true;
}
}
Widget actionButton(
{BuildContext context,
@required Image image,
@required String title,
@required String route}) {
return Container(
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
GestureDetector(
onTap: () {
if (route.isNotEmpty) {
Navigator.of(context, rootNavigator: true).pushNamed(route);
}
},
child: Container(
height: 48,
width: 48,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Theme.of(context).primaryTextTheme.subhead.color,
shape: BoxShape.circle),
child: image,
),
),
Padding(
padding: EdgeInsets.only(top: 12),
child: Text(
title,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Color.fromRGBO(140, 153, 201,
0.8) // Theme.of(context).primaryTextTheme.caption.color
),
),
)
],
),
);
}
@@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
class ActionButton extends StatelessWidget{
ActionButton({
@required this.image,
@required this.title,
@required this.route,
this.alignment = Alignment.center
});
final Image image;
final String title;
final String route;
final Alignment alignment;
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: 93,
alignment: alignment,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
GestureDetector(
onTap: () {
if (route.isNotEmpty) {
Navigator.of(context, rootNavigator: true).pushNamed(route);
}
},
child: Container(
height: 60,
width: 60,
alignment: Alignment.center,
decoration: BoxDecoration(
color: PaletteDark.nightBlue,
shape: BoxShape.circle),
child: image,
),
),
Text(
title,
style: TextStyle(
fontSize: 14,
color: Colors.white
),
)
],
),
);
}
}
@@ -0,0 +1,91 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/dashboard_view_model.dart';
import 'package:cake_wallet/palette.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart';
class BalancePage extends StatelessWidget {
BalancePage({@required this.dashboardViewModel});
final DashboardViewModel dashboardViewModel;
final triangleImage = Image.asset('assets/images/triangle.png');
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(
top: 12,
left: 24,
right: 24,
bottom: 24
),
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Positioned(
top: 0,
child: SyncIndicator(dashboardViewModel: dashboardViewModel)
),
Container(
height: 160,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Observer(
builder: (_) {
return Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
dashboardViewModel.wallet.currency.toString(),
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
color: PaletteDark.cyanBlue,
height: 1
),
),
Padding(
padding: EdgeInsets.only(left: 8),
child: triangleImage,
)
],
);
}
),
Observer(
builder: (_) {
return Text(
dashboardViewModel.balance.totalBalance,
style: TextStyle(
fontSize: 54,
fontWeight: FontWeight.bold,
color: Colors.white,
height: 1
),
);
}
),
Observer(
builder: (_) {
return Text(
'\$ 0.00',
style: TextStyle(
fontSize: 18,
color: PaletteDark.cyanBlue,
height: 1
),
);
}
),
],
),
)
],
),
);
}
}
@@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/dashboard_view_model.dart';
import 'package:cake_wallet/palette.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/src/domain/common/sync_status.dart';
class SyncIndicator extends StatelessWidget {
SyncIndicator({@required this.dashboardViewModel});
final DashboardViewModel dashboardViewModel;
@override
Widget build(BuildContext context) {
return Observer(
builder: (_) {
final syncIndicatorWidth = 250.0;
final status = dashboardViewModel.status;
final statusText = status.title();
final progress = status.progress();
final indicatorOffset = progress * syncIndicatorWidth;
final indicatorWidth =
progress <= 1 ? syncIndicatorWidth - indicatorOffset : 0.0;
final indicatorColor = status is SyncedSyncStatus
? PaletteDark.brightGreen
: PaletteDark.orangeYellow;
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(15)),
child: Container(
height: 30,
width: syncIndicatorWidth,
color: PaletteDark.lightNightBlue,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
progress <= 1
? Positioned(
left: indicatorOffset,
top: 0,
bottom: 0,
child: Container(
width: indicatorWidth,
height: 30,
color: PaletteDark.oceanBlue,
)
)
: Offstage(),
Padding(
padding: EdgeInsets.only(
left: 24,
right: 24
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: 4,
width: 4,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: indicatorColor
),
),
Padding(
padding: EdgeInsets.only(left: 6),
child: Text(
statusText,
style: TextStyle(
fontSize: 12,
color: PaletteDark.wildBlue
),
),
)
],
),
)
],
),
),
);
}
);
}
}