Merge pull request #62 from cake-tech/CWA-216-new-settings-screen

Cwa 216 new settings screen
This commit is contained in:
Oleksandr Sobol 2020-05-25 18:32:42 +03:00 committed by GitHub
commit 22f131069f
14 changed files with 683 additions and 674 deletions

View file

@ -6,6 +6,8 @@ import 'package:cake_wallet/palette.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/generated/i18n.dart';
class DisclaimerPage extends BasePage {
DisclaimerPage({this.isReadOnly = false});
@ -13,7 +15,7 @@ class DisclaimerPage extends BasePage {
final bool isReadOnly;
@override
bool get isModalBackButton => false;
Color get backgroundColor => PaletteDark.historyPanel;
@override
String get title => 'Terms of Use';
@ -34,7 +36,7 @@ class DisclaimerPageBody extends StatefulWidget {
class DisclaimerBodyState extends State<DisclaimerPageBody> {
DisclaimerBodyState(this._isAccepted);
static const xmrtoUrl = 'https://xmr.to/app_static/html/tos.html';
static const xmrtoUrl = 'https://xmr.to/terms-of-service';
static const changenowUrl = 'https://changenow.io/terms-of-use';
static const morphUrl = 'http://morphtoken.com/terms';
@ -55,22 +57,11 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
await showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(
'Terms and conditions',
textAlign: TextAlign.center,
),
content: Text(
'By using this app, you agree to the Terms of Agreement set forth to below',
textAlign: TextAlign.center,
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK')),
],
return AlertWithOneAction(
alertTitle: 'Terms and conditions',
alertContent: 'By using this app, you agree to the Terms of Agreement set forth to below',
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop()
);
});
}
@ -86,245 +77,255 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
SizedBox(height: 10.0),
Expanded(
child: Stack(
children: <Widget>[
SingleChildScrollView(
padding: EdgeInsets.only(left: 25.0, right: 25.0),
child: Column(
return Container(
color: PaletteDark.historyPanel,
child: Column(
children: <Widget>[
SizedBox(height: 10.0),
Expanded(
child: Stack(
children: <Widget>[
!_isAccepted
? Row(
SingleChildScrollView(
padding: EdgeInsets.only(left: 24.0, right: 24.0),
child: Column(
children: <Widget>[
!_isAccepted
? Row(
children: <Widget>[
Expanded(
child: Text(
'Terms and conditions',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold),
fontSize: 20.0,
fontWeight: FontWeight.bold,
color: Colors.white
),
),
)
],
)
: Offstage(),
!_isAccepted
? SizedBox(
: Offstage(),
!_isAccepted
? SizedBox(
height: 20.0,
)
: Offstage(),
Row(
children: <Widget>[
Expanded(
child: Text(
'Legal Disclaimer\nAnd\nTerms of Use',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12.0, fontWeight: FontWeight.bold),
),
)
],
),
SizedBox(
height: 16.0,
),
Row(
children: <Widget>[
Expanded(
child: Text(
_fileText,
style: TextStyle(fontSize: 12.0),
))
],
),
SizedBox(
height: 16.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Text(
'Other Terms and Conditions',
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 14.0, fontWeight: FontWeight.bold),
),
)
],
),
SizedBox(
height: 16.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () => launchUrl(xmrtoUrl),
child: Text(
xmrtoUrl,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
fontSize: 14.0,
fontWeight: FontWeight.normal,
decoration: TextDecoration.underline),
),
))
],
),
SizedBox(
height: 16.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () => launchUrl(changenowUrl),
child: Text(
changenowUrl,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
fontSize: 14.0,
fontWeight: FontWeight.normal,
decoration: TextDecoration.underline),
),
))
],
),
SizedBox(
height: 16.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () => launchUrl(morphUrl),
child: Text(
morphUrl,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
fontSize: 14.0,
fontWeight: FontWeight.normal,
decoration: TextDecoration.underline),
),
))
],
),
SizedBox(
height: 16.0,
)
],
),
),
Container(
alignment: Alignment.bottomCenter,
child: Container(
height: 12.0,
child: ClipRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 0.7, sigmaY: 0.7),
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Theme.of(context).backgroundColor.withOpacity(0.0),
Theme.of(context).backgroundColor,
: Offstage(),
Row(
children: <Widget>[
Expanded(
child: Text(
'Legal Disclaimer\nAnd\nTerms of Use',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.bold,
color: Colors.white
),
),
)
],
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
),
SizedBox(
height: 16.0,
),
Row(
children: <Widget>[
Expanded(
child: Text(
_fileText,
style: TextStyle(
fontSize: 12.0,
color: Colors.white
),
))
],
),
SizedBox(
height: 16.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Text(
'Other Terms and Conditions',
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold,
color: Colors.white
),
),
)
],
),
SizedBox(
height: 16.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () => launchUrl(xmrtoUrl),
child: Text(
xmrtoUrl,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
fontSize: 14.0,
fontWeight: FontWeight.normal,
decoration: TextDecoration.underline),
),
))
],
),
SizedBox(
height: 16.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () => launchUrl(changenowUrl),
child: Text(
changenowUrl,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
fontSize: 14.0,
fontWeight: FontWeight.normal,
decoration: TextDecoration.underline),
),
))
],
),
SizedBox(
height: 16.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () => launchUrl(morphUrl),
child: Text(
morphUrl,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
fontSize: 14.0,
fontWeight: FontWeight.normal,
decoration: TextDecoration.underline),
),
))
],
),
SizedBox(
height: 16.0,
)
],
),
),
Container(
alignment: Alignment.bottomCenter,
child: Container(
height: 12.0,
child: ClipRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 0.7, sigmaY: 0.7),
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
PaletteDark.historyPanel.withOpacity(0.0),
PaletteDark.historyPanel,
],
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
),
),
),
),
),
),
),
)
],
)),
if (!widget.isReadOnly) ...[
!_isAccepted
? Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 24.0, top: 10.0, right: 24.0, bottom: 10.0),
child: InkWell(
onTap: () {
setState(() {
_checked = !_checked;
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
height: 24.0,
width: 24.0,
margin: EdgeInsets.only(
right: 10.0,
),
decoration: BoxDecoration(
border: Border.all(
color: Palette.lightGrey, width: 1.0),
borderRadius: BorderRadius.all(
Radius.circular(8.0)),
color: PaletteDark.historyPanel),
child: _checked
? Icon(
Icons.check,
color: Colors.blue,
size: 20.0,
)
: null,
),
Text(
'I agree to Terms of Use',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0,
color: Colors.white
),
)
],
),
)),
),
],
)
: Offstage(),
!_isAccepted
? Container(
padding:
EdgeInsets.only(left: 24.0, right: 24.0, bottom: 24.0),
child: PrimaryButton(
onPressed: _checked ? () {} : null,
text: 'Accept',
color: Colors.green,
textColor: Colors.white,
),
)
: Offstage(),
_isAccepted
? SizedBox(
height: 24.0,
)
: Offstage()
],
)),
if (!widget.isReadOnly) ...[
!_isAccepted
? Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 25.0, top: 10.0, right: 25.0, bottom: 10.0),
child: InkWell(
onTap: () {
setState(() {
_checked = !_checked;
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
height: 25.0,
width: 25.0,
margin: EdgeInsets.only(
right: 10.0,
),
decoration: BoxDecoration(
border: Border.all(
color: Palette.lightGrey, width: 1.0),
borderRadius: BorderRadius.all(
Radius.circular(8.0)),
color: Theme.of(context).backgroundColor),
child: _checked
? Icon(
Icons.check,
color: Colors.blue,
size: 20.0,
)
: null,
),
Text(
'I agree to Terms of Use',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0),
)
],
),
)),
),
],
)
: Offstage(),
!_isAccepted
? Container(
padding:
EdgeInsets.only(left: 25.0, right: 25.0, bottom: 25.0),
child: PrimaryButton(
onPressed: _checked ? () {} : null,
text: 'Accept',
color: Theme.of(context)
.primaryTextTheme
.button
.backgroundColor,
textColor: Theme.of(context)
.primaryTextTheme
.button
.color,
),
)
: Offstage(),
_isAccepted
? SizedBox(
height: 20.0,
)
: Offstage()
],
],
),
);
}
}

