CAKE-27 | applied light theme to send and send template pages; made status bar is transparent; reworked menu widget and base send widget; applied switch between light and dark themes

This commit is contained in:
Oleksandr Sobol 2020-08-20 20:43:54 +03:00
parent 27dce3118d
commit 731f12cd63
13 changed files with 583 additions and 472 deletions

View file

@ -27,7 +27,9 @@ import 'package:cake_wallet/src/screens/receive/receive_page.dart';
import 'package:cake_wallet/src/screens/send/send_page.dart';
import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart';
import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
import 'package:cake_wallet/store/theme_changer_store.dart';
import 'package:cake_wallet/store/wallet_list_store.dart';
import 'package:cake_wallet/theme_changer.dart';
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart';
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
@ -318,3 +320,8 @@ Future setup(
getIt.registerFactory(() =>
ExchangeTemplatePage(getIt.get<ExchangeViewModel>()));
}
void setupThemeChangerStore(ThemeChanger themeChanger) {
getIt.registerSingleton<ThemeChangerStore>(
ThemeChangerStore(themeChanger: themeChanger));
}

View file

@ -1,4 +1,5 @@
import 'package:cake_wallet/reactions/bootstrap.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet_service.dart';
@ -52,6 +53,8 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/domain/common/language.dart';
import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart';
bool isThemeChangerRegistered = false;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
@ -197,7 +200,8 @@ class CakeWalletApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final settingsStore = Provider.of<SettingsStore>(context);
//final settingsStore = Provider.of<SettingsStore>(context);
final settingsStore = getIt.get<AppStore>().settingsStore;
return ChangeNotifierProvider<ThemeChanger>(
create: (_) => ThemeChanger(
@ -228,12 +232,20 @@ class MaterialAppWithTheme extends StatelessWidget {
final transactionDescriptions =
Provider.of<Box<TransactionDescription>>(context);
final statusBarColor =
settingsStore.isDarkTheme ? Colors.black : Colors.white;
if (!isThemeChangerRegistered) {
setupThemeChangerStore(theme);
isThemeChangerRegistered = true;
}
/*final statusBarColor =
settingsStore.isDarkTheme ? Colors.black : Colors.white;*/
final _settingsStore = getIt.get<AppStore>().settingsStore;
final statusBarColor = Colors.transparent;
final statusBarBrightness =
settingsStore.isDarkTheme ? Brightness.light : Brightness.dark;
_settingsStore.isDarkTheme ? Brightness.light : Brightness.dark;
final statusBarIconBrightness =
settingsStore.isDarkTheme ? Brightness.light : Brightness.dark;
_settingsStore.isDarkTheme ? Brightness.light : Brightness.dark;
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: statusBarColor,

View file

@ -29,6 +29,7 @@ class Palette {
static const Color gray = Color.fromRGBO(112, 147, 186, 1.0);
static const Color wildPeriwinkle = Color.fromRGBO(219, 227, 243, 1.0);
static const Color darkGray = Color.fromRGBO(122, 147, 186, 1.0);
static const Color shadowWhite = Color.fromRGBO(242, 245, 255, 1.0);
// FIXME: Rename.
static const Color eee = Color.fromRGBO(236, 239, 245, 1.0);

View file

@ -3,6 +3,7 @@ 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';
import 'package:flutter/rendering.dart';
class MenuWidget extends StatefulWidget {
MenuWidget({this.type, this.name, this.subname});
@ -23,7 +24,6 @@ class MenuWidgetState extends State<MenuWidget> {
double menuWidth;
double screenWidth;
double screenHeight;
double opacity;
double headerHeight;
double tileHeight;
@ -35,11 +35,10 @@ class MenuWidgetState extends State<MenuWidget> {
menuWidth = 0;
screenWidth = 0;
screenHeight = 0;
opacity = 0;
headerHeight = 125;
tileHeight = 75;
fromTopEdge = 50;
fromTopEdge = 30;
fromBottomEdge = 21;
super.initState();
@ -52,7 +51,6 @@ class MenuWidgetState extends State<MenuWidget> {
setState(() {
menuWidth = screenWidth;
opacity = 1;
if (screenHeight > largeScreen) {
final scale = screenHeight / largeScreen;
@ -69,41 +67,43 @@ class MenuWidgetState extends State<MenuWidget> {
final walletMenu = WalletMenu(context);
final itemCount = walletMenu.items.length;
return SafeArea(
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
return 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: PaletteDark.gray),
borderRadius: BorderRadius.all(Radius.circular(2)),
color: PaletteDark.gray),
)),
SizedBox(width: 12),
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.only(
SizedBox(width: 12),
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
bottomLeft: Radius.circular(24)),
child: Container(
width: menuWidth,
height: double.infinity,
color: Theme.of(context).textTheme.body2.decorationColor,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
child: Container(
width: menuWidth,
height: double.infinity,
color: Theme.of(context).textTheme.body2.color,
alignment: Alignment.topCenter,
child: ListView.separated(
itemBuilder: (_, index) {
if (index == 0) {
return Container(
height: headerHeight,
color: Theme.of(context).textTheme.body2.color,
padding: EdgeInsets.only(
left: 24,
top: fromTopEdge,
right: 24,
bottom: fromBottomEdge),
bottom: fromBottomEdge
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
@ -141,70 +141,63 @@ class MenuWidgetState extends State<MenuWidget> {
))
],
),
),
Container(
height: 1,
color: Theme.of(context).primaryTextTheme.caption.decorationColor,
),
ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (_, index) {
);
}
final item = walletMenu.items[index];
final image = walletMenu.images[index] ?? Offstage();
final isLastTile = index == itemCount - 1;
index--;
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: Theme.of(context).textTheme
.display2.color,
fontSize: 16,
fontWeight: FontWeight.bold),
))
],
),
)
);
},
separatorBuilder: (_, index) => Container(
height: 1,
color: Theme.of(context).primaryTextTheme.caption.decorationColor,
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: Container(
color: Theme.of(context).textTheme.body2.decorationColor,
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: Theme.of(context).textTheme
.display2.color,
fontSize: 16,
fontWeight: FontWeight.bold),
))
],
),
itemCount: itemCount)
],
)
);
},
separatorBuilder: (_, index) => Container(
height: 1,
color: Theme.of(context).primaryTextTheme.caption.decorationColor,
),
),
),
)
)
],
)
itemCount: itemCount + 1),
),
)
)
],
);
}

