CAKE-30 | created settings_version_cell, language_row, version_list_item; applied new design to settings, faq, disclaimer, pin code, change language pages; fixed items of settings page

This commit is contained in:
OleksandrSobol
2020-09-07 20:35:34 +03:00
parent dab3c1c8b4
commit 30665aac1c
20 changed files with 278 additions and 176 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ class Language with ChangeNotifier {
}
static Future<String> localeDetection() async {
String locale = await Devicelocale.currentLocale;
var locale = await Devicelocale.currentLocale;
locale = Intl.shortLocale(locale);
return languages.keys.contains(locale) ? locale : 'en';
@@ -1,4 +1,5 @@
import 'dart:ui';
import 'package:cake_wallet/palette.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
@@ -132,6 +133,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
_fileText,
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.normal,
color: Theme.of(context).primaryTextTheme.title.color
),
))
@@ -169,7 +171,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
xmrtoUrl,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
color: Palette.blueCraiola,
fontSize: 14.0,
fontWeight: FontWeight.normal,
decoration: TextDecoration.underline),
@@ -190,7 +192,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
changenowUrl,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
color: Palette.blueCraiola,
fontSize: 14.0,
fontWeight: FontWeight.normal,
decoration: TextDecoration.underline),
@@ -211,7 +213,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
morphUrl,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
color: Palette.blueCraiola,
fontSize: 14.0,
fontWeight: FontWeight.normal,
decoration: TextDecoration.underline),
+73 -79
View File
@@ -1,4 +1,6 @@
import 'dart:convert';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
@@ -27,93 +29,85 @@ class FaqFormState extends State<FaqForm> {
@override
Widget build(BuildContext context) {
final addIcon = Icon(Icons.add, color: Theme.of(context).primaryTextTheme.title.color);
final removeIcon = Icon(Icons.remove, color: Colors.green);
final removeIcon = Icon(Icons.remove, color: Palette.blueCraiola);
return Container(
padding: EdgeInsets.only(top: 12),
child: Container(
color: Theme.of(context).accentTextTheme.headline.color,
child: FutureBuilder(
builder: (context, snapshot) {
final faqItems = jsonDecode(snapshot.data.toString()) as List;
padding: EdgeInsets.only(top: 12, left: 24),
child: FutureBuilder(
builder: (context, snapshot) {
final faqItems = jsonDecode(snapshot.data.toString()) as List;
if (snapshot.hasData) {
setIconsAndColors(context, faqItems.length, addIcon);
}
if (snapshot.hasData) {
setIconsAndColors(context, faqItems.length, addIcon);
}
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 SingleChildScrollView(
child: Column(
children: <Widget>[
StandardListSeparator(),
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(
itemTitle,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: colors[index]
return ListTileTheme(
contentPadding: EdgeInsets.fromLTRB(0, 6, 24, 6),
child: ExpansionTile(
title: Text(
itemTitle,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: colors[index]
),
),
),
),
trailing: Padding(
padding: EdgeInsets.only(right: 24),
child: Container(
width: double.minPositive,
child: Center(
child: icons[index]
),
),
),
backgroundColor: Theme.of(context).accentTextTheme.headline.backgroundColor,
onExpansionChanged: (value) {
setState(() {
if (value) {
icons[index] = removeIcon;
colors[index] = Colors.green;
} else {
icons[index] = addIcon;
colors[index] = Theme.of(context).primaryTextTheme.title.color;
}
});
},
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
trailing: icons[index],
onExpansionChanged: (value) {
setState(() {
if (value) {
icons[index] = removeIcon;
colors[index] = Palette.blueCraiola;
} else {
icons[index] = addIcon;
colors[index] = Theme.of(context).primaryTextTheme.title.color;
}
});
},
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 24.0,
right: 24.0,
bottom: 8
),
child: Text(
itemChild,
style: TextStyle(
fontSize: 12,
color: Theme.of(context).primaryTextTheme.title.color
),
),
))
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.only(
right: 24.0,
),
child: Text(
itemChild,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context).primaryTextTheme.title.color
),
),
))
],
)
],
)
],
);
},
separatorBuilder: (_, __) =>
Container(color: Theme.of(context).dividerColor, height: 1.0),
itemCount: faqItems == null ? 0 : faqItems.length,
),
);
},
future: rootBundle.loadString(getFaqPath(context)),
),
),
);
},
separatorBuilder: (_, __) =>
StandardListSeparator(),
itemCount: faqItems == null ? 0 : faqItems.length,
)
],
),
);
},
future: rootBundle.loadString(getFaqPath(context)),
),
);
}
+5 -4
View File
@@ -108,7 +108,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
Text(title,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.title.color)),
Spacer(flex: 3),
Container(
@@ -126,7 +126,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
shape: BoxShape.circle,
color: isFilled
? Theme.of(context).primaryTextTheme.title.color
: Theme.of(context).primaryTextTheme.caption.color,
: Theme.of(context).accentTextTheme.body1.color,
));
}),
),
@@ -143,7 +143,8 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
_changePinLengthText(),
style: TextStyle(
fontSize: 14.0,
color: Theme.of(context).primaryTextTheme.caption.color),
fontWeight: FontWeight.normal,
color: Theme.of(context).accentTextTheme.body1.decorationColor),
))
],
Spacer(flex: 1),
@@ -227,7 +228,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
child: Text('$index',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.primaryTextTheme
.title
+31 -67
View File
@@ -1,3 +1,5 @@
import 'package:cake_wallet/src/screens/settings/widgets/language_row.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
@@ -16,29 +18,13 @@ class ChangeLanguage extends BasePage {
final settingsStore = Provider.of<SettingsStore>(context);
final currentLanguage = Provider.of<Language>(context);
final currentColor = Colors.green;
final notCurrentColor = Theme.of(context).primaryTextTheme.title.color;
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: 10.0),
child: ListView.builder(
itemCount: languages.values.length,
itemBuilder: (BuildContext context, int index) {
child: SectionStandardList(
sectionCount: 1,
context: context,
itemCounter: (int sectionIndex) => languages.values.length,
itemBuilder: (_, sectionIndex, index) {
final item = languages.values.elementAt(index);
final code = languages.keys.elementAt(index);
@@ -46,52 +32,30 @@ class ChangeLanguage extends BasePage {
? false
: code == settingsStore.languageCode;
return Column(
children: <Widget>[
index == 0 ? longDivider : Offstage(),
Container(
padding: EdgeInsets.only(top: 4, bottom: 4),
color: Theme.of(context).accentTextTheme.title.backgroundColor,
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: code);
currentLanguage.setCurrentLanguage(code);
Navigator.of(context).pop();
},
actionRightButton: () => Navigator.of(context).pop()
);
});
}
},
),
),
item == languages.values.last
? longDivider
: shortDivider
],
return LanguageRow(
title: item,
isSelected: isCurrent,
handler: (context) 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: code);
currentLanguage.setCurrentLanguage(code);
Navigator.of(context).pop();
},
actionRightButton: () => Navigator.of(context).pop()
);
});
}
},
);
},
)
+12 -1
View File
@@ -1,3 +1,5 @@
import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart';
import 'package:cake_wallet/view_model/settings/version_list_item.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@@ -41,6 +43,8 @@ class SettingsPage extends BasePage {
return SettingsPickerCell<dynamic>(
title: item.title,
selectedItem: item.selectedItem(),
setItem: (dynamic value) => item.setItem(value),
isAlwaysShowScrollThumb: item.isAlwaysShowScrollThumb,
items: item.items);
});
}
@@ -55,7 +59,7 @@ class SettingsPage extends BasePage {
}
if (item is RegularListItem) {
return SettingsCellWithArrow(title: item.title);
return SettingsCellWithArrow(title: item.title, handler: item.handler);
}
if (item is LinkListItem) {
@@ -66,6 +70,13 @@ class SettingsPage extends BasePage {
linkTitle: item.linkTitle);
}
if (item is VersionListItem) {
return Observer(builder: (_) {
return SettingsVersionCell(
title: S.of(context).version(settingsViewModel.currentVersion));
});
}
return Container();
});
}
@@ -0,0 +1,30 @@
import 'package:cake_wallet/palette.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
class LanguageRow extends StandardListRow {
LanguageRow({@required String title, @required this.isSelected, @required Function(BuildContext context) handler}) :
super(title: title, isSelected: isSelected, onTap: handler);
@override
final bool isSelected;
@override
Widget buildCenter(BuildContext context, {@required bool hasLeftOffset}) {
return Expanded(
child: Row(mainAxisAlignment: MainAxisAlignment.start, children: [
if (hasLeftOffset) SizedBox(width: 10),
Text(title,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: titleColor(context)))
]));
}
@override
Widget buildTrailing(BuildContext context) =>
isSelected
? Icon(Icons.done, color: Palette.blueCraiola)
: Offstage();
}
@@ -2,11 +2,11 @@ import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
class SettingsCellWithArrow extends StandardListRow {
SettingsCellWithArrow({@required String title})
: super(title: title, isSelected: false);
SettingsCellWithArrow({@required String title, @required Function(BuildContext context) handler})
: super(title: title, isSelected: false, onTap: handler);
@override
Widget buildTrailing(BuildContext context) =>
Image.asset('assets/images/select_arrow.png',
color: Theme.of(context).primaryTextTheme.caption.color);
color: Theme.of(context).primaryTextTheme.overline.color);
}
@@ -1,5 +1,7 @@
import 'package:cake_wallet/palette.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:url_launcher/url_launcher.dart';
class SettingsLinkProviderCell extends StandardListRow {
SettingsLinkProviderCell(
@@ -7,7 +9,7 @@ class SettingsLinkProviderCell extends StandardListRow {
@required this.icon,
@required this.link,
@required this.linkTitle})
: super(title: title, isSelected: false);
: super(title: title, isSelected: false, onTap: (BuildContext context) => _launchUrl(link) );
final String icon;
final String link;
@@ -20,5 +22,11 @@ class SettingsLinkProviderCell extends StandardListRow {
@override
Widget buildTrailing(BuildContext context) => Text(linkTitle,
style: TextStyle(
fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.blue));
fontSize: 14.0,
fontWeight: FontWeight.w500,
color: Palette.blueCraiola));
static void _launchUrl(String url) async {
if (await canLaunch(url)) await launch(url);
}
}
@@ -4,7 +4,8 @@ import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:cake_wallet/generated/i18n.dart';
class SettingsPickerCell<ItemType> extends StandardListRow {
SettingsPickerCell({@required String title, this.selectedItem, this.items})
SettingsPickerCell({@required String title, this.selectedItem, this.items,
this.setItem, this.isAlwaysShowScrollThumb})
: super(
title: title,
isSelected: false,
@@ -18,11 +19,14 @@ class SettingsPickerCell<ItemType> extends StandardListRow {
selectedAtIndex: selectedAtIndex,
title: S.current.please_select,
mainAxisAlignment: MainAxisAlignment.center,
onItemSelected: (Object _) {}));
isAlwaysShowScrollThumb: isAlwaysShowScrollThumb,
onItemSelected: (ItemType value) => setItem(value)));
});
final ItemType selectedItem;
final List<ItemType> items;
final Function(ItemType) setItem;
final bool isAlwaysShowScrollThumb;
@override
Widget buildTrailing(BuildContext context) {
@@ -32,7 +36,7 @@ class SettingsPickerCell<ItemType> extends StandardListRow {
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.caption.color),
color: Theme.of(context).primaryTextTheme.overline.color),
);
}
}
@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
class SettingsVersionCell extends StatelessWidget {
SettingsVersionCell({@required this.title});
final String title;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(bottom: 24),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
title,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
color: Theme.of(context).primaryTextTheme.overline.color
),
)
],
),
);
}
}
@@ -53,7 +53,7 @@ class _SetupPinCodeFormState<WidgetType extends SetupPinCodeForm>
state.clear();
} else {
if (listEquals<int>(state.pin, _originalPin)) {
final String pin = state.pin.fold("", (ac, val) => ac + '$val');
final String pin = state.pin.fold('', (ac, val) => ac + '$val');
_userStore.set(password: pin);
_settingsStore.setDefaultPinLength(pinLength: state.pinLength);
+1 -3
View File
@@ -123,9 +123,7 @@ class PickerState<Item> extends State<Picker> {
mainAxisAlignment: widget.mainAxisAlignment,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
image != null
? image
: Offstage(),
image ?? Offstage(),
Padding(
padding: EdgeInsets.only(
left: image != null ? 12 : 0
+10 -7
View File
@@ -41,18 +41,17 @@ class StandardListRow extends StatelessWidget {
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: _titleColor(context)))
color: titleColor(context)))
]));
}
Widget buildTrailing(BuildContext context) => null;
Color _titleColor(BuildContext context) => isSelected
Color titleColor(BuildContext context) => isSelected
? Palette.blueCraiola
: Theme.of(context).primaryTextTheme.title.color;
Color _backgroundColor(BuildContext context) {
// return Theme.of(context).accentTextTheme.subtitle.decorationColor;
return Theme.of(context).backgroundColor;
}
}
@@ -114,16 +113,20 @@ class SectionStandardList extends StatelessWidget {
{@required this.itemCounter,
@required this.itemBuilder,
@required this.sectionCount,
this.hasTopSeparator = false,
BuildContext context})
: totalRows = transform(context, sectionCount, itemCounter, itemBuilder);
: totalRows = transform(hasTopSeparator, context, sectionCount,
itemCounter, itemBuilder);
final int sectionCount;
final bool hasTopSeparator;
final int Function(int sectionIndex) itemCounter;
final Widget Function(BuildContext context, int sectionIndex, int itemIndex)
itemBuilder;
final List<Widget> totalRows;
static List<Widget> transform(
bool hasTopSeparator,
BuildContext context,
int sectionCount,
int Function(int sectionIndex) itemCounter,
@@ -132,9 +135,9 @@ class SectionStandardList extends StatelessWidget {
final items = <Widget>[];
for (var sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
/*if (sectionIndex == 0) {
items.add(StandardListSeparator());
}*/
if ((sectionIndex == 0)&&(hasTopSeparator)) {
items.add(StandardListSeparator(padding: EdgeInsets.only(left: 24)));
}
final itemCount = itemCounter(sectionIndex);
+1 -1
View File
@@ -26,7 +26,7 @@ class StandartSwitchState extends State<StandartSwitch> {
decoration: BoxDecoration(
color: widget.value
? Colors.green
: PaletteDark.distantBlue,
: Theme.of(context).accentTextTheme.display4.color,
borderRadius: BorderRadius.all(Radius.circular(14.0))),
child: Container(
width: 24.0,