View file

@ -2,10 +2,10 @@ 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:cake_wallet/src/screens/exchange/widgets/provider_picker.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
class PresentProviderPicker extends StatelessWidget {
PresentProviderPicker({@required this.exchangeStore});
@ -72,7 +72,7 @@ class PresentProviderPicker extends StatelessWidget {
}
showDialog<void>(
builder: (_) => ProviderPicker(
builder: (_) => Picker(
items: items,
images: images,
selectedAtIndex: selectedItem,

View file

@ -1,124 +0,0 @@
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/domain/exchange/exchange_provider.dart';
class ProviderPicker extends StatelessWidget {
ProviderPicker({
@required this.selectedAtIndex,
@required this.items,
@required this.images,
@required this.title,
@required this.onItemSelected,
});
final int selectedAtIndex;
final List<ExchangeProvider> items;
final List<Image> images;
final String title;
final Function(ExchangeProvider) onItemSelected;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: Container(
color: Colors.transparent,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
child: Container(
decoration: BoxDecoration(color: PaletteDark.historyPanel.withOpacity(0.75)),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 24, right: 24),
child: Text(
title,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
decoration: TextDecoration.none,
color: Colors.white
),
),
),
Padding(
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
child: GestureDetector(
onTap: () => null,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(14)),
child: Container(
height: 233,
color: PaletteDark.menuList,
child: ListView.separated(
separatorBuilder: (context, index) => Divider(
color: PaletteDark.mainBackgroundColor,
height: 1,
),
itemCount: items == null ? 0 : items.length,
itemBuilder: (context, index) {
final item = items[index];
final image = images[index];
final isItemSelected = index == selectedAtIndex;
final color = isItemSelected
? PaletteDark.menuHeader
: Colors.transparent;
final textColor = isItemSelected
? Colors.blue
: Colors.white;
return GestureDetector(
onTap: () {
if (onItemSelected == null) {
return;
}
Navigator.of(context).pop();
onItemSelected(item);
},
child: Container(
height: 77,
padding: EdgeInsets.only(left: 24, right: 24),
color: color,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
image,
Padding(
padding: EdgeInsets.only(left: 12),
child: Text(
item.toString(),
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: textColor,
decoration: TextDecoration.none,
),
),
)
],
),
),
);
},
)
),
),
),
)
],
),
)
),
),
),
);
}
}