View file

@ -1,7 +1,6 @@
import 'package:cake_wallet/view_model/send_view_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/send/widgets/base_send_widget.dart';
@ -14,15 +13,33 @@ class SendPage extends BasePage {
String get title => sendViewModel.pageTitle;
@override
Color get backgroundLightColor => PaletteDark.nightBlue;
Color get titleColor => Colors.white;
@override
Color get backgroundDarkColor => PaletteDark.nightBlue;
Color get backgroundLightColor => Colors.transparent;
@override
Color get backgroundDarkColor => Colors.transparent;
@override
bool get resizeToAvoidBottomPadding => false;
@override
Widget body(BuildContext context) =>
BaseSendWidget(sendViewModel: sendViewModel);
BaseSendWidget(
sendViewModel: sendViewModel,
leading: leading(context),
middle: middle(context),
);
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: resizeToAvoidBottomPadding,
body: Container(
color: Theme.of(context).backgroundColor,
child: body(context)
)
);
}
}

View file

@ -1,6 +1,5 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/view_model/send_view_model.dart';
@ -15,15 +14,34 @@ class SendTemplatePage extends BasePage {
String get title => S.current.exchange_new_template;
@override
Color get backgroundLightColor => PaletteDark.nightBlue;
Color get titleColor => Colors.white;
@override
Color get backgroundDarkColor => PaletteDark.nightBlue;
Color get backgroundLightColor => Colors.transparent;
@override
Color get backgroundDarkColor => Colors.transparent;
@override
bool get resizeToAvoidBottomPadding => false;
@override
Widget body(BuildContext context) =>
BaseSendWidget(sendViewModel: sendViewModel, isTemplate: true);
BaseSendWidget(
sendViewModel: sendViewModel,
leading: leading(context),
middle: middle(context),
isTemplate: true
);
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: resizeToAvoidBottomPadding,
body: Container(
color: Theme.of(context).backgroundColor,
child: body(context)
)
);
}
}

View file

