mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-20 06:08:34 +02:00
CAKE-20 | updated exchange and exchange template pages; created exchange_view_model and applied to exchange and exchange template pages; applied new design to menu widget; changed text validator and amount validator
This commit is contained in:
@@ -19,10 +19,14 @@ abstract class BasePage extends StatelessWidget {
|
||||
|
||||
bool get resizeToAvoidBottomPadding => true;
|
||||
|
||||
Widget get endDrawer => null;
|
||||
|
||||
AppBarStyle get appBarStyle => AppBarStyle.regular;
|
||||
|
||||
Widget Function(BuildContext, Widget) get rootWrapper => null;
|
||||
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
final _backArrowImage = Image.asset('assets/images/back_arrow.png',
|
||||
color: Colors.white);
|
||||
final _backArrowImageDarkTheme =
|
||||
@@ -32,6 +36,8 @@ abstract class BasePage extends StatelessWidget {
|
||||
final _closeButtonImageDarkTheme =
|
||||
Image.asset('assets/images/close_button_dark_theme.png');
|
||||
|
||||
void onOpenEndDrawer() => _scaffoldKey.currentState.openEndDrawer();
|
||||
|
||||
void onClose(BuildContext context) => Navigator.of(context).pop();
|
||||
|
||||
Widget leading(BuildContext context) {
|
||||
@@ -123,9 +129,11 @@ abstract class BasePage extends StatelessWidget {
|
||||
final _isDarkTheme = _themeChanger.getTheme() == Themes.darkTheme;
|
||||
|
||||
final root = Scaffold(
|
||||
key: _scaffoldKey,
|
||||
backgroundColor:
|
||||
_isDarkTheme ? backgroundDarkColor : backgroundLightColor,
|
||||
resizeToAvoidBottomPadding: resizeToAvoidBottomPadding,
|
||||
endDrawer: endDrawer,
|
||||
appBar: appBar(context),
|
||||
body: body(context), //SafeArea(child: ),
|
||||
floatingActionButton: floatingActionButton(context));
|
||||
|
||||
@@ -23,6 +23,12 @@ class DashboardPage extends BasePage {
|
||||
@override
|
||||
Color get backgroundDarkColor => PaletteDark.backgroundColor;
|
||||
|
||||
@override
|
||||
Widget get endDrawer => MenuWidget(
|
||||
name: walletViewModel.name,
|
||||
subname: walletViewModel.subname,
|
||||
type: walletViewModel.type);
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) {
|
||||
return SyncIndicator(dashboardViewModel: walletViewModel);
|
||||
@@ -40,14 +46,7 @@ class DashboardPage extends BasePage {
|
||||
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);
|
||||
},
|
||||
onPressed: () => onOpenEndDrawer(),
|
||||
child: menuButton
|
||||
)
|
||||
);
|
||||
|
||||
@@ -20,13 +20,13 @@ class WalletMenu {
|
||||
];
|
||||
|
||||
final List<Image> images = [
|
||||
Image.asset('assets/images/reconnect.png'),
|
||||
Image.asset('assets/images/wallet.png'),
|
||||
Image.asset('assets/images/nodes.png'),
|
||||
Image.asset('assets/images/eye.png'),
|
||||
Image.asset('assets/images/key.png'),
|
||||
Image.asset('assets/images/open_book.png'),
|
||||
Image.asset('assets/images/settings.png'),
|
||||
Image.asset('assets/images/reconnect_menu.png', height: 16, width: 16),
|
||||
Image.asset('assets/images/wallet_menu.png', height: 16, width: 16),
|
||||
Image.asset('assets/images/nodes_menu.png', height: 16, width: 16),
|
||||
Image.asset('assets/images/eye_menu.png', height: 16, width: 16),
|
||||
Image.asset('assets/images/key_menu.png', height: 16, width: 16),
|
||||
Image.asset('assets/images/open_book_menu.png', height: 16, width: 16),
|
||||
Image.asset('assets/images/settings_menu.png', height: 16, width: 16),
|
||||
];
|
||||
|
||||
final BuildContext context;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart';
|
||||
@@ -15,7 +16,7 @@ class MenuWidget extends StatefulWidget {
|
||||
}
|
||||
|
||||
class MenuWidgetState extends State<MenuWidget> {
|
||||
final moneroIcon = Image.asset('assets/images/monero.png');
|
||||
final moneroIcon = Image.asset('assets/images/monero_menu.png');
|
||||
final bitcoinIcon = Image.asset('assets/images/bitcoin.png');
|
||||
final largeScreen = 731;
|
||||
|
||||
@@ -36,10 +37,10 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
screenHeight = 0;
|
||||
opacity = 0;
|
||||
|
||||
headerHeight = 120;
|
||||
headerHeight = 125;
|
||||
tileHeight = 75;
|
||||
fromTopEdge = 50;
|
||||
fromBottomEdge = 30;
|
||||
fromBottomEdge = 21;//30;
|
||||
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback(afterLayout);
|
||||
@@ -66,189 +67,139 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final walletMenu = WalletMenu(context);
|
||||
// final walletStore = Provider.of<WalletStore>(context);
|
||||
final itemCount = walletMenu.items.length;
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
return SafeArea(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: Container(
|
||||
height: 60,
|
||||
width: 4,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(2)),
|
||||
color: Theme.of(context).hintColor),
|
||||
borderRadius: BorderRadius.all(Radius.circular(2)),
|
||||
color: Theme.of(context).hintColor),
|
||||
)),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () => null,
|
||||
child: Container(
|
||||
width: menuWidth,
|
||||
height: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(24),
|
||||
bottomLeft: Radius.circular(24)),
|
||||
color: Theme.of(context).primaryTextTheme.display1.color),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(24),
|
||||
bottomLeft: Radius.circular(24)),
|
||||
child: ListView.separated(
|
||||
itemBuilder: (_, index) {
|
||||
if (index == 0) {
|
||||
return Container(
|
||||
height: headerHeight,
|
||||
padding: EdgeInsets.only(
|
||||
left: 24,
|
||||
top: fromTopEdge,
|
||||
right: 24,
|
||||
bottom: fromBottomEdge),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.only(topLeft: Radius.circular(24)),
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display2
|
||||
.color),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
_iconFor(type: widget.type),
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 40,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: widget.subname != null
|
||||
? MainAxisAlignment.spaceBetween
|
||||
: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
widget.name,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color,
|
||||
decoration: TextDecoration.none,
|
||||
fontFamily: 'Avenir Next',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
if (widget.subname != null)
|
||||
Text(
|
||||
widget.subname,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.caption
|
||||
.color,
|
||||
decoration: TextDecoration.none,
|
||||
fontFamily: 'Avenir Next',
|
||||
fontSize: 12),
|
||||
)
|
||||
],
|
||||
),
|
||||
))
|
||||
],
|
||||
child: Container(
|
||||
width: menuWidth,
|
||||
height: double.infinity,
|
||||
color: PaletteDark.deepPurpleBlue,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: headerHeight,
|
||||
padding: EdgeInsets.only(
|
||||
left: 24,
|
||||
top: fromTopEdge,
|
||||
right: 24,
|
||||
bottom: fromBottomEdge),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
_iconFor(type: widget.type),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 42,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: widget.subname != null
|
||||
? MainAxisAlignment.spaceBetween
|
||||
: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
widget.name,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
if (widget.subname != null)
|
||||
Text(
|
||||
widget.subname,
|
||||
style: TextStyle(
|
||||
color: PaletteDark.darkCyanBlue,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12),
|
||||
)
|
||||
],
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
Container(
|
||||
height: 1,
|
||||
color: PaletteDark.lightOceanBlue,
|
||||
),
|
||||
ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (_, index) {
|
||||
|
||||
index -= 1;
|
||||
final item = walletMenu.items[index];
|
||||
final image = walletMenu.images[index] ?? Offstage();
|
||||
final item = walletMenu.items[index];
|
||||
final image = walletMenu.images[index] ?? Offstage();
|
||||
final isLastTile = index == itemCount - 1;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
walletMenu.action(index);
|
||||
},
|
||||
child: index == itemCount - 1
|
||||
? Container(
|
||||
height: headerHeight,
|
||||
padding: EdgeInsets.only(
|
||||
left: 24,
|
||||
right: 24,
|
||||
top: fromBottomEdge,
|
||||
bottom: fromTopEdge),
|
||||
alignment: Alignment.topLeft,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24)),
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display1
|
||||
.color,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image,
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item,
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.none,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color,
|
||||
fontFamily: 'Avenir Next',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold),
|
||||
))
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
height: tileHeight,
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display1
|
||||
.color,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image,
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item,
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.none,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color,
|
||||
fontFamily: 'Avenir Next',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold),
|
||||
))
|
||||
],
|
||||
),
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
walletMenu.action(index);
|
||||
},
|
||||
child: Container(
|
||||
height: isLastTile
|
||||
? headerHeight
|
||||
: tileHeight,
|
||||
padding: isLastTile
|
||||
? EdgeInsets.only(
|
||||
left: 24,
|
||||
right: 24,
|
||||
top: fromBottomEdge,
|
||||
bottom: fromTopEdge)
|
||||
: EdgeInsets.only(left: 24, right: 24),
|
||||
alignment: isLastTile ? Alignment.topLeft : null,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image,
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold),
|
||||
))
|
||||
],
|
||||
),
|
||||
)
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, index) => Container(
|
||||
height: 1,
|
||||
color: PaletteDark.lightOceanBlue,
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, index) => Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
itemCount: itemCount + 1),
|
||||
),
|
||||
),
|
||||
))
|
||||
],
|
||||
itemCount: itemCount)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,66 +1,40 @@
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange/exchange_store.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/base_exchange_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/trail_button.dart';
|
||||
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||
|
||||
class ExchangePage extends BasePage {
|
||||
ExchangePage(this.exchangeViewModel);
|
||||
|
||||
final ExchangeViewModel exchangeViewModel;
|
||||
|
||||
@override
|
||||
String get title => S.current.exchange;
|
||||
|
||||
@override
|
||||
Color get backgroundLightColor => Palette.darkLavender;
|
||||
Color get backgroundLightColor => PaletteDark.wildVioletBlue;
|
||||
|
||||
@override
|
||||
Color get backgroundDarkColor => PaletteDark.moderateBlue;
|
||||
Color get backgroundDarkColor => PaletteDark.wildVioletBlue;
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) {
|
||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
||||
|
||||
return PresentProviderPicker(exchangeStore: exchangeStore);
|
||||
}
|
||||
Widget middle(BuildContext context) =>
|
||||
PresentProviderPicker(exchangeViewModel: exchangeViewModel);
|
||||
|
||||
@override
|
||||
Widget trailing(BuildContext context) {
|
||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
||||
|
||||
return TrailButton(
|
||||
caption: S.of(context).reset,
|
||||
onPressed: () => exchangeStore.reset()
|
||||
);
|
||||
}
|
||||
Widget trailing(BuildContext context) =>
|
||||
TrailButton(
|
||||
caption: S.of(context).reset,
|
||||
onPressed: () => exchangeViewModel.reset()
|
||||
);
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) => ExchangeForm();
|
||||
}
|
||||
|
||||
class ExchangeForm extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() => ExchangeFormState();
|
||||
}
|
||||
|
||||
class ExchangeFormState extends State<ExchangeForm> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
||||
final walletStore = Provider.of<WalletStore>(context);
|
||||
final exchangeTemplateStore = Provider.of<ExchangeTemplateStore>(context);
|
||||
|
||||
return BaseExchangeWidget(
|
||||
exchangeStore: exchangeStore,
|
||||
walletStore: walletStore,
|
||||
exchangeTemplateStore: exchangeTemplateStore,
|
||||
isTemplate: false
|
||||
);
|
||||
}
|
||||
Widget body(BuildContext context) =>
|
||||
BaseExchangeWidget(exchangeViewModel: exchangeViewModel);
|
||||
}
|
||||
|
||||
@@ -1,55 +1,32 @@
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange/exchange_store.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/base_exchange_widget.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||
|
||||
class ExchangeTemplatePage extends BasePage {
|
||||
ExchangeTemplatePage(this.exchangeViewModel);
|
||||
|
||||
final ExchangeViewModel exchangeViewModel;
|
||||
|
||||
@override
|
||||
String get title => S.current.exchange_new_template;
|
||||
|
||||
@override
|
||||
Color get backgroundLightColor => Palette.darkLavender;
|
||||
Color get backgroundLightColor => PaletteDark.wildVioletBlue;
|
||||
|
||||
@override
|
||||
Color get backgroundDarkColor => PaletteDark.moderateBlue;
|
||||
Color get backgroundDarkColor => PaletteDark.wildVioletBlue;
|
||||
|
||||
@override
|
||||
Widget trailing(BuildContext context) {
|
||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
||||
|
||||
return PresentProviderPicker(exchangeStore: exchangeStore);
|
||||
}
|
||||
Widget trailing(BuildContext context) =>
|
||||
PresentProviderPicker(exchangeViewModel: exchangeViewModel);
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) => ExchangeTemplateForm();
|
||||
}
|
||||
|
||||
class ExchangeTemplateForm extends StatefulWidget{
|
||||
@override
|
||||
ExchangeTemplateFormState createState() => ExchangeTemplateFormState();
|
||||
}
|
||||
|
||||
class ExchangeTemplateFormState extends State<ExchangeTemplateForm> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
||||
final walletStore = Provider.of<WalletStore>(context);
|
||||
final exchangeTemplateStore = Provider.of<ExchangeTemplateStore>(context);
|
||||
|
||||
return BaseExchangeWidget(
|
||||
exchangeStore: exchangeStore,
|
||||
walletStore: walletStore,
|
||||
exchangeTemplateStore: exchangeTemplateStore,
|
||||
isTemplate: true
|
||||
);
|
||||
}
|
||||
Widget body(BuildContext context) =>
|
||||
BaseExchangeWidget(exchangeViewModel: exchangeViewModel, isTemplate: true);
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/src/domain/exchange/exchange_template.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@@ -12,49 +14,37 @@ import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
|
||||
import 'package:cake_wallet/src/domain/exchange/xmrto/xmrto_exchange_provider.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange/exchange_trade_state.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange/limits_state.dart';
|
||||
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange/exchange_store.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/exchange_card.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/src/widgets/top_panel.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||
|
||||
class BaseExchangeWidget extends StatefulWidget {
|
||||
BaseExchangeWidget({
|
||||
@ required this.exchangeStore,
|
||||
@ required this.walletStore,
|
||||
@ required this.exchangeTemplateStore,
|
||||
@ required this.isTemplate,
|
||||
@ required this.exchangeViewModel,
|
||||
this.isTemplate = false,
|
||||
});
|
||||
|
||||
final ExchangeStore exchangeStore;
|
||||
final WalletStore walletStore;
|
||||
final ExchangeTemplateStore exchangeTemplateStore;
|
||||
final ExchangeViewModel exchangeViewModel;
|
||||
final bool isTemplate;
|
||||
|
||||
@override
|
||||
BaseExchangeWidgetState createState() =>
|
||||
BaseExchangeWidgetState(
|
||||
exchangeStore: exchangeStore,
|
||||
walletStore: walletStore,
|
||||
exchangeTemplateStore: exchangeTemplateStore,
|
||||
exchangeViewModel: exchangeViewModel,
|
||||
isTemplate: isTemplate
|
||||
);
|
||||
}
|
||||
|
||||
class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
BaseExchangeWidgetState({
|
||||
@ required this.exchangeStore,
|
||||
@ required this.walletStore,
|
||||
@ required this.exchangeTemplateStore,
|
||||
@ required this.exchangeViewModel,
|
||||
@ required this.isTemplate,
|
||||
});
|
||||
|
||||
final ExchangeStore exchangeStore;
|
||||
final WalletStore walletStore;
|
||||
final ExchangeTemplateStore exchangeTemplateStore;
|
||||
final ExchangeViewModel exchangeViewModel;
|
||||
final bool isTemplate;
|
||||
|
||||
final depositKey = GlobalKey<ExchangeCardState>();
|
||||
@@ -64,31 +54,31 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Image arrowBottomPurple = Image.asset(
|
||||
final arrowBottomPurple = Image.asset(
|
||||
'assets/images/arrow_bottom_purple_icon.png',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
color: Colors.white,
|
||||
height: 8,
|
||||
);
|
||||
final Image arrowBottomCakeGreen = Image.asset(
|
||||
final arrowBottomCakeGreen = Image.asset(
|
||||
'assets/images/arrow_bottom_cake_green.png',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
color: Colors.white,
|
||||
height: 8,
|
||||
);
|
||||
|
||||
final depositWalletName =
|
||||
exchangeStore.depositCurrency == CryptoCurrency.xmr
|
||||
? walletStore.name
|
||||
exchangeViewModel.depositCurrency == CryptoCurrency.xmr
|
||||
? exchangeViewModel.wallet.name
|
||||
: null;
|
||||
final receiveWalletName =
|
||||
exchangeStore.receiveCurrency == CryptoCurrency.xmr
|
||||
? walletStore.name
|
||||
exchangeViewModel.receiveCurrency == CryptoCurrency.xmr
|
||||
? exchangeViewModel.wallet.name
|
||||
: null;
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(_) => _setReactions(context, exchangeStore, walletStore));
|
||||
(_) => _setReactions(context, exchangeViewModel));
|
||||
|
||||
return Container(
|
||||
color: Theme.of(context).backgroundColor,
|
||||
color: PaletteDark.backgroundColor,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: ScrollableWithBottomSection(
|
||||
@@ -96,73 +86,60 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
content: Column(
|
||||
children: <Widget>[
|
||||
TopPanel(
|
||||
color: Theme.of(context).accentTextTheme.title.backgroundColor,
|
||||
edgeInsets: EdgeInsets.only(bottom: 24),
|
||||
color: PaletteDark.darkNightBlue,
|
||||
edgeInsets: EdgeInsets.only(bottom: 32),
|
||||
widget: Column(
|
||||
children: <Widget>[
|
||||
TopPanel(
|
||||
color: Theme.of(context).accentTextTheme.title.color,
|
||||
edgeInsets: EdgeInsets.fromLTRB(24, 29, 24, 32),
|
||||
color: PaletteDark.wildVioletBlue,
|
||||
widget: Observer(
|
||||
builder: (_) => ExchangeCard(
|
||||
key: depositKey,
|
||||
title: S.of(context).you_will_send,
|
||||
initialCurrency: exchangeStore.depositCurrency,
|
||||
initialCurrency: exchangeViewModel.depositCurrency,
|
||||
initialWalletName: depositWalletName,
|
||||
initialAddress:
|
||||
exchangeStore.depositCurrency == walletStore.type
|
||||
? walletStore.address
|
||||
: exchangeStore.depositAddress,
|
||||
exchangeViewModel.depositCurrency == exchangeViewModel.wallet.currency
|
||||
? exchangeViewModel.wallet.address
|
||||
: exchangeViewModel.depositAddress,
|
||||
initialIsAmountEditable: true,
|
||||
initialIsAddressEditable: exchangeStore.isDepositAddressEnabled,
|
||||
initialIsAddressEditable: exchangeViewModel.isDepositAddressEnabled,
|
||||
isAmountEstimated: false,
|
||||
currencies: CryptoCurrency.all,
|
||||
onCurrencySelected: (currency) =>
|
||||
exchangeStore.changeDepositCurrency(currency: currency),
|
||||
exchangeViewModel.changeDepositCurrency(currency: currency),
|
||||
imageArrow: arrowBottomPurple,
|
||||
currencyButtonColor: Theme.of(context).accentTextTheme.title.color,
|
||||
addressButtonsColor: Theme.of(context).accentTextTheme.title.backgroundColor,
|
||||
currencyValueValidator: (value) {
|
||||
exchangeStore.validateCryptoCurrency(value);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
addressTextFieldValidator: (value) {
|
||||
exchangeStore.validateAddress(value,
|
||||
cryptoCurrency: exchangeStore.depositCurrency);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
currencyButtonColor: PaletteDark.wildVioletBlue,
|
||||
addressButtonsColor: PaletteDark.moderateBlue,
|
||||
currencyValueValidator: exchangeViewModel.amountValidator,
|
||||
addressTextFieldValidator: exchangeViewModel.addressValidator,
|
||||
),
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 32, left: 24, right: 24),
|
||||
padding: EdgeInsets.only(top: 29, left: 24, right: 24),
|
||||
child: Observer(
|
||||
builder: (_) => ExchangeCard(
|
||||
key: receiveKey,
|
||||
title: S.of(context).you_will_get,
|
||||
initialCurrency: exchangeStore.receiveCurrency,
|
||||
initialCurrency: exchangeViewModel.receiveCurrency,
|
||||
initialWalletName: receiveWalletName,
|
||||
initialAddress:
|
||||
exchangeStore.receiveCurrency == walletStore.type
|
||||
? walletStore.address
|
||||
: exchangeStore.receiveAddress,
|
||||
exchangeViewModel.receiveCurrency == exchangeViewModel.wallet.currency
|
||||
? exchangeViewModel.wallet.address
|
||||
: exchangeViewModel.receiveAddress,
|
||||
initialIsAmountEditable: false,
|
||||
initialIsAddressEditable: exchangeStore.isReceiveAddressEnabled,
|
||||
initialIsAddressEditable: exchangeViewModel.isReceiveAddressEnabled,
|
||||
isAmountEstimated: true,
|
||||
currencies: CryptoCurrency.all,
|
||||
onCurrencySelected: (currency) => exchangeStore
|
||||
onCurrencySelected: (currency) => exchangeViewModel
|
||||
.changeReceiveCurrency(currency: currency),
|
||||
imageArrow: arrowBottomCakeGreen,
|
||||
currencyButtonColor: Theme.of(context).accentTextTheme.title.backgroundColor,
|
||||
addressButtonsColor: Theme.of(context).accentTextTheme.title.color,
|
||||
currencyValueValidator: (value) {
|
||||
exchangeStore.validateCryptoCurrency(value);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
addressTextFieldValidator: (value) {
|
||||
exchangeStore.validateAddress(value,
|
||||
cryptoCurrency: exchangeStore.receiveCurrency);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
currencyButtonColor: PaletteDark.darkNightBlue,
|
||||
addressButtonsColor: PaletteDark.moderateBlue,
|
||||
currencyValueValidator: exchangeViewModel.amountValidator,
|
||||
addressTextFieldValidator: exchangeViewModel.addressValidator,
|
||||
)),
|
||||
)
|
||||
],
|
||||
@@ -172,7 +149,7 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
? Offstage()
|
||||
: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: 32,
|
||||
top: 30,
|
||||
left: 24,
|
||||
bottom: 24
|
||||
),
|
||||
@@ -184,7 +161,7 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).primaryTextTheme.caption.color
|
||||
color: PaletteDark.darkCyanBlue
|
||||
),
|
||||
)
|
||||
],
|
||||
@@ -196,66 +173,90 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: Observer(
|
||||
builder: (_) {
|
||||
final itemCount = exchangeTemplateStore.templates.length + 1;
|
||||
|
||||
return ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: itemCount,
|
||||
itemBuilder: (context, index) {
|
||||
|
||||
if (index == 0) {
|
||||
return GestureDetector(
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.exchangeTemplate),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(right: 10),
|
||||
child: DottedBorder(
|
||||
borderType: BorderType.RRect,
|
||||
dashPattern: [8, 4],
|
||||
color: Theme.of(context).accentTextTheme.title.backgroundColor,
|
||||
strokeWidth: 2,
|
||||
radius: Radius.circular(20),
|
||||
child: Container(
|
||||
height: 40,
|
||||
width: 75,
|
||||
padding: EdgeInsets.only(left: 10, right: 10),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
color: Colors.transparent,
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).send_new,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).primaryTextTheme.caption.color
|
||||
),
|
||||
),
|
||||
)
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.exchangeTemplate),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 1, right: 10),
|
||||
child: DottedBorder(
|
||||
borderType: BorderType.RRect,
|
||||
dashPattern: [6, 4],
|
||||
color: PaletteDark.darkCyanBlue,
|
||||
strokeWidth: 2,
|
||||
radius: Radius.circular(20),
|
||||
child: Container(
|
||||
height: 34,
|
||||
width: 75,
|
||||
padding: EdgeInsets.only(left: 10, right: 10),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
color: Colors.transparent,
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).send_new,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: PaletteDark.darkCyanBlue
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
Observer(
|
||||
builder: (_) {
|
||||
final templates = exchangeViewModel.templates;
|
||||
final itemCount = exchangeViewModel.templates.length;
|
||||
|
||||
index -= 1;
|
||||
return ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: itemCount,
|
||||
itemBuilder: (context, index) {
|
||||
final template = templates[index];
|
||||
|
||||
final template = exchangeTemplateStore.templates[index];
|
||||
|
||||
return TemplateTile(
|
||||
amount: template.amount,
|
||||
from: template.depositCurrency,
|
||||
to: template.receiveCurrency,
|
||||
onTap: () {
|
||||
applyTemplate(exchangeStore, template);
|
||||
return TemplateTile(
|
||||
key: UniqueKey(),
|
||||
amount: template.amount,
|
||||
from: template.depositCurrency,
|
||||
to: template.receiveCurrency,
|
||||
onTap: () {
|
||||
applyTemplate(exchangeViewModel, template);
|
||||
},
|
||||
onRemove: () {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (dialogContext) {
|
||||
return AlertWithTwoActions(
|
||||
alertTitle: S.of(context).template,
|
||||
alertContent: S.of(context).confirm_delete_template,
|
||||
leftButtonText: S.of(context).delete,
|
||||
rightButtonText: S.of(context).cancel,
|
||||
actionLeftButton: () {
|
||||
Navigator.of(dialogContext).pop();
|
||||
exchangeViewModel.exchangeTemplateStore.remove(template: template);
|
||||
exchangeViewModel.exchangeTemplateStore.update();
|
||||
},
|
||||
actionRightButton: () => Navigator.of(dialogContext).pop()
|
||||
);
|
||||
}
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
@@ -265,14 +266,15 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
padding: EdgeInsets.only(bottom: 15),
|
||||
child: Observer(builder: (_) {
|
||||
final description =
|
||||
exchangeStore.provider is XMRTOExchangeProvider
|
||||
exchangeViewModel.provider is XMRTOExchangeProvider
|
||||
? S.of(context).amount_is_guaranteed
|
||||
: S.of(context).amount_is_estimate;
|
||||
return Center(
|
||||
child: Text(
|
||||
description,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.caption.color,
|
||||
color: PaletteDark.darkCyanBlue,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12
|
||||
),
|
||||
),
|
||||
@@ -283,15 +285,15 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
? PrimaryButton(
|
||||
onPressed: () {
|
||||
if (_formKey.currentState.validate()) {
|
||||
exchangeTemplateStore.addTemplate(
|
||||
amount: exchangeStore.depositAmount,
|
||||
depositCurrency: exchangeStore.depositCurrency.toString(),
|
||||
receiveCurrency: exchangeStore.receiveCurrency.toString(),
|
||||
provider: exchangeStore.provider.toString(),
|
||||
depositAddress: exchangeStore.depositAddress,
|
||||
receiveAddress: exchangeStore.receiveAddress
|
||||
exchangeViewModel.exchangeTemplateStore.addTemplate(
|
||||
amount: exchangeViewModel.depositAmount,
|
||||
depositCurrency: exchangeViewModel.depositCurrency.toString(),
|
||||
receiveCurrency: exchangeViewModel.receiveCurrency.toString(),
|
||||
provider: exchangeViewModel.provider.toString(),
|
||||
depositAddress: exchangeViewModel.depositAddress,
|
||||
receiveAddress: exchangeViewModel.receiveAddress
|
||||
);
|
||||
exchangeTemplateStore.update();
|
||||
exchangeViewModel.exchangeTemplateStore.update();
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
@@ -304,41 +306,47 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
text: S.of(context).exchange,
|
||||
onPressed: () {
|
||||
if (_formKey.currentState.validate()) {
|
||||
exchangeStore.createTrade();
|
||||
exchangeViewModel.createTrade();
|
||||
}
|
||||
},
|
||||
color: Colors.blue,
|
||||
textColor: Colors.white,
|
||||
isLoading: exchangeStore.tradeState is TradeIsCreating,
|
||||
isLoading: exchangeViewModel.tradeState is TradeIsCreating,
|
||||
)),
|
||||
]),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
void applyTemplate(ExchangeStore store, ExchangeTemplate template) {
|
||||
store.changeDepositCurrency(currency: CryptoCurrency.fromString(template.depositCurrency));
|
||||
store.changeReceiveCurrency(currency: CryptoCurrency.fromString(template.receiveCurrency));
|
||||
void applyTemplate(ExchangeViewModel exchangeViewModel,
|
||||
ExchangeTemplate template) {
|
||||
exchangeViewModel.changeDepositCurrency(
|
||||
currency: CryptoCurrency.fromString(template.depositCurrency));
|
||||
exchangeViewModel.changeReceiveCurrency(
|
||||
currency: CryptoCurrency.fromString(template.receiveCurrency));
|
||||
|
||||
switch (template.provider) {
|
||||
case 'XMR.TO':
|
||||
store.changeProvider(provider: store.providerList[0]);
|
||||
exchangeViewModel.changeProvider(
|
||||
provider: exchangeViewModel.providerList[0]);
|
||||
break;
|
||||
case 'ChangeNOW':
|
||||
store.changeProvider(provider: store.providerList[1]);
|
||||
exchangeViewModel.changeProvider(
|
||||
provider: exchangeViewModel.providerList[1]);
|
||||
break;
|
||||
case 'MorphToken':
|
||||
store.changeProvider(provider: store.providerList[2]);
|
||||
exchangeViewModel.changeProvider(
|
||||
provider: exchangeViewModel.providerList[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
store.changeDepositAmount(amount: template.amount);
|
||||
store.depositAddress = template.depositAddress;
|
||||
store.receiveAddress = template.receiveAddress;
|
||||
exchangeViewModel.changeDepositAmount(amount: template.amount);
|
||||
exchangeViewModel.depositAddress = template.depositAddress;
|
||||
exchangeViewModel.receiveAddress = template.receiveAddress;
|
||||
}
|
||||
|
||||
void _setReactions(
|
||||
BuildContext context, ExchangeStore store, WalletStore walletStore) {
|
||||
BuildContext context, ExchangeViewModel exchangeViewModel) {
|
||||
if (_isReactionsSet) {
|
||||
return;
|
||||
}
|
||||
@@ -347,7 +355,7 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
final depositAmountController = depositKey.currentState.amountController;
|
||||
final receiveAddressController = receiveKey.currentState.addressController;
|
||||
final receiveAmountController = receiveKey.currentState.amountController;
|
||||
final limitsState = store.limitsState;
|
||||
final limitsState = exchangeViewModel.limitsState;
|
||||
|
||||
if (limitsState is LimitsLoadedSuccessfully) {
|
||||
final min = limitsState.limits.min != null
|
||||
@@ -360,63 +368,62 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
key.currentState.changeLimits(min: min, max: max);
|
||||
}
|
||||
|
||||
_onCurrencyChange(store.receiveCurrency, walletStore, receiveKey);
|
||||
_onCurrencyChange(store.depositCurrency, walletStore, depositKey);
|
||||
_onCurrencyChange(exchangeViewModel.receiveCurrency, exchangeViewModel, receiveKey);
|
||||
_onCurrencyChange(exchangeViewModel.depositCurrency, exchangeViewModel, depositKey);
|
||||
|
||||
reaction(
|
||||
(_) => walletStore.name,
|
||||
(_) => exchangeViewModel.wallet.name,
|
||||
(String _) => _onWalletNameChange(
|
||||
walletStore, store.receiveCurrency, receiveKey));
|
||||
exchangeViewModel, exchangeViewModel.receiveCurrency, receiveKey));
|
||||
|
||||
reaction(
|
||||
(_) => walletStore.name,
|
||||
(_) => exchangeViewModel.wallet.name,
|
||||
(String _) => _onWalletNameChange(
|
||||
walletStore, store.depositCurrency, depositKey));
|
||||
exchangeViewModel, exchangeViewModel.depositCurrency, depositKey));
|
||||
|
||||
reaction(
|
||||
(_) => store.receiveCurrency,
|
||||
(_) => exchangeViewModel.receiveCurrency,
|
||||
(CryptoCurrency currency) =>
|
||||
_onCurrencyChange(currency, walletStore, receiveKey));
|
||||
_onCurrencyChange(currency, exchangeViewModel, receiveKey));
|
||||
|
||||
reaction(
|
||||
(_) => store.depositCurrency,
|
||||
(_) => exchangeViewModel.depositCurrency,
|
||||
(CryptoCurrency currency) =>
|
||||
_onCurrencyChange(currency, walletStore, depositKey));
|
||||
_onCurrencyChange(currency, exchangeViewModel, depositKey));
|
||||
|
||||
reaction((_) => store.depositAmount, (String amount) {
|
||||
reaction((_) => exchangeViewModel.depositAmount, (String amount) {
|
||||
if (depositKey.currentState.amountController.text != amount) {
|
||||
depositKey.currentState.amountController.text = amount;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.depositAddress, (String address) {
|
||||
reaction((_) => exchangeViewModel.depositAddress, (String address) {
|
||||
if (depositKey.currentState.addressController.text != address) {
|
||||
depositKey.currentState.addressController.text = address;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.isDepositAddressEnabled, (bool isEnabled) {
|
||||
reaction((_) => exchangeViewModel.isDepositAddressEnabled, (bool isEnabled) {
|
||||
depositKey.currentState.isAddressEditable(isEditable: isEnabled);
|
||||
});
|
||||
|
||||
reaction((_) => store.receiveAmount, (String amount) {
|
||||
if (receiveKey.currentState.amountController.text !=
|
||||
store.receiveAmount) {
|
||||
reaction((_) => exchangeViewModel.receiveAmount, (String amount) {
|
||||
if (receiveKey.currentState.amountController.text != amount) {
|
||||
receiveKey.currentState.amountController.text = amount;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.receiveAddress, (String address) {
|
||||
reaction((_) => exchangeViewModel.receiveAddress, (String address) {
|
||||
if (receiveKey.currentState.addressController.text != address) {
|
||||
receiveKey.currentState.addressController.text = address;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.isReceiveAddressEnabled, (bool isEnabled) {
|
||||
reaction((_) => exchangeViewModel.isReceiveAddressEnabled, (bool isEnabled) {
|
||||
receiveKey.currentState.isAddressEditable(isEditable: isEnabled);
|
||||
});
|
||||
|
||||
reaction((_) => store.tradeState, (ExchangeTradeState state) {
|
||||
reaction((_) => exchangeViewModel.tradeState, (ExchangeTradeState state) {
|
||||
if (state is TradeIsCreatedFailure) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
showDialog<void>(
|
||||
@@ -437,7 +444,7 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.limitsState, (LimitsState state) {
|
||||
reaction((_) => exchangeViewModel.limitsState, (LimitsState state) {
|
||||
String min;
|
||||
String max;
|
||||
|
||||
@@ -461,29 +468,29 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
});
|
||||
|
||||
depositAddressController.addListener(
|
||||
() => store.depositAddress = depositAddressController.text);
|
||||
() => exchangeViewModel.depositAddress = depositAddressController.text);
|
||||
|
||||
depositAmountController.addListener(() {
|
||||
if (depositAmountController.text != store.depositAmount) {
|
||||
store.changeDepositAmount(amount: depositAmountController.text);
|
||||
if (depositAmountController.text != exchangeViewModel.depositAmount) {
|
||||
exchangeViewModel.changeDepositAmount(amount: depositAmountController.text);
|
||||
}
|
||||
});
|
||||
|
||||
receiveAddressController.addListener(
|
||||
() => store.receiveAddress = receiveAddressController.text);
|
||||
() => exchangeViewModel.receiveAddress = receiveAddressController.text);
|
||||
|
||||
receiveAmountController.addListener(() {
|
||||
if (receiveAmountController.text != store.receiveAmount) {
|
||||
store.changeReceiveAmount(amount: receiveAmountController.text);
|
||||
if (receiveAmountController.text != exchangeViewModel.receiveAmount) {
|
||||
exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text);
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => walletStore.address, (String address) {
|
||||
if (store.depositCurrency == CryptoCurrency.xmr) {
|
||||
reaction((_) => exchangeViewModel.wallet.address, (String address) {
|
||||
if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
|
||||
depositKey.currentState.changeAddress(address: address);
|
||||
}
|
||||
|
||||
if (store.receiveCurrency == CryptoCurrency.xmr) {
|
||||
if (exchangeViewModel.receiveCurrency == CryptoCurrency.xmr) {
|
||||
receiveKey.currentState.changeAddress(address: address);
|
||||
}
|
||||
});
|
||||
@@ -491,28 +498,33 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||
_isReactionsSet = true;
|
||||
}
|
||||
|
||||
void _onCurrencyChange(CryptoCurrency currency, WalletStore walletStore,
|
||||
void _onCurrencyChange(CryptoCurrency currency,
|
||||
ExchangeViewModel exchangeViewModel,
|
||||
GlobalKey<ExchangeCardState> key) {
|
||||
final isCurrentTypeWallet = currency == walletStore.type;
|
||||
final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
|
||||
|
||||
key.currentState.changeSelectedCurrency(currency);
|
||||
key.currentState
|
||||
.changeWalletName(isCurrentTypeWallet ? walletStore.name : null);
|
||||
.changeWalletName(isCurrentTypeWallet
|
||||
? exchangeViewModel.wallet.name : null);
|
||||
|
||||
key.currentState
|
||||
.changeAddress(address: isCurrentTypeWallet ? walletStore.address : '');
|
||||
.changeAddress(address: isCurrentTypeWallet
|
||||
? exchangeViewModel.wallet.address : '');
|
||||
|
||||
key.currentState.changeAmount(amount: '');
|
||||
}
|
||||
|
||||
void _onWalletNameChange(WalletStore walletStore, CryptoCurrency currency,
|
||||
void _onWalletNameChange(ExchangeViewModel exchangeViewModel,
|
||||
CryptoCurrency currency,
|
||||
GlobalKey<ExchangeCardState> key) {
|
||||
final isCurrentTypeWallet = currency == walletStore.type;
|
||||
final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
|
||||
|
||||
if (isCurrentTypeWallet) {
|
||||
key.currentState.changeWalletName(walletStore.name);
|
||||
key.currentState.addressController.text = walletStore.address;
|
||||
} else if (key.currentState.addressController.text == walletStore.address) {
|
||||
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
|
||||
key.currentState.addressController.text = exchangeViewModel.wallet.address;
|
||||
} else if (key.currentState.addressController.text ==
|
||||
exchangeViewModel.wallet.address) {
|
||||
key.currentState.changeWalletName(null);
|
||||
key.currentState.addressController.text = null;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
|
||||
import 'package:cake_wallet/src/widgets/address_text_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
|
||||
class ExchangeCard extends StatefulWidget {
|
||||
ExchangeCard(
|
||||
@@ -57,6 +58,10 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
bool _isAddressEditable;
|
||||
bool _isAmountEstimated;
|
||||
|
||||
final copyImage = Image.asset('assets/images/copy_content.png',
|
||||
height: 16, width: 16,
|
||||
color: Colors.white);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_title = widget.title;
|
||||
@@ -114,6 +119,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
width: double.infinity,
|
||||
color: Colors.transparent,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
@@ -123,13 +129,13 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).primaryTextTheme.caption.color
|
||||
color: PaletteDark.lightBlueGrey
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
BaseTextFormField(
|
||||
@@ -143,7 +149,20 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
RegExp('[\\-|\\ |\\,]'))
|
||||
],
|
||||
hintText: '0.0000',
|
||||
validator: widget.currencyValueValidator
|
||||
borderColor: PaletteDark.blueGrey,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white
|
||||
),
|
||||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: PaletteDark.lightBlueGrey
|
||||
),
|
||||
validator: _isAmountEditable
|
||||
? widget.currencyValueValidator
|
||||
: null
|
||||
),
|
||||
Positioned(
|
||||
top: 8,
|
||||
@@ -163,7 +182,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).primaryTextTheme.title.color)),
|
||||
color: Colors.white)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 5),
|
||||
child: widget.imageArrow,
|
||||
@@ -181,45 +200,96 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
_min != null
|
||||
? Text(
|
||||
? Text(
|
||||
S.of(context).min_value(
|
||||
_min, _selectedCurrency.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: Theme.of(context).primaryTextTheme.caption.color),
|
||||
color: PaletteDark.lightBlueGrey),
|
||||
)
|
||||
: Offstage(),
|
||||
: Offstage(),
|
||||
_min != null ? SizedBox(width: 10) : Offstage(),
|
||||
_max != null
|
||||
? Text(
|
||||
? Text(
|
||||
S.of(context).max_value(
|
||||
_max, _selectedCurrency.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: Theme.of(context).primaryTextTheme.caption.color))
|
||||
: Offstage(),
|
||||
color: PaletteDark.lightBlueGrey))
|
||||
: Offstage(),
|
||||
]),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: AddressTextField(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: Text(
|
||||
_isAddressEditable
|
||||
? S.of(context).widgets_address
|
||||
: S.of(context).refund_address,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: PaletteDark.lightBlueGrey
|
||||
),
|
||||
)
|
||||
),
|
||||
_isAddressEditable
|
||||
? AddressTextField(
|
||||
controller: addressController,
|
||||
isActive: _isAddressEditable,
|
||||
options: _isAddressEditable
|
||||
? _walletName != null
|
||||
? []
|
||||
: [
|
||||
options: [
|
||||
AddressTextFieldOption.paste,
|
||||
AddressTextFieldOption.qrCode,
|
||||
AddressTextFieldOption.addressBook,
|
||||
]
|
||||
: [],
|
||||
],
|
||||
placeholder: '',
|
||||
isBorderExist: false,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white),
|
||||
buttonColor: widget.addressButtonsColor,
|
||||
validator: widget.addressTextFieldValidator,
|
||||
),
|
||||
)
|
||||
: Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Builder(
|
||||
builder: (context) => GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text: addressController.text));
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
S.of(context).copied_to_clipboard,
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
backgroundColor: Colors.green,
|
||||
duration: Duration(milliseconds: 500),
|
||||
));
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Text(
|
||||
addressController.text,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 16),
|
||||
child: copyImage,
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange/exchange_store.dart';
|
||||
import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart';
|
||||
import 'package:cake_wallet/src/domain/exchange/exchange_provider.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
|
||||
class PresentProviderPicker extends StatelessWidget {
|
||||
PresentProviderPicker({@required this.exchangeStore});
|
||||
PresentProviderPicker({@required this.exchangeViewModel});
|
||||
|
||||
final ExchangeStore exchangeStore;
|
||||
final ExchangeViewModel exchangeViewModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Image arrowBottom =
|
||||
final arrowBottom =
|
||||
Image.asset('assets/images/arrow_bottom_purple_icon.png',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
color: Colors.white,
|
||||
height: 6);
|
||||
|
||||
return FlatButton(
|
||||
@@ -33,19 +34,19 @@ class PresentProviderPicker extends StatelessWidget {
|
||||
Text(S.of(context).exchange,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).primaryTextTheme.title.color)),
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white)),
|
||||
Observer(
|
||||
builder: (_) => Text('${exchangeStore.provider.title}',
|
||||
builder: (_) => Text('${exchangeViewModel.provider.title}',
|
||||
style: TextStyle(
|
||||
fontSize: 10.0,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).primaryTextTheme.caption.color)))
|
||||
fontWeight: FontWeight.w500,
|
||||
color: PaletteDark.lightBlueGrey)))
|
||||
],
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 8),
|
||||
padding: EdgeInsets.only(top: 12),
|
||||
child: arrowBottom,
|
||||
)
|
||||
],
|
||||
@@ -54,11 +55,11 @@ class PresentProviderPicker extends StatelessWidget {
|
||||
}
|
||||
|
||||
void _presentProviderPicker(BuildContext context) {
|
||||
final items = exchangeStore.providersForCurrentPair();
|
||||
final selectedItem = items.indexOf(exchangeStore.provider);
|
||||
final images = List<Image>();
|
||||
final items = exchangeViewModel.providersForCurrentPair();
|
||||
final selectedItem = items.indexOf(exchangeViewModel.provider);
|
||||
final images = <Image>[];
|
||||
|
||||
for (ExchangeProvider provider in items) {
|
||||
for (var provider in items) {
|
||||
switch (provider.description) {
|
||||
case ExchangeProviderDescription.xmrto:
|
||||
images.add(Image.asset('assets/images/xmr_btc.png'));
|
||||
@@ -79,7 +80,7 @@ class PresentProviderPicker extends StatelessWidget {
|
||||
selectedAtIndex: selectedItem,
|
||||
title: S.of(context).change_exchange_provider,
|
||||
onItemSelected: (ExchangeProvider provider) =>
|
||||
exchangeStore.changeProvider(provider: provider)),
|
||||
exchangeViewModel.changeProvider(provider: provider)),
|
||||
context: context);
|
||||
}
|
||||
}
|
||||
@@ -125,7 +125,7 @@ class ReceivePage extends BasePage {
|
||||
.headline5
|
||||
.color
|
||||
.withOpacity(0.4),
|
||||
validator: AmountValidator(),
|
||||
validator: AmountValidator(isAutovalidate: true),
|
||||
autovalidate: true,
|
||||
placeholderTextStyle: TextStyle(
|
||||
color: Theme.of(context)
|
||||
|
||||
@@ -72,6 +72,10 @@ class BaseTextFormField extends StatelessWidget {
|
||||
borderSide: BorderSide(
|
||||
color: borderColor ?? Theme.of(context).dividerColor,
|
||||
width: 1.0)),
|
||||
disabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: borderColor ?? Theme.of(context).dividerColor,
|
||||
width: 1.0)),
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: borderColor ?? Theme.of(context).dividerColor,
|
||||
|
||||
@@ -71,6 +71,8 @@ class NavBar extends StatelessWidget implements ObstructingPreferredSizeWidget {
|
||||
EdgeInsetsDirectional.only(bottom: _paddingBottom, top: paddingTop),
|
||||
child: CupertinoNavigationBar(
|
||||
leading: leading,
|
||||
automaticallyImplyLeading: false,
|
||||
automaticallyImplyMiddle: false,
|
||||
middle: middle,
|
||||
trailing: trailing,
|
||||
backgroundColor: backgroundColor,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
|
||||
class TrailButton extends StatelessWidget {
|
||||
TrailButton({
|
||||
@@ -21,7 +22,7 @@ class TrailButton extends StatelessWidget {
|
||||
child: Text(
|
||||
caption,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.caption.color,
|
||||
color: PaletteDark.lightBlueGrey,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user