View file

@ -5,49 +5,134 @@ import 'package:provider/provider.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/stores/settings/settings_store.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/palette.dart';
class FaqPage extends BasePage {
@override
String get title => S.current.faq;
@override
Widget body(BuildContext context) {
return FutureBuilder(
builder: (context, snapshot) {
final faqItems = jsonDecode(snapshot.data.toString()) as List;
Color get backgroundColor => PaletteDark.historyPanel;
return ListView.separated(
itemBuilder: (BuildContext context, int index) {
final itemTitle = faqItems[index]["question"].toString();
final itemChild = faqItems[index]["answer"].toString();
@override
Widget body(BuildContext context) => FaqForm();
}
return ExpansionTile(
title: Text(itemTitle),
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.only(left: 15.0, right: 15.0),
class FaqForm extends StatefulWidget {
@override
FaqFormState createState() => FaqFormState();
}
class FaqFormState extends State<FaqForm> {
final addIcon = Icon(Icons.add, color: Colors.white);
final removeIcon = Icon(Icons.remove, color: Colors.green);
List<Icon> icons;
List<Color> colors;
bool isLoaded = false;
@override
Widget build(BuildContext context) {
return Container(
color: PaletteDark.historyPanel,
padding: EdgeInsets.only(top: 12),
child: Container(
color: PaletteDark.menuList,
child: FutureBuilder(
builder: (context, snapshot) {
final faqItems = jsonDecode(snapshot.data.toString()) as List;
if (snapshot.hasData) {
setIconsAndColors(faqItems.length);
}
return SingleChildScrollView(
child: ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
final itemTitle = faqItems[index]["question"].toString();
final itemChild = faqItems[index]["answer"].toString();
return ExpansionTile(
title: Padding(
padding: EdgeInsets.only(left: 8, top: 12, bottom: 12),
child: Text(
itemChild,
itemTitle,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: colors[index]
),
),
))
],
)
],
),
trailing: Padding(
padding: EdgeInsets.only(right: 24),
child: Container(
width: double.minPositive,
child: Center(
child: icons[index]
),
),
),
backgroundColor: PaletteDark.menuHeader,
onExpansionChanged: (value) {
setState(() {
if (value) {
icons[index] = removeIcon;
colors[index] = Colors.green;
} else {
icons[index] = addIcon;
colors[index] = Colors.white;
}
});
},
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 24.0,
right: 24.0,
bottom: 8
),
child: Text(
itemChild,
style: TextStyle(
fontSize: 12,
color: Colors.white
),
),
))
],
)
],
);
},
separatorBuilder: (_, __) =>
Container(color: PaletteDark.mainBackgroundColor, height: 1.0),
itemCount: faqItems == null ? 0 : faqItems.length,
),
);
},
separatorBuilder: (_, __) =>
Divider(color: Theme.of(context).dividerTheme.color, height: 1.0),
itemCount: faqItems == null ? 0 : faqItems.length,
);
},
future: rootBundle.loadString(getFaqPath(context)),
future: rootBundle.loadString(getFaqPath(context)),
),
),
);
}
void setIconsAndColors(int index) {
if (isLoaded) {
return;
}
icons = List.generate(index, (int i) => addIcon);
colors = List.generate(index, (int i) => Colors.white);
isLoaded = true;
}
String getFaqPath(BuildContext context) {
final settingsStore = Provider.of<SettingsStore>(context);
@ -80,4 +165,4 @@ class FaqPage extends BasePage {
return 'assets/faq/faq_en.json';
}
}
}
}