@ -22,11 +22,15 @@ import 'package:cake_wallet/routes.dart';
class BaseSendWidget extends StatelessWidget {
BaseSendWidget({
@required this.sendViewModel,
@required this.leading,
@required this.middle,
this.isTemplate = false
});
final SendViewModel sendViewModel;
final bool isTemplate;
final Widget leading;
final Widget middle;
final _addressController = TextEditingController();
final _cryptoAmountController = TextEditingController();
@ -42,371 +46,386 @@ class BaseSendWidget extends StatelessWidget {
_setEffects(context);
return Container(
color: PaletteDark.backgroundColor,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24),
content: Column(
children: <Widget>[
TopPanel(
color: PaletteDark.nightBlue,
edgeInsets: EdgeInsets.fromLTRB(24, 24, 24, 32),
widget: Form(
key: _formKey,
child: Column(children: <Widget>[
isTemplate
? BaseTextFormField(
controller: _nameController,
hintText: S.of(context).send_name,
borderColor: PaletteDark.lightVioletBlue,
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.white
),
placeholderTextStyle: TextStyle(
color: PaletteDark.darkCyanBlue,
fontWeight: FontWeight.w500,
fontSize: 14),
validator: sendViewModel.templateValidator,
)
: Offstage(),
Padding(
padding: EdgeInsets.only(top: isTemplate ? 20 : 0),
child: AddressTextField(
controller: _addressController,
placeholder: S.of(context).send_address(
sendViewModel.cryptoCurrencyTitle),
focusNode: _focusNode,
onURIScanned: (uri) {
var address = '';
var amount = '';
if (uri != null) {
address = uri.path;
amount = uri.queryParameters['tx_amount'];
} else {
address = uri.toString();
}
_addressController.text = address;
_cryptoAmountController.text = amount;
},
options: [
AddressTextFieldOption.paste,
AddressTextFieldOption.qrCode,
AddressTextFieldOption.addressBook
],
buttonColor: PaletteDark.buttonNightBlue,
borderColor: PaletteDark.lightVioletBlue,
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.white
),
hintStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: PaletteDark.darkCyanBlue
),
validator: sendViewModel.addressValidator,
),
),
Observer(
builder: (_) {
return Padding(
padding: const EdgeInsets.only(top: 20),
child: BaseTextFormField(
controller: _cryptoAmountController,
keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: true),
inputFormatters: [
BlacklistingTextInputFormatter(
RegExp('[\\-|\\ |\\,]'))
],
prefixIcon: Padding(
padding: EdgeInsets.only(top: 9),
child: Text(sendViewModel.currency.title + ':',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.white,
)),
),
suffixIcon: isTemplate
? Offstage()
: Padding(
padding: EdgeInsets.only(bottom: 2),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width/2,
alignment: Alignment.centerLeft,
child: Text(
' / ' + sendViewModel.balance,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14,
color: PaletteDark.darkCyanBlue
)
),
),
Container(
height: 34,
width: 34,
margin: EdgeInsets.only(left: 12, bottom: 8),
decoration: BoxDecoration(
color: PaletteDark.buttonNightBlue,
borderRadius: BorderRadius.all(Radius.circular(6))
),
child: InkWell(
onTap: () => sendViewModel.setSendAll(),
child: Center(
child: Text(S.of(context).all,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: PaletteDark.lightBlueGrey
)
),
),
),
)
],
),
),
hintText: '0.0000',
borderColor: PaletteDark.lightVioletBlue,
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.white
),
placeholderTextStyle: TextStyle(
color: PaletteDark.darkCyanBlue,
fontWeight: FontWeight.w500,
fontSize: 14),
validator: sendViewModel.amountValidator
)
);
}
),
Padding(
padding: const EdgeInsets.only(top: 20),
child: BaseTextFormField(
controller: _fiatAmountController,
keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: true),
inputFormatters: [
BlacklistingTextInputFormatter(
RegExp('[\\-|\\ |\\,]'))
],
prefixIcon: Padding(
padding: EdgeInsets.only(top: 9),
child: Text(
sendViewModel.fiat.title + ':',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.white,
)),
),
hintText: '0.00',
borderColor: PaletteDark.lightVioletBlue,
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24),
content: Column(
children: <Widget>[
TopPanel(
edgeInsets: EdgeInsets.all(0),
gradient: LinearGradient(colors: [
Theme.of(context).primaryTextTheme.subhead.color,
Theme.of(context).primaryTextTheme.subhead.decorationColor,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight),
widget: Form(
key: _formKey,
child: Column(children: <Widget>[
CupertinoNavigationBar(
leading: leading,
middle: middle,
backgroundColor: Colors.transparent,
border: null,
),
Padding(
padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
child: Column(
children: <Widget>[
isTemplate
? BaseTextFormField(
controller: _nameController,
hintText: S.of(context).send_name,
borderColor: Theme.of(context).primaryTextTheme.headline.color,
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.white
),
placeholderTextStyle: TextStyle(
color: PaletteDark.darkCyanBlue,
color: Theme.of(context).primaryTextTheme.headline.decorationColor,
fontWeight: FontWeight.w500,
fontSize: 14),
validator: sendViewModel.templateValidator,
)
),
isTemplate
? Offstage()
: Padding(
padding: const EdgeInsets.only(top: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(S.of(context).send_estimated_fee,
style: TextStyle(
fontSize: 12,
: Offstage(),
Padding(
padding: EdgeInsets.only(top: isTemplate ? 20 : 0),
child: AddressTextField(
controller: _addressController,
placeholder: S.of(context).send_address(
sendViewModel.cryptoCurrencyTitle),
focusNode: _focusNode,
onURIScanned: (uri) {
var address = '';
var amount = '';
if (uri != null) {
address = uri.path;
amount = uri.queryParameters['tx_amount'];
} else {
address = uri.toString();
}
_addressController.text = address;
_cryptoAmountController.text = amount;
},
options: [
AddressTextFieldOption.paste,
AddressTextFieldOption.qrCode,
AddressTextFieldOption.addressBook
],
buttonColor: Theme.of(context).primaryTextTheme.display1.color,
borderColor: Theme.of(context).primaryTextTheme.headline.color,
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.white,
)),
Text(
sendViewModel.estimatedFee.toString() + ' '
+ sendViewModel.currency.title,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Colors.white,
))
],
),
)
]),
),
color: Colors.white
),
hintStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.headline.decorationColor
),
validator: sendViewModel.addressValidator,
),
),
Observer(
builder: (_) {
return Padding(
padding: const EdgeInsets.only(top: 20),
child: BaseTextFormField(
controller: _cryptoAmountController,
keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: true),
inputFormatters: [
BlacklistingTextInputFormatter(
RegExp('[\\-|\\ |\\,]'))
],
prefixIcon: Padding(
padding: EdgeInsets.only(top: 9),
child: Text(sendViewModel.currency.title + ':',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.white,
)),
),
suffixIcon: isTemplate
? Offstage()
: Padding(
padding: EdgeInsets.only(bottom: 2),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width/2,
alignment: Alignment.centerLeft,
child: Text(
' / ' + sendViewModel.balance,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).primaryTextTheme.headline.decorationColor
)
),
),
Container(
height: 34,
width: 34,
margin: EdgeInsets.only(left: 12, bottom: 8),
decoration: BoxDecoration(
color: Theme.of(context).primaryTextTheme.display1.color,
borderRadius: BorderRadius.all(Radius.circular(6))
),
child: InkWell(
onTap: () => sendViewModel.setSendAll(),
child: Center(
child: Text(S.of(context).all,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryTextTheme.display1.decorationColor
)
),
),
),
)
],
),
),
hintText: '0.0000',
borderColor: Theme.of(context).primaryTextTheme.headline.color,
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.white
),
placeholderTextStyle: TextStyle(
color: Theme.of(context).primaryTextTheme.headline.decorationColor,
fontWeight: FontWeight.w500,
fontSize: 14),
validator: sendViewModel.amountValidator
)
);
}
),
Padding(
padding: const EdgeInsets.only(top: 20),
child: BaseTextFormField(
controller: _fiatAmountController,
keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: true),
inputFormatters: [
BlacklistingTextInputFormatter(
RegExp('[\\-|\\ |\\,]'))
],
prefixIcon: Padding(
padding: EdgeInsets.only(top: 9),
child: Text(
sendViewModel.fiat.title + ':',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.white,
)),
),
hintText: '0.00',
borderColor: Theme.of(context).primaryTextTheme.headline.color,
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.white
),
placeholderTextStyle: TextStyle(
color: Theme.of(context).primaryTextTheme.headline.decorationColor,
fontWeight: FontWeight.w500,
fontSize: 14),
)
),
isTemplate
? Offstage()
: Padding(
padding: const EdgeInsets.only(top: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(S.of(context).send_estimated_fee,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.display2.color,
)),
Text(
sendViewModel.estimatedFee.toString() + ' '
+ sendViewModel.currency.title,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Theme.of(context).primaryTextTheme.display2.color,
))
],
),
)
],
),
)
]),
),
isTemplate
? Offstage()
: Padding(
padding: EdgeInsets.only(
top: 30,
left: 24,
bottom: 24
),
),
isTemplate
? Offstage()
: Padding(
padding: EdgeInsets.only(
top: 30,
left: 24,
bottom: 24
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
S.of(context).send_templates,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Theme.of(context).primaryTextTheme.title.color
),
)
],
),
),
isTemplate
? Offstage()
: Container(
height: 40,
width: double.infinity,
padding: EdgeInsets.only(left: 24),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
S.of(context).send_templates,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: PaletteDark.darkCyanBlue
GestureDetector(
onTap: () => Navigator.of(context)
.pushNamed(Routes.sendTemplate),
child: Container(
padding: EdgeInsets.only(left: 1, right: 10),
child: DottedBorder(
borderType: BorderType.RRect,
dashPattern: [6, 4],
color: Theme.of(context).primaryTextTheme.display2.decorationColor,
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: Theme.of(context).primaryTextTheme.display3.color
),
),
)
),
),
),
Observer(
builder: (_) {
final templates = sendViewModel.templates;
final itemCount = templates.length;
return ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: itemCount,
itemBuilder: (context, index) {
final template = templates[index];
return TemplateTile(
key: UniqueKey(),
to: template.name,
amount: template.amount,
from: template.cryptoCurrency,
onTap: () {
_addressController.text = template.address;
_cryptoAmountController.text = template.amount;
getOpenaliasRecord(context);
},
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();
sendViewModel.sendTemplateStore.remove(template: template);
sendViewModel.sendTemplateStore.update();
},
actionRightButton: () => Navigator.of(dialogContext).pop()
);
}
);
},
);
}
);
}
)
],
),
),
isTemplate
? Offstage()
: Container(
height: 40,
width: double.infinity,
padding: EdgeInsets.only(left: 24),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
GestureDetector(
onTap: () => Navigator.of(context)
.pushNamed(Routes.sendTemplate),
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 = sendViewModel.templates;
final itemCount = templates.length;
return ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: itemCount,
itemBuilder: (context, index) {
final template = templates[index];
return TemplateTile(
key: UniqueKey(),
to: template.name,
amount: template.amount,
from: template.cryptoCurrency,
onTap: () {
_addressController.text = template.address;
_cryptoAmountController.text = template.amount;
getOpenaliasRecord(context);
},
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();
sendViewModel.sendTemplateStore.remove(template: template);
sendViewModel.sendTemplateStore.update();
},
actionRightButton: () => Navigator.of(dialogContext).pop()
);
}
);
},
);
}
);
}
)
],
),
),
)
],
),
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: isTemplate
? PrimaryButton(
)
],
),
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: isTemplate
? PrimaryButton(
onPressed: () {
if (_formKey.currentState.validate()) {
sendViewModel.sendTemplateStore.addTemplate(
name: _nameController.text,
address: _addressController.text,
cryptoCurrency: sendViewModel.currency.title,
amount: _cryptoAmountController.text
);
sendViewModel.sendTemplateStore.update();
Navigator.of(context).pop();
}
},
text: S.of(context).save,
color: Colors.green,
textColor: Colors.white)
: Observer(builder: (_) {
return LoadingPrimaryButton(
onPressed: () {
if (_formKey.currentState.validate()) {
sendViewModel.sendTemplateStore.addTemplate(
name: _nameController.text,
address: _addressController.text,
cryptoCurrency: sendViewModel.currency.title,
amount: _cryptoAmountController.text
);
sendViewModel.sendTemplateStore.update();
Navigator.of(context).pop();
print('SENT!!!');
}
},
text: S.of(context).save,
color: Colors.green,
textColor: Colors.white)
: Observer(builder: (_) {
return LoadingPrimaryButton(
onPressed: () {
if (_formKey.currentState.validate()) {
print('SENT!!!');
}
},
text: S.of(context).send,
color: Colors.blue,
textColor: Colors.white,
isLoading: sendViewModel.state is TransactionIsCreating ||
sendViewModel.state is TransactionCommitting,
isDisabled:
false // FIXME !(syncStore.status is SyncedSyncStatus),
);
}),
),
text: S.of(context).send,
color: Palette.blueCraiola,
textColor: Colors.white,
isLoading: sendViewModel.state is TransactionIsCreating ||
sendViewModel.state is TransactionCommitting,
isDisabled:
false // FIXME !(syncStore.status is SyncedSyncStatus),
);
}),
);
}

