You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

508 lines
22 KiB

import 'dart:async';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/src/domain/common/balance_display_mode.dart';
import 'package:cake_wallet/src/stores/balance/balance_store.dart';
import 'package:cake_wallet/src/stores/settings/settings_store.dart';
import 'package:cake_wallet/src/stores/sync/sync_store.dart';
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/domain/common/sync_status.dart';
import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/view_model/dashboard_view_model.dart';
class WalletCard extends StatefulWidget {
WalletCard({this.walletVM});
DashboardViewModel walletVM;
@override
WalletCardState createState() => WalletCardState();
}
class WalletCardState extends State<WalletCard> {
final _syncingObserverKey = GlobalKey();
final _balanceObserverKey = GlobalKey();
final _addressObserverKey = GlobalKey();
double cardWidth;
double cardHeight;
double screenWidth;
double opacity;
bool isDraw;
bool isFrontSide;
@override
void initState() {
cardWidth = 0;
cardHeight = 220;
screenWidth = 0;
opacity = 0;
isDraw = false;
isFrontSide = true;
super.initState();
WidgetsBinding.instance.addPostFrameCallback(afterLayout);
}
void afterLayout(dynamic _) {
screenWidth = MediaQuery.of(context).size.width - 20;
setState(() {
cardWidth = screenWidth;
opacity = 1;
});
Timer(Duration(milliseconds: 500), () => setState(() => isDraw = true));
}
@override
Widget build(BuildContext context) {
final colorsSync = [
Theme.of(context).cardTheme.color,
Theme.of(context).hoverColor
];
return Container(
width: double.infinity,
height: cardHeight,
alignment: Alignment.centerRight,
child: AnimatedContainer(
alignment: Alignment.centerLeft,
width: cardWidth,
height: cardHeight,
duration: Duration(milliseconds: 500),
curve: Curves.fastOutSlowIn,
padding: EdgeInsets.only(top: 1, left: 1, bottom: 1),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10)),
color: Theme.of(context).focusColor,
boxShadow: [
BoxShadow(
color: PaletteDark.darkNightBlue.withOpacity(0.5),
blurRadius: 8,
offset: Offset(5, 5))
]),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10), bottomLeft: Radius.circular(10)),
child: Container(
width: cardWidth,
height: cardHeight,
color: Theme.of(context).cardColor,
child: InkWell(
onTap: () => setState(() => isFrontSide = !isFrontSide),
child: isFrontSide
? frontSide(colorsSync)
: backSide(colorsSync)),
),
)),
);
}
Widget frontSide(List<Color> colorsSync) {
// final syncStore = Provider.of<SyncStore>(context);
// final walletStore = Provider.of<WalletStore>(context);
final settingsStore = Provider.of<SettingsStore>(context);
// final balanceStore = Provider.of<BalanceStore>(context);
final triangleButton = Image.asset(
'assets/images/triangle.png',
color: Theme.of(context).primaryTextTheme.title.color,
);
return Observer(
key: _syncingObserverKey,
builder: (_) {
final status = widget.walletVM.status;
final statusText = status.title();
final progress = status.progress();
final indicatorWidth = progress * cardWidth;
final shortAddress = widget.walletVM.address
.replaceRange(4, widget.walletVM.address.length - 4, '...');
var descriptionText = '';
if (status is SyncingSyncStatus) {
descriptionText = S.of(context).Blocks_remaining(status.toString());
}
if (status is FailedSyncStatus) {
descriptionText = S.of(context).please_try_to_connect_to_another_node;
}
return Container(
width: cardWidth,
height: cardHeight,
child: Stack(
children: <Widget>[
Container(
height: cardHeight,
width: indicatorWidth,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10)),
gradient: LinearGradient(
colors: colorsSync,
begin: Alignment.topCenter,
end: Alignment.bottomCenter)),
),
progress != 1
? Positioned(
left: indicatorWidth,
top: 0,
bottom: 0,
child: Container(
width: 1,
height: cardHeight,
color: Theme.of(context).focusColor,
))
: Offstage(),
isDraw
? Positioned(
left: 20,
right: 20,
top: 30,
bottom: 30,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
InkWell(
onTap: () {},
child: Row(
children: <Widget>[
Text(
widget.walletVM.name,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
),
SizedBox(width: 10),
triangleButton
],
),
),
SizedBox(height: 5),
if (widget.walletVM.subname?.isNotEmpty ?? false)
Text(
widget.walletVM.subname,
style: TextStyle(
fontSize: 12,
color: Theme.of(context)
.primaryTextTheme
.caption
.color),
)
],
),
Container(
width: 98,
height: 32,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Theme.of(context)
.accentTextTheme
.subtitle
.backgroundColor,
borderRadius: BorderRadius.all(
Radius.circular(16))),
child: Text(
shortAddress,
style: TextStyle(
fontSize: 12,
color: Theme.of(context)
.primaryTextTheme
.caption
.color),
),
)
],
),
status is SyncedSyncStatus
? Observer(
key: _balanceObserverKey,
builder: (_) {
final balanceDisplayMode =
BalanceDisplayMode.fullBalance;
// settingsStore.balanceDisplayMode;
final symbol =
settingsStore.fiatCurrency.toString();
var balance = '---';
var fiatBalance = '---';
if (balanceDisplayMode ==
BalanceDisplayMode.availableBalance) {
balance = widget.walletVM.balance
.unlockedBalance ??
'0.0';
fiatBalance = '\$ 123.43';
// '$symbol ${balanceStore.fiatUnlockedBalance}';
}
if (balanceDisplayMode ==
BalanceDisplayMode.fullBalance) {
balance = widget.walletVM.balance
.totalBalance ??
'0.0';
fiatBalance = '\$ 123.43';
// '$symbol ${balanceStore.fiatFullBalance}';
}
return Row(
crossAxisAlignment:
CrossAxisAlignment.end,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(
balanceDisplayMode.toString(),
style: TextStyle(
fontSize: 12,
color: Theme.of(context)
.primaryTextTheme
.caption
.color),
),
SizedBox(height: 5),
Text(
balance,
style: TextStyle(
fontSize: 28,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
)
],
),
Text(
fiatBalance,
style: TextStyle(
fontSize: 14,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
)
],
);
})
: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(
statusText,
style: TextStyle(
fontSize: 12,
color: Theme.of(context)
.primaryTextTheme
.caption
.color),
),
SizedBox(height: 5),
Text(
descriptionText,
style: TextStyle(
fontSize: 14,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
)
],
)
],
)
],
),
))
: Offstage()
],
),
);
},
);
}
Widget backSide(List<Color> colorsSync) {
final rightArrow = Image.asset(
'assets/images/right_arrow.png',
color: Theme.of(context).primaryTextTheme.title.color,
);
var messageBoxHeight = 0.0;
var messageBoxWidth = cardWidth - 10;
return Observer(
key: _addressObserverKey,
builder: (_) {
return Container(
width: cardWidth,
height: cardHeight,
alignment: Alignment.topCenter,
child: Stack(
alignment: Alignment.topRight,
children: <Widget>[
Container(
width: cardWidth,
height: cardHeight,
padding:
EdgeInsets.only(left: 20, right: 20, top: 30, bottom: 30),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10)),
gradient: LinearGradient(
colors: colorsSync,
begin: Alignment.topCenter,
end: Alignment.bottomCenter)),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Container(
height: 90,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
S.current.card_address,
style: TextStyle(
fontSize: 12,
color: Theme.of(context)
.primaryTextTheme
.caption
.color),
),
SizedBox(height: 10),
GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(
text: widget.walletVM.address));
_addressObserverKey.currentState
.setState(() {
messageBoxHeight = 20;
messageBoxWidth = cardWidth;
});
Timer(Duration(milliseconds: 1000), () {
try {
_addressObserverKey.currentState
.setState(() {
messageBoxHeight = 0;
messageBoxWidth = cardWidth - 10;
});
} catch (e) {
print('${e.toString()}');
}
});
},
child: Text(
widget.walletVM.address,
style: TextStyle(
fontSize: 14,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
),
)
],
),
)),
SizedBox(width: 10),
Container(
width: 90,
height: 90,
child: QrImage(
data: widget.walletVM.address,
backgroundColor: Colors.transparent,
foregroundColor: Theme.of(context)
.primaryTextTheme
.caption
.color),
)
],
),
Container(
height: 44,
padding: EdgeInsets.only(left: 20, right: 20),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(22)),
color: Theme.of(context)
.primaryTextTheme
.overline
.color),
child: InkWell(
onTap: () =>
Navigator.of(context, rootNavigator: true)
.pushNamed(Routes.receive),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
S.of(context).accounts_subaddresses,
style: TextStyle(
fontSize: 14,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
),
rightArrow
],
),
),
)
],
),
),
AnimatedContainer(
width: messageBoxWidth,
height: messageBoxHeight,
alignment: Alignment.center,
duration: Duration(milliseconds: 500),
curve: Curves.fastOutSlowIn,
decoration: BoxDecoration(
borderRadius:
BorderRadius.only(topLeft: Radius.circular(10)),
color: Colors.green),
child: Text(
S.of(context).copied_to_clipboard,
style: TextStyle(fontSize: 10, color: Colors.white),
),
)
],
),
);
});
}
}