View file

@ -5,76 +5,101 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/domain/common/language.dart';
import 'package:cake_wallet/src/stores/settings/settings_store.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
class ChangeLanguage extends BasePage {
@override
String get title => S.current.settings_change_language;
@override
Color get backgroundColor => PaletteDark.historyPanel;
@override
Widget body(BuildContext context) {
final settingsStore = Provider.of<SettingsStore>(context);
final currentLanguage = Provider.of<Language>(context);
final currentColor = Theme.of(context).selectedRowColor;
final notCurrentColor = Theme.of(context).accentTextTheme.subhead.backgroundColor;
final currentColor = Colors.green;
final notCurrentColor = Colors.white;
final shortDivider = Container(
height: 1,
padding: EdgeInsets.only(left: 24),
color: PaletteDark.menuList,
child: Container(
height: 1,
color: PaletteDark.mainBackgroundColor,
),
);
final longDivider = Container(
height: 1,
color: PaletteDark.mainBackgroundColor,
);
return Container(
padding: EdgeInsets.only(top: 10.0, bottom: 10.0),
color: PaletteDark.historyPanel,
padding: EdgeInsets.only(top: 10.0),
child: ListView.builder(
itemCount: languages.values.length,
itemBuilder: (BuildContext context, int index) {
final item = languages.values.elementAt(index);
final code = languages.keys.elementAt(index);
final isCurrent = settingsStore.languageCode == null
? false
: languages.keys.elementAt(index) ==
settingsStore.languageCode;
: code == settingsStore.languageCode;
return Container(
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
color: isCurrent ? currentColor : notCurrentColor,
child: ListTile(
title: Text(
languages.values.elementAt(index),
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context).primaryTextTheme.title.color),
),
onTap: () async {
if (!isCurrent) {
await showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(
S.of(context).change_language,
textAlign: TextAlign.center,
),
content: Text(
S.of(context).change_language_to(
languages.values.elementAt(index)),
textAlign: TextAlign.center,
),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(S.of(context).cancel)),
FlatButton(
onPressed: () {
return Column(
children: <Widget>[
index == 0 ? longDivider : Offstage(),
Container(
padding: EdgeInsets.only(top: 4, bottom: 4),
color: PaletteDark.menuList,
child: ListTile(
contentPadding: EdgeInsets.only(left: 24, right: 24),
title: Text(
item,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
color: isCurrent ? currentColor : notCurrentColor
),
),
trailing: isCurrent
? Icon(Icons.done, color: currentColor)
: Offstage(),
onTap: () async {
if (!isCurrent) {
await showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertWithTwoActions(
alertTitle: S.of(context).change_language,
alertContent: S.of(context).change_language_to(item),
leftButtonText: S.of(context).change,
rightButtonText: S.of(context).cancel,
actionLeftButton: () {
settingsStore.saveLanguageCode(
languageCode:
languages.keys.elementAt(index));
currentLanguage.setCurrentLanguage(
languages.keys.elementAt(index));
languageCode: code);
currentLanguage.setCurrentLanguage(code);
Navigator.of(context).pop();
},
child: Text(S.of(context).change)),
],
);
});
}
},
),
actionRightButton: () => Navigator.of(context).pop()
);
});
}
},
),
),
item == languages.values.last
? longDivider
: shortDivider
],
);
},
));
)
);
}
}