View file

@ -112,7 +112,9 @@ class AddressTextField extends StatelessWidget {
borderRadius:
BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/duplicate.png')),
'assets/images/duplicate.png',
color: Theme.of(context).primaryTextTheme.display1.decorationColor,
)),
)),
],
if (this.options.contains(AddressTextFieldOption.qrCode)) ...[
@ -128,7 +130,9 @@ class AddressTextField extends StatelessWidget {
color: buttonColor ?? Theme.of(context).accentTextTheme.title.color,
borderRadius:
BorderRadius.all(Radius.circular(6))),
child: Image.asset('assets/images/qr_code_icon.png')),
child: Image.asset('assets/images/qr_code_icon.png',
color: Theme.of(context).primaryTextTheme.display1.decorationColor,
)),
))
],
if (this
@ -147,7 +151,9 @@ class AddressTextField extends StatelessWidget {
borderRadius:
BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/open_book.png')),
'assets/images/open_book.png',
color: Theme.of(context).primaryTextTheme.display1.decorationColor,
)),
))
],
if (this
@ -166,7 +172,9 @@ class AddressTextField extends StatelessWidget {
borderRadius:
BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/receive_icon_raw.png')),
'assets/images/receive_icon_raw.png',
color: Theme.of(context).primaryTextTheme.display1.decorationColor,
)),
)),
],
],

