cake_wallet/lib/src/screens/settings/settings.dart

439 lines
17 KiB
Dart
Raw Normal View History

2020-01-08 12:26:34 +00:00
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
2020-01-04 19:31:52 +00:00
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:provider/provider.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/domain/common/balance_display_mode.dart';
import 'package:cake_wallet/src/domain/common/fiat_currency.dart';
import 'package:cake_wallet/src/domain/common/transaction_priority.dart';
import 'package:cake_wallet/src/stores/settings/settings_store.dart';
import 'package:cake_wallet/src/stores/action_list/action_list_display_mode.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/settings/attributes.dart';
import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart';
import 'package:cake_wallet/src/screens/settings/items/settings_item.dart';
import 'package:cake_wallet/src/screens/settings/items/item_headers.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
2020-01-04 19:31:52 +00:00
// Settings widgets
import 'package:cake_wallet/src/screens/settings/widgets/settings_arrow_list_row.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_header_list_row.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_link_list_row.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_switch_list_row.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_text_list_row.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_raw_widget_list_row.dart';
class SettingsPage extends BasePage {
2020-01-08 12:26:34 +00:00
@override
2020-01-04 19:31:52 +00:00
String get title => S.current.settings_title;
2020-01-08 12:26:34 +00:00
2020-01-04 19:31:52 +00:00
@override
Widget body(BuildContext context) {
return SettingsForm();
}
}
class SettingsForm extends StatefulWidget {
@override
2020-01-08 12:26:34 +00:00
SettingsFormState createState() => SettingsFormState();
2020-01-04 19:31:52 +00:00
}
class SettingsFormState extends State<SettingsForm> {
final _telegramImage = Image.asset('assets/images/Telegram.png');
final _twitterImage = Image.asset('assets/images/Twitter.png');
final _changeNowImage = Image.asset('assets/images/change_now.png');
final _xmrBtcImage = Image.asset('assets/images/xmr_btc.png');
final _morphImage = Image.asset('assets/images/morph_icon.png');
2020-01-04 19:31:52 +00:00
final _emailUrl = 'mailto:support@cakewallet.com';
final _telegramUrl = 'https:t.me/cakewallet_bot';
2020-01-04 19:31:52 +00:00
final _twitterUrl = 'https:twitter.com/CakewalletXMR';
final _changeNowUrl = 'mailto:support@changenow.io';
final _xmrToUrl = 'mailto:support@xmr.to';
final _morphUrl = 'mailto:support@morphtoken.com';
2020-01-04 19:31:52 +00:00
2020-01-08 12:26:34 +00:00
final _items = List<SettingsItem>();
2020-01-04 19:31:52 +00:00
2020-01-08 12:26:34 +00:00
void _launchUrl(String url) async {
2020-01-04 19:31:52 +00:00
if (await canLaunch(url)) await launch(url);
}
2020-01-08 12:26:34 +00:00
void _setSettingsList() {
2020-01-04 19:31:52 +00:00
final settingsStore = Provider.of<SettingsStore>(context);
settingsStore.setItemHeaders();
_items.addAll([
SettingsItem(
onTaped: () => _setBalance(context),
title: ItemHeaders.displayBalanceAs,
widget: Observer(
builder: (_) => Text(
settingsStore.balanceDisplayMode.toString(),
textAlign: TextAlign.right,
2020-01-04 19:31:52 +00:00
style: TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryTextTheme.caption.color),
2020-01-04 19:31:52 +00:00
)),
attribute: Attributes.widget),
SettingsItem(
onTaped: () => _setCurrency(context),
title: ItemHeaders.currency,
widget: Observer(
builder: (_) => Text(
settingsStore.fiatCurrency.toString(),
textAlign: TextAlign.right,
2020-01-04 19:31:52 +00:00
style: TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryTextTheme.caption.color),
2020-01-04 19:31:52 +00:00
)),
attribute: Attributes.widget),
SettingsItem(
onTaped: () => _setTransactionPriority(context),
title: ItemHeaders.feePriority,
widget: Observer(
builder: (_) => Text(
settingsStore.transactionPriority.toString(),
textAlign: TextAlign.right,
2020-01-04 19:31:52 +00:00
style: TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryTextTheme.caption.color),
2020-01-04 19:31:52 +00:00
)),
attribute: Attributes.widget),
SettingsItem(
title: ItemHeaders.saveRecipientAddress,
attribute: Attributes.switcher),
SettingsItem(title: '', attribute: Attributes.header),
2020-01-04 19:31:52 +00:00
SettingsItem(
onTaped: () {
Navigator.of(context).pushNamed(Routes.auth,
2020-01-08 12:26:34 +00:00
arguments: (bool isAuthenticatedSuccessfully,
AuthPageState auth) =>
2020-01-04 19:31:52 +00:00
isAuthenticatedSuccessfully
? Navigator.of(context).popAndPushNamed(Routes.setupPin,
2020-01-08 12:26:34 +00:00
arguments:
(BuildContext setupPinContext, String _) =>
Navigator.of(context).pop())
2020-01-04 19:31:52 +00:00
: null);
},
title: ItemHeaders.changePIN,
attribute: Attributes.arrow),
SettingsItem(
onTaped: () => Navigator.pushNamed(context, Routes.changeLanguage),
title: ItemHeaders.changeLanguage,
attribute: Attributes.arrow),
SettingsItem(
title: ItemHeaders.allowBiometricalAuthentication,
attribute: Attributes.switcher),
SettingsItem(title: ItemHeaders.darkMode, attribute: Attributes.switcher),
SettingsItem(
widgetBuilder: (context) {
return PopupMenuButton<ActionListDisplayMode>(
itemBuilder: (context) => [
PopupMenuItem(
value: ActionListDisplayMode.transactions,
child: Observer(
builder: (_) => Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(S
.of(context)
.settings_transactions,
style: TextStyle(
color: Theme.of(context).primaryTextTheme.title.color
),
),
2020-01-04 19:31:52 +00:00
Checkbox(
value: settingsStore
.actionlistDisplayMode
.contains(ActionListDisplayMode
.transactions),
onChanged: (value) => settingsStore
.toggleTransactionsDisplay(),
)
]))),
PopupMenuItem(
value: ActionListDisplayMode.trades,
child: Observer(
builder: (_) => Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
S.of(context).settings_trades,
style: TextStyle(
color: Theme.of(context).primaryTextTheme.title.color
),
),
2020-01-04 19:31:52 +00:00
Checkbox(
value: settingsStore
.actionlistDisplayMode
.contains(
ActionListDisplayMode.trades),
onChanged: (value) => settingsStore
.toggleTradesDisplay(),
)
])))
],
child: Container(
height: 56,
padding: EdgeInsets.only(left: 24, right: 24),
2020-01-04 19:31:52 +00:00
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(S.of(context).settings_display_on_dashboard_list,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).primaryTextTheme.title.color)),
2020-01-04 19:31:52 +00:00
Observer(builder: (_) {
var title = '';
if (settingsStore.actionlistDisplayMode.length ==
ActionListDisplayMode.values.length) {
title = S.of(context).settings_all;
}
if (title.isEmpty &&
settingsStore.actionlistDisplayMode
.contains(ActionListDisplayMode.trades)) {
title = S.of(context).settings_only_trades;
}
if (title.isEmpty &&
settingsStore.actionlistDisplayMode.contains(
ActionListDisplayMode.transactions)) {
title = S.of(context).settings_only_transactions;
}
if (title.isEmpty) {
title = S.of(context).settings_none;
}
return Text(title,
style: TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryTextTheme.caption.color));
2020-01-04 19:31:52 +00:00
})
]),
));
},
attribute: Attributes.rawWidget),
SettingsItem(title: '', attribute: Attributes.header),
2020-01-04 19:31:52 +00:00
SettingsItem(
onTaped: () => _launchUrl(_emailUrl),
title: 'Email',
link: 'support@cakewallet.com',
2020-01-04 19:31:52 +00:00
image: null,
attribute: Attributes.link),
SettingsItem(
onTaped: () => _launchUrl(_telegramUrl),
title: 'Telegram',
link: 'Cake_Wallet',
2020-01-04 19:31:52 +00:00
image: _telegramImage,
attribute: Attributes.link),
SettingsItem(
onTaped: () => _launchUrl(_twitterUrl),
title: 'Twitter',
link: '@CakeWalletXMR',
2020-01-04 19:31:52 +00:00
image: _twitterImage,
attribute: Attributes.link),
SettingsItem(
onTaped: () => _launchUrl(_changeNowUrl),
title: 'ChangeNow',
link: 'support@changenow.io',
image: _changeNowImage,
attribute: Attributes.link),
SettingsItem(
onTaped: () => _launchUrl(_morphUrl),
title: 'Morph',
link: 'support@morphtoken.com',
image: _morphImage,
attribute: Attributes.link),
2020-01-04 19:31:52 +00:00
SettingsItem(
onTaped: () => _launchUrl(_xmrToUrl),
title: 'XMR.to',
link: 'support@xmr.to',
image: _xmrBtcImage,
attribute: Attributes.link),
SettingsItem(
onTaped: () {
Navigator.push(
context,
2020-01-08 12:26:34 +00:00
CupertinoPageRoute<void>(
2020-01-04 19:31:52 +00:00
builder: (BuildContext context) => DisclaimerPage()));
},
title: ItemHeaders.termsAndConditions,
attribute: Attributes.arrow),
SettingsItem(
onTaped: () => Navigator.pushNamed(context, Routes.faq),
title: ItemHeaders.faq,
attribute: Attributes.arrow)
]);
setState(() {});
}
2020-01-08 12:26:34 +00:00
void _afterLayout(dynamic _) => _setSettingsList();
2020-01-04 19:31:52 +00:00
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback(_afterLayout);
}
Widget _getWidget(SettingsItem item) {
switch (item.attribute) {
case Attributes.arrow:
return SettingsArrowListRow(
onTaped: item.onTaped,
title: item.title,
);
case Attributes.header:
return SettingsHeaderListRow(
title: item.title,
);
case Attributes.link:
return SettingsLinktListRow(
onTaped: item.onTaped,
title: item.title,
link: item.link,
image: item.image,
);
case Attributes.switcher:
return SettingsSwitchListRow(
title: item.title,
);
case Attributes.widget:
return SettingsTextListRow(
onTaped: item.onTaped,
title: item.title,
widget: item.widget,
);
case Attributes.rawWidget:
return SettingRawWidgetListRow(widgetBuilder: item.widgetBuilder);
default:
return Offstage();
}
}
@override
Widget build(BuildContext context) {
final settingsStore = Provider.of<SettingsStore>(context);
settingsStore.setItemHeaders();
final shortDivider = Container(
height: 1,
padding: EdgeInsets.only(left: 24),
color: Theme.of(context).accentTextTheme.title.backgroundColor,
child: Container(
height: 1,
color: Theme.of(context).dividerColor,
),
);
final longDivider = Container(
height: 1,
color: Theme.of(context).dividerColor,
);
return Container(
padding: EdgeInsets.only(top: 12),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
longDivider,
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: _items.length,
itemBuilder: (context, index) {
final item = _items[index];
Widget divider;
if (item.attribute == Attributes.header || item == _items.last) {
divider = longDivider;
} else if (_items[index + 1].attribute == Attributes.header){
divider = longDivider;
} else {
divider = shortDivider;
}
return Column(
children: <Widget>[
_getWidget(item),
divider
],
);
}),
Padding(
padding: EdgeInsets.only(top: 12),
child: ListTile(
title: Center(
child: Text(
settingsStore.itemHeaders[ItemHeaders.version],
style: TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryTextTheme.caption.color)
),
),
),
)
],
)),
);
2020-01-04 19:31:52 +00:00
}
2020-01-08 12:26:34 +00:00
Future<void> _setBalance(BuildContext context) async {
2020-01-04 19:31:52 +00:00
final settingsStore = Provider.of<SettingsStore>(context);
final items = BalanceDisplayMode.all;
final selectedItem = items.indexOf(settingsStore.balanceDisplayMode);
2020-01-04 19:31:52 +00:00
await showDialog<void>(
builder: (_) => Picker(
items: items,
selectedAtIndex: selectedItem,
title: S.of(context).please_select,
mainAxisAlignment: MainAxisAlignment.center,
onItemSelected: (BalanceDisplayMode mode) async =>
await settingsStore.setCurrentBalanceDisplayMode(
balanceDisplayMode: mode)),
context: context);
2020-01-04 19:31:52 +00:00
}
2020-01-08 12:26:34 +00:00
Future<void> _setCurrency(BuildContext context) async {
2020-01-04 19:31:52 +00:00
final settingsStore = Provider.of<SettingsStore>(context);
final items = FiatCurrency.all;
final selectedItem = items.indexOf(settingsStore.fiatCurrency);
2020-01-04 19:31:52 +00:00
await showDialog<void>(
builder: (_) => Picker(
items: items,
selectedAtIndex: selectedItem,
title: S.of(context).please_select,
mainAxisAlignment: MainAxisAlignment.center,
onItemSelected: (FiatCurrency currency) async =>
await settingsStore.setCurrentFiatCurrency(currency: currency)),
context: context);
2020-01-04 19:31:52 +00:00
}
2020-01-08 12:26:34 +00:00
Future<void> _setTransactionPriority(BuildContext context) async {
2020-01-04 19:31:52 +00:00
final settingsStore = Provider.of<SettingsStore>(context);
final items = TransactionPriority.all;
final selectedItem = items.indexOf(settingsStore.transactionPriority);
2020-01-04 19:31:52 +00:00
await showDialog<void>(
builder: (_) => Picker(
items: items,
selectedAtIndex: selectedItem,
title: S.of(context).please_select,
mainAxisAlignment: MainAxisAlignment.center,
onItemSelected: (TransactionPriority priority) async =>
await settingsStore.setCurrentTransactionPriority(
priority: priority)),
context: context);
2020-01-04 19:31:52 +00:00
}
}