View file

@ -17,7 +17,7 @@ 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/present_picker.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
// 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';
@ -31,10 +31,7 @@ class SettingsPage extends BasePage {
String get title => S.current.settings_title;
@override
bool get isModalBackButton => true;
@override
Color get backgroundColor => Palette.lightGrey2;
Color get backgroundColor => PaletteDark.historyPanel;
@override
Widget body(BuildContext context) {
@ -73,21 +70,6 @@ class SettingsFormState extends State<SettingsForm> {
settingsStore.setItemHeaders();
_items.addAll([
SettingsItem(title: ItemHeaders.nodes, attribute: Attributes.header),
SettingsItem(
onTaped: () => Navigator.of(context).pushNamed(Routes.nodeList),
title: ItemHeaders.currentNode,
widget: Observer(
builder: (_) => Text(
settingsStore.node == null ? '' : settingsStore.node.uri,
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 16.0,
color:
Theme.of(context).primaryTextTheme.subtitle.color),
)),
attribute: Attributes.widget),
SettingsItem(title: ItemHeaders.wallets, attribute: Attributes.header),
SettingsItem(
onTaped: () => _setBalance(context),
title: ItemHeaders.displayBalanceAs,
@ -96,9 +78,8 @@ class SettingsFormState extends State<SettingsForm> {
settingsStore.balanceDisplayMode.toString(),
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 16.0,
color:
Theme.of(context).primaryTextTheme.subtitle.color),
fontSize: 14.0,
color: PaletteDark.walletCardText),
)),
attribute: Attributes.widget),
SettingsItem(
@ -109,9 +90,8 @@ class SettingsFormState extends State<SettingsForm> {
settingsStore.fiatCurrency.toString(),
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 16.0,
color:
Theme.of(context).primaryTextTheme.subtitle.color),
fontSize: 14.0,
color: PaletteDark.walletCardText),
)),
attribute: Attributes.widget),
SettingsItem(
@ -122,15 +102,14 @@ class SettingsFormState extends State<SettingsForm> {
settingsStore.transactionPriority.toString(),
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 16.0,
color:
Theme.of(context).primaryTextTheme.subtitle.color),
fontSize: 14.0,
color: PaletteDark.walletCardText),
)),
attribute: Attributes.widget),
SettingsItem(
title: ItemHeaders.saveRecipientAddress,
attribute: Attributes.switcher),
SettingsItem(title: ItemHeaders.personal, attribute: Attributes.header),
SettingsItem(title: '', attribute: Attributes.header),
SettingsItem(
onTaped: () {
Navigator.of(context).pushNamed(Routes.auth,
@ -196,17 +175,14 @@ class SettingsFormState extends State<SettingsForm> {
],
child: Container(
height: 56,
padding: EdgeInsets.only(left: 20, right: 20),
padding: EdgeInsets.only(left: 24, right: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(S.of(context).settings_display_on_dashboard_list,
style: TextStyle(
fontSize: 16,
color: Theme.of(context)
.primaryTextTheme
.title
.color)),
fontSize: 14,
color: Colors.white)),
Observer(builder: (_) {
var title = '';
@ -233,17 +209,14 @@ class SettingsFormState extends State<SettingsForm> {
return Text(title,
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context)
.primaryTextTheme
.subtitle
.color));
fontSize: 14.0,
color: PaletteDark.walletCardText));
})
]),
));
},
attribute: Attributes.rawWidget),
SettingsItem(title: ItemHeaders.support, attribute: Attributes.header),
SettingsItem(title: '', attribute: Attributes.header),
SettingsItem(
onTaped: () => _launchUrl(_emailUrl),
title: 'Email',
@ -253,13 +226,13 @@ class SettingsFormState extends State<SettingsForm> {
SettingsItem(
onTaped: () => _launchUrl(_telegramUrl),
title: 'Telegram',
link: 't.me/cakewallet_bot',
link: 'Cake_Wallet',
image: _telegramImage,
attribute: Attributes.link),
SettingsItem(
onTaped: () => _launchUrl(_twitterUrl),
title: 'Twitter',
link: 'twitter.com/CakewalletXMR',
link: '@CakeWalletXMR',
image: _twitterImage,
attribute: Attributes.link),
SettingsItem(
@ -268,18 +241,18 @@ class SettingsFormState extends State<SettingsForm> {
link: 'support@changenow.io',
image: _changeNowImage,
attribute: Attributes.link),
SettingsItem(
onTaped: () => _launchUrl(_morphUrl),
title: 'Morph',
link: 'support@morphtoken.com',
image: _morphImage,
attribute: Attributes.link),
SettingsItem(
onTaped: () => _launchUrl(_xmrToUrl),
title: 'XMR.to',
link: 'support@xmr.to',
image: _xmrBtcImage,
attribute: Attributes.link),
SettingsItem(
onTaped: () => _launchUrl(_morphUrl),
title: 'MorphToken',
link: 'support@morphtoken.com',
image: _morphImage,
attribute: Attributes.link),
SettingsItem(
onTaped: () {
Navigator.push(
@ -345,87 +318,116 @@ class SettingsFormState extends State<SettingsForm> {
final settingsStore = Provider.of<SettingsStore>(context);
settingsStore.setItemHeaders();
return SingleChildScrollView(
child: Column(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: _items.length,
itemBuilder: (context, index) {
final item = _items[index];
bool _isDrawDivider = true;
final shortDivider = Container(
height: 1,
padding: EdgeInsets.only(left: 24),
color: PaletteDark.menuList,
child: Container(
height: 1,
color: PaletteDark.mainBackgroundColor,
),
);
if (item.attribute == Attributes.header || item == _items.last) {
_isDrawDivider = false;
} else {
if (_items[index + 1].attribute == Attributes.header) {
_isDrawDivider = false;
}
}
final longDivider = Container(
height: 1,
color: PaletteDark.mainBackgroundColor,
);
return Column(
children: <Widget>[
_getWidget(item),
_isDrawDivider
? Container(
color: Theme.of(context)
.accentTextTheme
.headline
.backgroundColor,
padding: EdgeInsets.only(
left: 20.0,
right: 20.0,
),
child: Divider(
color: Theme.of(context).dividerColor,
height: 1.0,
),
)
: Offstage()
],
);
}),
ListTile(
contentPadding: EdgeInsets.only(left: 20.0),
title: Text(
settingsStore.itemHeaders[ItemHeaders.version],
style: TextStyle(
fontSize: 14.0, color: Palette.wildDarkBlue)
),
)
],
));
return Container(
color: PaletteDark.historyPanel,
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: PaletteDark.walletCardText)
),
),
),
)
],
)),
);
}
Future<void> _setBalance(BuildContext context) async {
final settingsStore = Provider.of<SettingsStore>(context);
final selectedDisplayMode =
await presentPicker(context, BalanceDisplayMode.all);
final items = BalanceDisplayMode.all;
final selectedItem = items.indexOf(settingsStore.balanceDisplayMode);
if (selectedDisplayMode != null) {
await settingsStore.setCurrentBalanceDisplayMode(
balanceDisplayMode: selectedDisplayMode);
}
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);
}
Future<void> _setCurrency(BuildContext context) async {
final settingsStore = Provider.of<SettingsStore>(context);
final selectedCurrency = await presentPicker(context, FiatCurrency.all);
final items = FiatCurrency.all;
final selectedItem = items.indexOf(settingsStore.fiatCurrency);
if (selectedCurrency != null) {
await settingsStore.setCurrentFiatCurrency(currency: selectedCurrency);
}
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);
}
Future<void> _setTransactionPriority(BuildContext context) async {
final settingsStore = Provider.of<SettingsStore>(context);
final selectedPriority =
await presentPicker(context, TransactionPriority.all);
final items = TransactionPriority.all;
final selectedItem = items.indexOf(settingsStore.transactionPriority);
if (selectedPriority != null) {
await settingsStore.setCurrentTransactionPriority(
priority: selectedPriority);
}
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);
}
}

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/palette.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -8,22 +9,23 @@ class SettingsArrowListRow extends StatelessWidget {
final VoidCallback onTaped;
final String title;
final _cakeArrowImage = Image.asset('assets/images/cake_arrow.png');
final _cakeArrowImage = Image.asset('assets/images/select_arrow.png',
color: PaletteDark.walletCardText);
@override
Widget build(BuildContext context) {
final settingsStore = Provider.of<SettingsStore>(context);
return Container(
color: Theme.of(context).accentTextTheme.headline.backgroundColor,
color: PaletteDark.menuList,
child: ListTile(
contentPadding: EdgeInsets.only(left: 20.0, right: 20.0),
contentPadding: EdgeInsets.only(left: 24.0, right: 24.0),
title: Observer(
builder: (_) => Text(
settingsStore.itemHeaders[title],
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context).primaryTextTheme.title.color),
fontSize: 14.0,
color: Colors.white),
)),
trailing: _cakeArrowImage,
onTap: onTaped),