View file

@ -47,8 +47,7 @@ class TemplateTileState extends State<TemplateTile> {
@override
Widget build(BuildContext context) {
//final color = isRemovable ? Colors.white : Theme.of(context).primaryTextTheme.title.color;
final color = Colors.white;
final color = isRemovable ? Colors.white : Theme.of(context).primaryTextTheme.title.color;
final toIcon = Image.asset('assets/images/to_icon.png', color: color);
final content = Row(
@ -106,7 +105,7 @@ class TemplateTileState extends State<TemplateTile> {
child: Container(
height: 40,
padding: EdgeInsets.only(left: 24, right: 24),
color: PaletteDark.darkVioletBlue,
color: Theme.of(context).primaryTextTheme.display3.decorationColor,
child: content,
),
),

View file

@ -2,25 +2,28 @@ import 'package:flutter/material.dart';
class TopPanel extends StatefulWidget {
TopPanel({
@required this.color,
@required this.widget,
this.edgeInsets = const EdgeInsets.all(24)
this.edgeInsets = const EdgeInsets.all(24),
this.color,
this.gradient
});
final Color color;
final Widget widget;
final EdgeInsets edgeInsets;
final Gradient gradient;
@override
TopPanelState createState() => TopPanelState(color, widget, edgeInsets);
TopPanelState createState() => TopPanelState(widget, edgeInsets, color, gradient);
}
class TopPanelState extends State<TopPanel> {
TopPanelState(this._color, this._widget, this._edgeInsets);
TopPanelState(this._widget, this._edgeInsets, this._color, this._gradient);
final Color _color;
final Widget _widget;
final EdgeInsets _edgeInsets;
final Gradient _gradient;
@override
Widget build(BuildContext context) {
@ -32,7 +35,8 @@ class TopPanelState extends State<TopPanel> {
bottomLeft: Radius.circular(24),
bottomRight: Radius.circular(24)
),
color: _color
color: _color,
gradient: _gradient
),
child: _widget,
);

View file

@ -0,0 +1,13 @@
import 'package:cake_wallet/theme_changer.dart';
import 'package:mobx/mobx.dart';
part 'theme_changer_store.g.dart';
class ThemeChangerStore = ThemeChangerStoreBase with _$ThemeChangerStore;
abstract class ThemeChangerStoreBase with Store {
ThemeChangerStoreBase({this.themeChanger});
@observable
ThemeChanger themeChanger;
}

View file

@ -80,25 +80,35 @@ class Themes {
color: Palette.darkGray, // transaction/trade details titles
decorationColor: Colors.white.withOpacity(0.5), // placeholder
),
subhead: TextStyle(
color: Colors.white.withOpacity(0.5) // send, exchange, buy buttons on dashboard page
color: Palette.blueCraiola, // first gradient color (send page)
decorationColor: Palette.pinkFlamingo // second gradient color (send page)
),
headline: TextStyle(
color: Palette.lightBlueGrey // historyPanelText
color: Colors.white.withOpacity(0.5), // text field border color (send page)
decorationColor: Colors.white.withOpacity(0.5), // text field hint color (send page)
),
display1: TextStyle(
color: Colors.white // menuList
color: Colors.white.withOpacity(0.2), // text field button color (send page)
decorationColor: Colors.white // text field button icon color (send page)
),
display2: TextStyle(
color: Palette.lavender // menuHeader
color: Colors.white.withOpacity(0.5), // estimated fee (send page)
decorationColor: Palette.shadowWhite // template dotted border (send page)
),
display3: TextStyle(
color: Palette.lavender // historyPanelButton
color: Palette.darkBlueCraiola, // template new text (send page)
decorationColor: Palette.shadowWhite // template background color (send page)
),
display4: TextStyle(
color: Palette.oceanBlue // QR code
),
@ -182,7 +192,7 @@ class Themes {
decorationColor: PaletteDark.nightBlue // background of tiles (receive page)
),
display3: TextStyle(
color: Colors.blue, // text color of current tile (receive page)
color: Palette.blueCraiola, // text color of current tile (receive page)
decorationColor: PaletteDark.lightOceanBlue // background of current tile (receive page)
),
display4: TextStyle(
@ -215,24 +225,29 @@ class Themes {
color: PaletteDark.lightBlueGrey, // transaction/trade details titles
decorationColor: Colors.grey, // placeholder
),
subhead: TextStyle(
color: PaletteDark.lightDistantBlue // send, exchange, buy buttons on dashboard page
color: PaletteDark.darkNightBlue, // first gradient color (send page)
decorationColor: PaletteDark.darkNightBlue // second gradient color (send page)
),
headline: TextStyle(
color: PaletteDark.pigeonBlue // historyPanelText
color: PaletteDark.lightVioletBlue, // text field border color (send page)
decorationColor: PaletteDark.darkCyanBlue, // text field hint color (send page)
),
display1: TextStyle(
color: PaletteDark.lightNightBlue // menuList
color: PaletteDark.buttonNightBlue, // text field button color (send page)
decorationColor: PaletteDark.gray // text field button icon color (send page)
),
display2: TextStyle(
color: PaletteDark.headerNightBlue // menuHeader
color: Colors.white, // estimated fee (send page)
decorationColor: PaletteDark.darkCyanBlue // template dotted border (send page)
),
display3: TextStyle(
color: PaletteDark.moderateNightBlue // historyPanelButton
color: PaletteDark.darkCyanBlue, // template new text (send page)
decorationColor: PaletteDark.darkVioletBlue // template background color (send page)
),
display4: TextStyle(
color: PaletteDark.gray // QR code
),

View file

@ -1,3 +1,6 @@
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/store/theme_changer_store.dart';
import 'package:cake_wallet/themes.dart';
import 'package:flutter/cupertino.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/routes.dart';
@ -69,7 +72,9 @@ abstract class SettingsViewModelBase with Store {
title: S.current.settings_dark_mode,
value: () => _settingsStore.isDarkTheme,
onValueChange: (bool value) {
// FIXME: Implement me
_settingsStore.isDarkTheme = value;
getIt.get<ThemeChangerStore>().themeChanger.setTheme(
value ? Themes.darkTheme : Themes.lightTheme);
})
],
[