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/send/send_page.dart';
import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_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/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/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_list_view_model.dart';
import 'package:cake_wallet/view_model/contact_list/contact_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'; import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
@ -318,3 +320,8 @@ Future setup(
getIt.registerFactory(() => getIt.registerFactory(() =>
ExchangeTemplatePage(getIt.get<ExchangeViewModel>())); 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/reactions/bootstrap.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet_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/domain/common/language.dart';
import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart'; import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart';
bool isThemeChangerRegistered = false;
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
@ -197,7 +200,8 @@ class CakeWalletApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { 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>( return ChangeNotifierProvider<ThemeChanger>(
create: (_) => ThemeChanger( create: (_) => ThemeChanger(
@ -228,12 +232,20 @@ class MaterialAppWithTheme extends StatelessWidget {
final transactionDescriptions = final transactionDescriptions =
Provider.of<Box<TransactionDescription>>(context); Provider.of<Box<TransactionDescription>>(context);
final statusBarColor = if (!isThemeChangerRegistered) {
settingsStore.isDarkTheme ? Colors.black : Colors.white; setupThemeChangerStore(theme);
isThemeChangerRegistered = true;
}
/*final statusBarColor =
settingsStore.isDarkTheme ? Colors.black : Colors.white;*/
final _settingsStore = getIt.get<AppStore>().settingsStore;
final statusBarColor = Colors.transparent;
final statusBarBrightness = final statusBarBrightness =
settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; _settingsStore.isDarkTheme ? Brightness.light : Brightness.dark;
final statusBarIconBrightness = final statusBarIconBrightness =
settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; _settingsStore.isDarkTheme ? Brightness.light : Brightness.dark;
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: statusBarColor, statusBarColor: statusBarColor,

View file

@ -29,6 +29,7 @@ class Palette {
static const Color gray = Color.fromRGBO(112, 147, 186, 1.0); 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 wildPeriwinkle = Color.fromRGBO(219, 227, 243, 1.0);
static const Color darkGray = Color.fromRGBO(122, 147, 186, 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. // FIXME: Rename.
static const Color eee = Color.fromRGBO(236, 239, 245, 1.0); 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:flutter/material.dart';
import 'package:cake_wallet/src/domain/common/wallet_type.dart'; import 'package:cake_wallet/src/domain/common/wallet_type.dart';
import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart'; import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart';
import 'package:flutter/rendering.dart';
class MenuWidget extends StatefulWidget { class MenuWidget extends StatefulWidget {
MenuWidget({this.type, this.name, this.subname}); MenuWidget({this.type, this.name, this.subname});
@ -23,7 +24,6 @@ class MenuWidgetState extends State<MenuWidget> {
double menuWidth; double menuWidth;
double screenWidth; double screenWidth;
double screenHeight; double screenHeight;
double opacity;
double headerHeight; double headerHeight;
double tileHeight; double tileHeight;
@ -35,11 +35,10 @@ class MenuWidgetState extends State<MenuWidget> {
menuWidth = 0; menuWidth = 0;
screenWidth = 0; screenWidth = 0;
screenHeight = 0; screenHeight = 0;
opacity = 0;
headerHeight = 125; headerHeight = 125;
tileHeight = 75; tileHeight = 75;
fromTopEdge = 50; fromTopEdge = 30;
fromBottomEdge = 21; fromBottomEdge = 21;
super.initState(); super.initState();
@ -52,7 +51,6 @@ class MenuWidgetState extends State<MenuWidget> {
setState(() { setState(() {
menuWidth = screenWidth; menuWidth = screenWidth;
opacity = 1;
if (screenHeight > largeScreen) { if (screenHeight > largeScreen) {
final scale = screenHeight / largeScreen; final scale = screenHeight / largeScreen;
@ -69,41 +67,43 @@ class MenuWidgetState extends State<MenuWidget> {
final walletMenu = WalletMenu(context); final walletMenu = WalletMenu(context);
final itemCount = walletMenu.items.length; final itemCount = walletMenu.items.length;
return SafeArea( return Row(
child: Row( mainAxisSize: MainAxisSize.max,
mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[
children: <Widget>[ Padding(
Padding(
padding: EdgeInsets.only(left: 24), padding: EdgeInsets.only(left: 24),
child: Container( child: Container(
height: 60, height: 60,
width: 4, width: 4,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(2)), borderRadius: BorderRadius.all(Radius.circular(2)),
color: PaletteDark.gray), color: PaletteDark.gray),
)), )),
SizedBox(width: 12), SizedBox(width: 12),
Expanded( Expanded(
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(24), topLeft: Radius.circular(24),
bottomLeft: Radius.circular(24)), bottomLeft: Radius.circular(24)),
child: Container( child: Container(
width: menuWidth, width: menuWidth,
height: double.infinity, height: double.infinity,
color: Theme.of(context).textTheme.body2.decorationColor, color: Theme.of(context).textTheme.body2.color,
child: SingleChildScrollView( alignment: Alignment.topCenter,
child: Column( child: ListView.separated(
children: <Widget>[ itemBuilder: (_, index) {
Container(
if (index == 0) {
return Container(
height: headerHeight, height: headerHeight,
color: Theme.of(context).textTheme.body2.color, color: Theme.of(context).textTheme.body2.color,
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: 24, left: 24,
top: fromTopEdge, top: fromTopEdge,
right: 24, right: 24,
bottom: fromBottomEdge), bottom: fromBottomEdge
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[ 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]; index--;
final image = walletMenu.images[index] ?? Offstage();
final isLastTile = index == itemCount - 1;
return GestureDetector( final item = walletMenu.items[index];
onTap: () { final image = walletMenu.images[index] ?? Offstage();
Navigator.of(context).pop(); final isLastTile = index == itemCount - 1;
walletMenu.action(index);
}, return GestureDetector(
child: Container( onTap: () {
height: isLastTile Navigator.of(context).pop();
? headerHeight walletMenu.action(index);
: tileHeight, },
padding: isLastTile child: Container(
? EdgeInsets.only( color: Theme.of(context).textTheme.body2.decorationColor,
left: 24, height: isLastTile
right: 24, ? headerHeight
top: fromBottomEdge, : tileHeight,
bottom: fromTopEdge) padding: isLastTile
: EdgeInsets.only(left: 24, right: 24), ? EdgeInsets.only(
alignment: isLastTile ? Alignment.topLeft : null, left: 24,
child: Row( right: 24,
mainAxisAlignment: MainAxisAlignment.start, top: fromBottomEdge,
crossAxisAlignment: CrossAxisAlignment.center, //bottom: fromTopEdge
children: <Widget>[ )
image, : EdgeInsets.only(left: 24, right: 24),
SizedBox(width: 16), alignment: isLastTile ? Alignment.topLeft : null,
Expanded( child: Row(
child: Text( mainAxisAlignment: MainAxisAlignment.start,
item, crossAxisAlignment: CrossAxisAlignment.center,
style: TextStyle( children: <Widget>[
color: Theme.of(context).textTheme image,
.display2.color, SizedBox(width: 16),
fontSize: 16, Expanded(
fontWeight: FontWeight.bold), 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,
), ),
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:cake_wallet/view_model/send_view_model.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.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/base_page.dart';
import 'package:cake_wallet/src/screens/send/widgets/base_send_widget.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; String get title => sendViewModel.pageTitle;
@override @override
Color get backgroundLightColor => PaletteDark.nightBlue; Color get titleColor => Colors.white;
@override @override
Color get backgroundDarkColor => PaletteDark.nightBlue; Color get backgroundLightColor => Colors.transparent;
@override
Color get backgroundDarkColor => Colors.transparent;
@override @override
bool get resizeToAvoidBottomPadding => false; bool get resizeToAvoidBottomPadding => false;
@override @override
Widget body(BuildContext context) => 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/cupertino.dart';
import 'package:flutter/material.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/base_page.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/view_model/send_view_model.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; String get title => S.current.exchange_new_template;
@override @override
Color get backgroundLightColor => PaletteDark.nightBlue; Color get titleColor => Colors.white;
@override @override
Color get backgroundDarkColor => PaletteDark.nightBlue; Color get backgroundLightColor => Colors.transparent;
@override
Color get backgroundDarkColor => Colors.transparent;
@override @override
bool get resizeToAvoidBottomPadding => false; bool get resizeToAvoidBottomPadding => false;
@override @override
Widget body(BuildContext context) => 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 { class BaseSendWidget extends StatelessWidget {
BaseSendWidget({ BaseSendWidget({
@required this.sendViewModel, @required this.sendViewModel,
@required this.leading,
@required this.middle,
this.isTemplate = false this.isTemplate = false
}); });
final SendViewModel sendViewModel; final SendViewModel sendViewModel;
final bool isTemplate; final bool isTemplate;
final Widget leading;
final Widget middle;
final _addressController = TextEditingController(); final _addressController = TextEditingController();
final _cryptoAmountController = TextEditingController(); final _cryptoAmountController = TextEditingController();
@ -42,371 +46,386 @@ class BaseSendWidget extends StatelessWidget {
_setEffects(context); _setEffects(context);
return Container( return ScrollableWithBottomSection(
color: PaletteDark.backgroundColor, contentPadding: EdgeInsets.only(bottom: 24),
child: ScrollableWithBottomSection( content: Column(
contentPadding: EdgeInsets.only(bottom: 24), children: <Widget>[
content: Column( TopPanel(
children: <Widget>[ edgeInsets: EdgeInsets.all(0),
TopPanel( gradient: LinearGradient(colors: [
color: PaletteDark.nightBlue, Theme.of(context).primaryTextTheme.subhead.color,
edgeInsets: EdgeInsets.fromLTRB(24, 24, 24, 32), Theme.of(context).primaryTextTheme.subhead.decorationColor,
widget: Form( ],
key: _formKey, begin: Alignment.topLeft,
child: Column(children: <Widget>[ end: Alignment.bottomRight),
isTemplate widget: Form(
? BaseTextFormField( key: _formKey,
controller: _nameController, child: Column(children: <Widget>[
hintText: S.of(context).send_name, CupertinoNavigationBar(
borderColor: PaletteDark.lightVioletBlue, leading: leading,
textStyle: TextStyle( middle: middle,
fontSize: 14, backgroundColor: Colors.transparent,
fontWeight: FontWeight.w500, border: null,
color: Colors.white ),
), Padding(
placeholderTextStyle: TextStyle( padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
color: PaletteDark.darkCyanBlue, child: Column(
fontWeight: FontWeight.w500, children: <Widget>[
fontSize: 14), isTemplate
validator: sendViewModel.templateValidator, ? BaseTextFormField(
) controller: _nameController,
: Offstage(), hintText: S.of(context).send_name,
Padding( borderColor: Theme.of(context).primaryTextTheme.headline.color,
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,
textStyle: TextStyle( textStyle: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Colors.white color: Colors.white
), ),
placeholderTextStyle: TextStyle( placeholderTextStyle: TextStyle(
color: PaletteDark.darkCyanBlue, color: Theme.of(context).primaryTextTheme.headline.decorationColor,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
fontSize: 14), fontSize: 14),
validator: sendViewModel.templateValidator,
) )
), : Offstage(),
isTemplate Padding(
? Offstage() padding: EdgeInsets.only(top: isTemplate ? 20 : 0),
: Padding( child: AddressTextField(
padding: const EdgeInsets.only(top: 24), controller: _addressController,
child: Row( placeholder: S.of(context).send_address(
mainAxisAlignment: MainAxisAlignment.spaceBetween, sendViewModel.cryptoCurrencyTitle),
children: <Widget>[ focusNode: _focusNode,
Text(S.of(context).send_estimated_fee, onURIScanned: (uri) {
style: TextStyle( var address = '';
fontSize: 12, 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, fontWeight: FontWeight.w500,
color: Colors.white, color: Colors.white
)), ),
Text( hintStyle: TextStyle(
sendViewModel.estimatedFee.toString() + ' ' fontSize: 14,
+ sendViewModel.currency.title, fontWeight: FontWeight.w500,
style: TextStyle( color: Theme.of(context).primaryTextTheme.headline.decorationColor
fontSize: 12, ),
fontWeight: FontWeight.w600, validator: sendViewModel.addressValidator,
color: Colors.white, ),
)) ),
], 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() isTemplate
: Padding( ? Offstage()
padding: EdgeInsets.only( : Padding(
top: 30, padding: EdgeInsets.only(
left: 24, top: 30,
bottom: 24 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( child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Text( GestureDetector(
S.of(context).send_templates, onTap: () => Navigator.of(context)
style: TextStyle( .pushNamed(Routes.sendTemplate),
fontSize: 18, child: Container(
fontWeight: FontWeight.w600, padding: EdgeInsets.only(left: 1, right: 10),
color: PaletteDark.darkCyanBlue 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, bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
width: double.infinity, bottomSection: isTemplate
padding: EdgeInsets.only(left: 24), ? PrimaryButton(
child: SingleChildScrollView( onPressed: () {
scrollDirection: Axis.horizontal, if (_formKey.currentState.validate()) {
child: Row( sendViewModel.sendTemplateStore.addTemplate(
children: <Widget>[ name: _nameController.text,
GestureDetector( address: _addressController.text,
onTap: () => Navigator.of(context) cryptoCurrency: sendViewModel.currency.title,
.pushNamed(Routes.sendTemplate), amount: _cryptoAmountController.text
child: Container( );
padding: EdgeInsets.only(left: 1, right: 10), sendViewModel.sendTemplateStore.update();
child: DottedBorder( Navigator.of(context).pop();
borderType: BorderType.RRect, }
dashPattern: [6, 4], },
color: PaletteDark.darkCyanBlue, text: S.of(context).save,
strokeWidth: 2, color: Colors.green,
radius: Radius.circular(20), textColor: Colors.white)
child: Container( : Observer(builder: (_) {
height: 34, return LoadingPrimaryButton(
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(
onPressed: () { onPressed: () {
if (_formKey.currentState.validate()) { if (_formKey.currentState.validate()) {
sendViewModel.sendTemplateStore.addTemplate( print('SENT!!!');
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, text: S.of(context).send,
color: Colors.green, color: Palette.blueCraiola,
textColor: Colors.white) textColor: Colors.white,
: Observer(builder: (_) { isLoading: sendViewModel.state is TransactionIsCreating ||
return LoadingPrimaryButton( sendViewModel.state is TransactionCommitting,
onPressed: () { isDisabled:
if (_formKey.currentState.validate()) { false // FIXME !(syncStore.status is SyncedSyncStatus),
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),
);
}),
),
); );
} }

View file

@ -112,7 +112,9 @@ class AddressTextField extends StatelessWidget {
borderRadius: borderRadius:
BorderRadius.all(Radius.circular(6))), BorderRadius.all(Radius.circular(6))),
child: Image.asset( child: Image.asset(
'assets/images/duplicate.png')), 'assets/images/duplicate.png',
color: Theme.of(context).primaryTextTheme.display1.decorationColor,
)),
)), )),
], ],
if (this.options.contains(AddressTextFieldOption.qrCode)) ...[ if (this.options.contains(AddressTextFieldOption.qrCode)) ...[
@ -128,7 +130,9 @@ class AddressTextField extends StatelessWidget {
color: buttonColor ?? Theme.of(context).accentTextTheme.title.color, color: buttonColor ?? Theme.of(context).accentTextTheme.title.color,
borderRadius: borderRadius:
BorderRadius.all(Radius.circular(6))), 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 if (this
@ -147,7 +151,9 @@ class AddressTextField extends StatelessWidget {
borderRadius: borderRadius:
BorderRadius.all(Radius.circular(6))), BorderRadius.all(Radius.circular(6))),
child: Image.asset( child: Image.asset(
'assets/images/open_book.png')), 'assets/images/open_book.png',
color: Theme.of(context).primaryTextTheme.display1.decorationColor,
)),
)) ))
], ],
if (this if (this
@ -166,7 +172,9 @@ class AddressTextField extends StatelessWidget {
borderRadius: borderRadius:
BorderRadius.all(Radius.circular(6))), BorderRadius.all(Radius.circular(6))),
child: Image.asset( 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
//final color = isRemovable ? Colors.white : Theme.of(context).primaryTextTheme.title.color; final color = isRemovable ? Colors.white : Theme.of(context).primaryTextTheme.title.color;
final color = Colors.white;
final toIcon = Image.asset('assets/images/to_icon.png', color: color); final toIcon = Image.asset('assets/images/to_icon.png', color: color);
final content = Row( final content = Row(
@ -106,7 +105,7 @@ class TemplateTileState extends State<TemplateTile> {
child: Container( child: Container(
height: 40, height: 40,
padding: EdgeInsets.only(left: 24, right: 24), padding: EdgeInsets.only(left: 24, right: 24),
color: PaletteDark.darkVioletBlue, color: Theme.of(context).primaryTextTheme.display3.decorationColor,
child: content, child: content,
), ),
), ),

View file

@ -2,25 +2,28 @@ import 'package:flutter/material.dart';
class TopPanel extends StatefulWidget { class TopPanel extends StatefulWidget {
TopPanel({ TopPanel({
@required this.color,
@required this.widget, @required this.widget,
this.edgeInsets = const EdgeInsets.all(24) this.edgeInsets = const EdgeInsets.all(24),
this.color,
this.gradient
}); });
final Color color; final Color color;
final Widget widget; final Widget widget;
final EdgeInsets edgeInsets; final EdgeInsets edgeInsets;
final Gradient gradient;
@override @override
TopPanelState createState() => TopPanelState(color, widget, edgeInsets); TopPanelState createState() => TopPanelState(widget, edgeInsets, color, gradient);
} }
class TopPanelState extends State<TopPanel> { 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 Color _color;
final Widget _widget; final Widget _widget;
final EdgeInsets _edgeInsets; final EdgeInsets _edgeInsets;
final Gradient _gradient;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -32,7 +35,8 @@ class TopPanelState extends State<TopPanel> {
bottomLeft: Radius.circular(24), bottomLeft: Radius.circular(24),
bottomRight: Radius.circular(24) bottomRight: Radius.circular(24)
), ),
color: _color color: _color,
gradient: _gradient
), ),
child: _widget, 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 color: Palette.darkGray, // transaction/trade details titles
decorationColor: Colors.white.withOpacity(0.5), // placeholder decorationColor: Colors.white.withOpacity(0.5), // placeholder
), ),
subhead: TextStyle( 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( 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( 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( 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( display3: TextStyle(
color: Palette.lavender // historyPanelButton color: Palette.darkBlueCraiola, // template new text (send page)
decorationColor: Palette.shadowWhite // template background color (send page)
), ),
display4: TextStyle( display4: TextStyle(
color: Palette.oceanBlue // QR code color: Palette.oceanBlue // QR code
), ),
@ -182,7 +192,7 @@ class Themes {
decorationColor: PaletteDark.nightBlue // background of tiles (receive page) decorationColor: PaletteDark.nightBlue // background of tiles (receive page)
), ),
display3: TextStyle( 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) decorationColor: PaletteDark.lightOceanBlue // background of current tile (receive page)
), ),
display4: TextStyle( display4: TextStyle(
@ -215,24 +225,29 @@ class Themes {
color: PaletteDark.lightBlueGrey, // transaction/trade details titles color: PaletteDark.lightBlueGrey, // transaction/trade details titles
decorationColor: Colors.grey, // placeholder decorationColor: Colors.grey, // placeholder
), ),
subhead: TextStyle( 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( 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( 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( display2: TextStyle(
color: PaletteDark.headerNightBlue // menuHeader color: Colors.white, // estimated fee (send page)
decorationColor: PaletteDark.darkCyanBlue // template dotted border (send page)
), ),
display3: TextStyle( display3: TextStyle(
color: PaletteDark.moderateNightBlue // historyPanelButton color: PaletteDark.darkCyanBlue, // template new text (send page)
decorationColor: PaletteDark.darkVioletBlue // template background color (send page)
), ),
display4: TextStyle( display4: TextStyle(
color: PaletteDark.gray // QR code 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:flutter/cupertino.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
@ -69,7 +72,9 @@ abstract class SettingsViewModelBase with Store {
title: S.current.settings_dark_mode, title: S.current.settings_dark_mode,
value: () => _settingsStore.isDarkTheme, value: () => _settingsStore.isDarkTheme,
onValueChange: (bool value) { onValueChange: (bool value) {
// FIXME: Implement me _settingsStore.isDarkTheme = value;
getIt.get<ThemeChangerStore>().themeChanger.setTheme(
value ? Themes.darkTheme : Themes.lightTheme);
}) })
], ],
[ [