View file

@ -16,7 +16,7 @@ class SettingsHeaderListRow extends StatelessWidget {
return Column(
children: <Widget>[
SizedBox(
height: 28.0,
height: 20.0,
),
Container(
padding: EdgeInsets.only(left: 20.0),
@ -25,7 +25,9 @@ class SettingsHeaderListRow extends StatelessWidget {
children: <Widget>[
Observer(
builder: (_) => Text(
settingsStore.itemHeaders[title],
title.isNotEmpty
? settingsStore.itemHeaders[title]
: '',
style: TextStyle(
fontSize: 15.0, color: Palette.wildDarkBlue),
))

View file

@ -13,9 +13,9 @@ class SettingsLinktListRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).accentTextTheme.headline.backgroundColor,
color: PaletteDark.menuList,
child: ListTile(
contentPadding: EdgeInsets.only(left: 20.0, right: 20.0),
contentPadding: EdgeInsets.only(left: 24.0, right: 24.0),
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
@ -26,16 +26,15 @@ class SettingsLinktListRow extends StatelessWidget {
child: Text(
title,
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.title.color),
fontSize: 14.0,
color: Colors.white),
),
)
],
),
trailing: Text(
link,
style: TextStyle(fontSize: 14.0, color: Palette.cakeGreen),
style: TextStyle(fontSize: 14.0, color: Colors.blue),
),
onTap: onTaped,
),

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
class SettingRawWidgetListRow extends StatelessWidget {
SettingRawWidgetListRow({@required this.widgetBuilder});
@ -8,7 +9,7 @@ class SettingRawWidgetListRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).accentTextTheme.headline.backgroundColor,
color: PaletteDark.menuList,
child: widgetBuilder(context) ?? Container(),
);
}

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/palette.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -61,14 +62,14 @@ class SettingsSwitchListRow extends StatelessWidget {
final settingsStore = Provider.of<SettingsStore>(context);
return Container(
color: Theme.of(context).accentTextTheme.headline.backgroundColor,
color: PaletteDark.menuList,
child: ListTile(
contentPadding: EdgeInsets.only(left: 20.0, right: 20.0),
contentPadding: EdgeInsets.only(left: 24.0, right: 24.0),
title: Observer(
builder: (_) => Text(settingsStore.itemHeaders[title],
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context).primaryTextTheme.title.color)),
fontSize: 14,
color: Colors.white)),
),
trailing: _getSwitch(context)),
);

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/palette.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -15,9 +16,9 @@ class SettingsTextListRow extends StatelessWidget {
final settingsStore = Provider.of<SettingsStore>(context);
return Container(
color: Theme.of(context).accentTextTheme.headline.backgroundColor,
color: PaletteDark.menuList,
child: ListTile(
contentPadding: EdgeInsets.only(left: 20.0, right: 20.0),
contentPadding: EdgeInsets.only(left: 24.0, right: 24.0),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
@ -26,8 +27,8 @@ class SettingsTextListRow extends StatelessWidget {
builder: (_) => Text(
settingsStore.itemHeaders[title],
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context).primaryTextTheme.title.color),
fontSize: 14.0,
color: Colors.white),
)),
),
Flexible(

View file

@ -1,19 +1,23 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
class Picker<Item extends Object> extends StatelessWidget {
Picker(
{@required this.selectedAtIndex,
@required this.items,
@required this.title,
this.pickerHeight = 300,
this.onItemSelected});
Picker({
@required this.selectedAtIndex,
@required this.items,
this.images,
@required this.title,
@required this.onItemSelected,
this.mainAxisAlignment = MainAxisAlignment.start
});
final int selectedAtIndex;
final List<Item> items;
final List<Image> images;
final String title;
final double pickerHeight;
final Function(Item) onItemSelected;
final MainAxisAlignment mainAxisAlignment;
@override
Widget build(BuildContext context) {
@ -24,83 +28,98 @@ class Picker<Item extends Object> extends StatelessWidget {
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
child: Container(
decoration: BoxDecoration(color: Colors.white.withOpacity(0.55)),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
onTap: () => null,
child: Container(
width: double.infinity,
height: pickerHeight,
color: Theme.of(context).backgroundColor,
child: ListView.separated(
itemCount: items.length + 1,
separatorBuilder: (_, index) => index == 0
? SizedBox()
: Divider(
height: 1,
color: Color.fromRGBO(235, 238, 242, 1)),
itemBuilder: (_, index) {
if (index == 0) {
return Container(
height: 100,
width: double.infinity,
color: Theme.of(context).backgroundColor,
child: Center(
child: Text(
title,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
decoration: TextDecoration.none,
color: Theme.of(context)
.primaryTextTheme
.caption
.color),
decoration: BoxDecoration(color: PaletteDark.historyPanel.withOpacity(0.75)),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 24, right: 24),
child: Text(
title,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
decoration: TextDecoration.none,
color: Colors.white
),
),
),
Padding(
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
child: GestureDetector(
onTap: () => null,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(14)),
child: Container(
height: 233,
color: PaletteDark.menuList,
child: ListView.separated(
separatorBuilder: (context, index) => Divider(
color: PaletteDark.mainBackgroundColor,
height: 1,
),
),
);
}
itemCount: items == null ? 0 : items.length,
itemBuilder: (context, index) {
final item = items[index];
final image = images != null? images[index] : null;
final isItemSelected = index == selectedAtIndex;
index -= 1;
final item = items[index];
final color = isItemSelected
? PaletteDark.menuHeader
: Colors.transparent;
final textColor = isItemSelected
? Colors.blue
: Colors.white;
return GestureDetector(
onTap: () {
if (onItemSelected == null) {
return;
}
Navigator.of(context).pop();
onItemSelected(item);
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.only(top: 18, bottom: 18),
child: Center(
child: Text(
item.toString(),
style: TextStyle(
decoration: TextDecoration.none,
fontSize: 18,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: index == selectedAtIndex
? Color.fromRGBO(138, 80, 255, 1)
: Theme.of(context)
.primaryTextTheme
.caption
.color),
)),
),
);
},
)),
)
],
),
return GestureDetector(
onTap: () {
if (onItemSelected == null) {
return;
}
Navigator.of(context).pop();
onItemSelected(item);
},
child: Container(
height: 77,
padding: EdgeInsets.only(left: 24, right: 24),
color: color,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: mainAxisAlignment,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
image != null
? image
: Offstage(),
Padding(
padding: EdgeInsets.only(
left: image != null ? 12 : 0
),
child: Text(
item.toString(),
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: textColor,
decoration: TextDecoration.none,
),
),
)
],
),
),
);
},
)
),
),
),
)
],
),
)
),
),
),

View file

@ -1,3 +1,5 @@
import 'package:cake_wallet/palette.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class StandartSwitch extends StatefulWidget {
@ -16,29 +18,22 @@ class StandartSwitchState extends State<StandartSwitch> {
return GestureDetector(
onTap: widget.onTaped,
child: AnimatedContainer(
padding: EdgeInsets.only(left: 4.0, right: 4.0),
padding: EdgeInsets.only(left: 2.0, right: 2.0),
alignment: widget.value ? Alignment.centerRight : Alignment.centerLeft,
duration: Duration(milliseconds: 250),
width: 55.0,
height: 33.0,
width: 50,
height: 28,
decoration: BoxDecoration(
color: Theme.of(context).toggleButtonsTheme.color,
border: Border.all(
color: Theme.of(context).toggleButtonsTheme.borderColor),
borderRadius: BorderRadius.all(Radius.circular(10.0))),
color: widget.value
? Colors.green
: PaletteDark.mainBackgroundColor,
borderRadius: BorderRadius.all(Radius.circular(14.0))),
child: Container(
width: 25.0,
height: 25.0,
width: 24.0,
height: 24.0,
decoration: BoxDecoration(
color: widget.value
? Theme.of(context).toggleButtonsTheme.selectedColor
: Theme.of(context).toggleButtonsTheme.disabledColor,
borderRadius: BorderRadius.all(Radius.circular(8.0))),
child: Icon(
widget.value ? Icons.check : Icons.close,
color: Colors.white,
size: 16.0,
),
color: Colors.white,
shape: BoxShape.circle),
),
),
);