Merge branch 'CW-301-desktop-side-bar-ui' of https://github.com/cake-tech/cake_wallet into CW-311-remove-drawer-from-mac-os

This commit is contained in:
OmarHatem 2023-02-11 00:48:16 +02:00
commit 10b877f55e
9 changed files with 562 additions and 554 deletions

View file

@ -445,7 +445,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
)); ));
case Routes.ioniaWelcomePage: case Routes.ioniaWelcomePage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaWelcomePage>()); return CupertinoPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<IoniaWelcomePage>(),
);
case Routes.ioniaLoginPage: case Routes.ioniaLoginPage:
return CupertinoPageRoute<void>( builder: (_) => getIt.get<IoniaLoginPage>()); return CupertinoPageRoute<void>( builder: (_) => getIt.get<IoniaLoginPage>());

View file

@ -1,7 +1,9 @@
import 'package:cake_wallet/entities/main_actions.dart'; import 'package:cake_wallet/entities/main_actions.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_action_button.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_action_button.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class DesktopDashboardActions extends StatelessWidget { class DesktopDashboardActions extends StatelessWidget {
final DashboardViewModel dashboardViewModel; final DashboardViewModel dashboardViewModel;
@ -10,62 +12,69 @@ class DesktopDashboardActions extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Observer(
children: [ builder: (_) {
const SizedBox(height: 16), return Column(
DesktopActionButton(
title: MainActions.exchangeAction.name(context),
image: MainActions.exchangeAction.image,
canShow: MainActions.exchangeAction.canShow?.call(dashboardViewModel),
isEnabled: MainActions.exchangeAction.isEnabled?.call(dashboardViewModel),
onTap: () async => await MainActions.exchangeAction.onTap(context, dashboardViewModel),
),
Row(
children: [ children: [
Expanded( const SizedBox(height: 16),
child: DesktopActionButton( DesktopActionButton(
title: MainActions.receiveAction.name(context), title: MainActions.exchangeAction.name(context),
image: MainActions.receiveAction.image, image: MainActions.exchangeAction.image,
canShow: MainActions.receiveAction.canShow?.call(dashboardViewModel), canShow: MainActions.exchangeAction.canShow?.call(dashboardViewModel),
isEnabled: MainActions.receiveAction.isEnabled?.call(dashboardViewModel), isEnabled: MainActions.exchangeAction.isEnabled?.call(dashboardViewModel),
onTap: () async => onTap: () async => await MainActions.exchangeAction.onTap(context, dashboardViewModel),
await MainActions.receiveAction.onTap(context, dashboardViewModel), ),
), Row(
children: [
Expanded(
child: DesktopActionButton(
title: MainActions.receiveAction.name(context),
image: MainActions.receiveAction.image,
canShow: MainActions.receiveAction.canShow?.call(dashboardViewModel),
isEnabled: MainActions.receiveAction.isEnabled?.call(dashboardViewModel),
onTap: () async =>
await MainActions.receiveAction.onTap(context, dashboardViewModel),
),
),
Expanded(
child: DesktopActionButton(
title: MainActions.sendAction.name(context),
image: MainActions.sendAction.image,
canShow: MainActions.sendAction.canShow?.call(dashboardViewModel),
isEnabled: MainActions.sendAction.isEnabled?.call(dashboardViewModel),
onTap: () async => await MainActions.sendAction.onTap(context, dashboardViewModel),
),
),
],
),
Row(
children: [
Expanded(
child: DesktopActionButton(
title: MainActions.buyAction.name(context),
image: MainActions.buyAction.image,
canShow: MainActions.buyAction.canShow?.call(dashboardViewModel),
isEnabled: MainActions.buyAction.isEnabled?.call(dashboardViewModel),
onTap: () async => await MainActions.buyAction.onTap(context, dashboardViewModel),
),
),
Expanded(
child: DesktopActionButton(
title: MainActions.sellAction.name(context),
image: MainActions.sellAction.image,
canShow: MainActions.sellAction.canShow?.call(dashboardViewModel),
isEnabled: MainActions.sellAction.isEnabled?.call(dashboardViewModel),
onTap: () async => await MainActions.sellAction.onTap(context, dashboardViewModel),
),
),
],
), ),
Expanded( Expanded(
child: DesktopActionButton( child: MarketPlacePage(dashboardViewModel: dashboardViewModel),
title: MainActions.sendAction.name(context),
image: MainActions.sendAction.image,
canShow: MainActions.sendAction.canShow?.call(dashboardViewModel),
isEnabled: MainActions.sendAction.isEnabled?.call(dashboardViewModel),
onTap: () async => await MainActions.sendAction.onTap(context, dashboardViewModel),
),
), ),
], ],
), );
Row( }
children: [
Expanded(
child: DesktopActionButton(
title: MainActions.buyAction.name(context),
image: MainActions.buyAction.image,
canShow: MainActions.buyAction.canShow?.call(dashboardViewModel),
isEnabled: MainActions.buyAction.isEnabled?.call(dashboardViewModel),
onTap: () async => await MainActions.buyAction.onTap(context, dashboardViewModel),
),
),
Expanded(
child: DesktopActionButton(
title: MainActions.sellAction.name(context),
image: MainActions.sellAction.image,
canShow: MainActions.sellAction.canShow?.call(dashboardViewModel),
isEnabled: MainActions.sellAction.isEnabled?.call(dashboardViewModel),
onTap: () async => await MainActions.sellAction.onTap(context, dashboardViewModel),
),
),
],
),
],
); );
} }
} }

View file

@ -1,6 +1,7 @@
import 'package:cake_wallet/entities/generate_name.dart'; import 'package:cake_wallet/entities/generate_name.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
@ -24,18 +25,14 @@ class NewWalletPage extends BasePage {
final walletNameImage = Image.asset('assets/images/wallet_name.png'); final walletNameImage = Image.asset('assets/images/wallet_name.png');
final walletNameLightImage = final walletNameLightImage = Image.asset('assets/images/wallet_name_light.png');
Image.asset('assets/images/wallet_name_light.png');
@override @override
String get title => S.current.new_wallet; String get title => S.current.new_wallet;
@override @override
Widget body(BuildContext context) => WalletNameForm( Widget body(BuildContext context) => WalletNameForm(
_walletNewVM, _walletNewVM, currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage);
currentTheme.type == ThemeType.dark
? walletNameImage
: walletNameLightImage);
} }
class WalletNameForm extends StatefulWidget { class WalletNameForm extends StatefulWidget {
@ -50,9 +47,9 @@ class WalletNameForm extends StatefulWidget {
class _WalletNameFormState extends State<WalletNameForm> { class _WalletNameFormState extends State<WalletNameForm> {
_WalletNameFormState(this._walletNewVM) _WalletNameFormState(this._walletNewVM)
: _formKey = GlobalKey<FormState>(), : _formKey = GlobalKey<FormState>(),
_languageSelectorKey = GlobalKey<SeedLanguageSelectorState>(), _languageSelectorKey = GlobalKey<SeedLanguageSelectorState>(),
_controller = TextEditingController(); _controller = TextEditingController();
static const aspectRatioImage = 1.22; static const aspectRatioImage = 1.22;
@ -64,11 +61,9 @@ class _WalletNameFormState extends State<WalletNameForm> {
@override @override
void initState() { void initState() {
_stateReaction ??= _stateReaction ??= reaction((_) => _walletNewVM.state, (ExecutionState state) {
reaction((_) => _walletNewVM.state, (ExecutionState state) {
if (state is ExecutedSuccessfullyState) { if (state is ExecutedSuccessfullyState) {
Navigator.of(context) Navigator.of(context).pushNamed(Routes.preSeed, arguments: _walletNewVM.type);
.pushNamed(Routes.preSeed, arguments: _walletNewVM.type);
} }
if (state is FailureState) { if (state is FailureState) {
@ -90,140 +85,144 @@ class _WalletNameFormState extends State<WalletNameForm> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Padding(
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
child: ScrollableWithBottomSection( child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
content: content: Center(
Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ child: ConstrainedBox(
Padding( constraints:
padding: EdgeInsets.only(left: 12, right: 12), BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
child: AspectRatio( child: Column(
aspectRatio: aspectRatioImage, crossAxisAlignment: CrossAxisAlignment.center,
child: children: [
FittedBox(child: widget.walletImage, fit: BoxFit.fill)), Padding(
), padding: EdgeInsets.only(left: 12, right: 12),
Padding( child: AspectRatio(
padding: EdgeInsets.only(top: 24), aspectRatio: aspectRatioImage,
child: Form( child: FittedBox(child: widget.walletImage, fit: BoxFit.fill)),
key: _formKey, ),
child: Stack( Padding(
alignment: Alignment.centerRight, padding: EdgeInsets.only(top: 24),
children: [ child: Form(
TextFormField( key: _formKey,
onChanged: (value) => _walletNewVM.name = value, child: Stack(
controller: _controller, alignment: Alignment.centerRight,
textAlign: TextAlign.center, children: [
style: TextStyle( TextFormField(
fontSize: 20.0, onChanged: (value) => _walletNewVM.name = value,
fontWeight: FontWeight.w600, controller: _controller,
color: textAlign: TextAlign.center,
Theme.of(context).primaryTextTheme!.headline6!.color!), style: TextStyle(
decoration: InputDecoration( fontSize: 20.0,
hintStyle: TextStyle( fontWeight: FontWeight.w600,
fontSize: 18.0, color: Theme.of(context).primaryTextTheme!.headline6!.color!),
fontWeight: FontWeight.w500, decoration: InputDecoration(
color: Theme.of(context) hintStyle: TextStyle(
.accentTextTheme! fontSize: 18.0,
.headline2! fontWeight: FontWeight.w500,
.color!), color: Theme.of(context).accentTextTheme!.headline2!.color!),
hintText: S.of(context).wallet_name, hintText: S.of(context).wallet_name,
focusedBorder: UnderlineInputBorder( focusedBorder: UnderlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: Theme.of(context) color: Theme.of(context)
.accentTextTheme! .accentTextTheme!
.headline2! .headline2!
.decorationColor!, .decorationColor!,
width: 1.0)), width: 1.0)),
enabledBorder: UnderlineInputBorder( enabledBorder: UnderlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: Theme.of(context) color: Theme.of(context)
.accentTextTheme! .accentTextTheme!
.headline2! .headline2!
.decorationColor!, .decorationColor!,
width: 1.0), width: 1.0),
), ),
suffixIcon: IconButton( suffixIcon: IconButton(
onPressed: () async { onPressed: () async {
final rName = await generateName(); final rName = await generateName();
FocusManager.instance.primaryFocus?.unfocus(); FocusManager.instance.primaryFocus?.unfocus();
setState(() { setState(() {
_controller.text = rName; _controller.text = rName;
_walletNewVM.name = rName; _walletNewVM.name = rName;
_controller.selection = TextSelection.fromPosition( _controller.selection = TextSelection.fromPosition(
TextPosition(offset: _controller.text.length)); TextPosition(offset: _controller.text.length));
}); });
}, },
icon: Container( icon: Container(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0), borderRadius: BorderRadius.circular(6.0),
color: Theme.of(context).hintColor, color: Theme.of(context).hintColor,
), ),
width: 34, width: 34,
height: 34, height: 34,
child: Image.asset( child: Image.asset(
'assets/images/refresh_icon.png', 'assets/images/refresh_icon.png',
color: Theme.of(context) color: Theme.of(context)
.primaryTextTheme! .primaryTextTheme!
.headline4! .headline4!
.decorationColor!, .decorationColor!,
),
),
),
), ),
validator: WalletNameValidator(),
), ),
), ],
), ),
validator: WalletNameValidator(),
), ),
], ),
), if (_walletNewVM.hasLanguageSelector) ...[
Padding(
padding: EdgeInsets.only(top: 40),
child: Text(
S.of(context).seed_language_choose,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme!.headline6!.color!),
),
),
Padding(
padding: EdgeInsets.only(top: 24),
child: SeedLanguageSelector(
key: _languageSelectorKey, initialSelected: defaultSeedLanguage),
)
]
],
), ),
), ),
if (_walletNewVM.hasLanguageSelector) ...[ ),
Padding( bottomSectionPadding: EdgeInsets.all(24),
padding: EdgeInsets.only(top: 40), bottomSection: ConstrainedBox(
child: Text( constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
S.of(context).seed_language_choose, child: Column(
textAlign: TextAlign.center, children: [
style: TextStyle( Observer(
fontSize: 16.0, builder: (context) {
fontWeight: FontWeight.w500, return LoadingPrimaryButton(
color: Theme.of(context).primaryTextTheme!.headline6!.color!), onPressed: _confirmForm,
text: S.of(context).seed_language_next,
color: Colors.green,
textColor: Colors.white,
isLoading: _walletNewVM.state is IsExecutingState,
isDisabled: _walletNewVM.name.isEmpty,
);
},
), ),
), const SizedBox(height: 25),
Padding( GestureDetector(
padding: EdgeInsets.only(top: 24), onTap: () {
child: SeedLanguageSelector( Navigator.of(context)
key: _languageSelectorKey, .pushNamed(Routes.advancedPrivacySettings, arguments: _walletNewVM.type);
initialSelected: defaultSeedLanguage), },
) child: Text(S.of(context).advanced_privacy_settings),
] ),
]), ],
bottomSectionPadding: ),
EdgeInsets.all(24),
bottomSection: Column(
children: [
Observer(
builder: (context) {
return LoadingPrimaryButton(
onPressed: _confirmForm,
text: S.of(context).seed_language_next,
color: Colors.green,
textColor: Colors.white,
isLoading: _walletNewVM.state is IsExecutingState,
isDisabled: _walletNewVM.name.isEmpty,
);
},
),
const SizedBox(height: 25),
GestureDetector(
onTap: () {
Navigator.of(context)
.pushNamed(Routes.advancedPrivacySettings, arguments: _walletNewVM.type);
},
child: Text(S.of(context).advanced_privacy_settings),
),
],
)), )),
); );
} }

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_base.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -13,23 +14,19 @@ class NewWalletTypePage extends BasePage {
final void Function(BuildContext, WalletType) onTypeSelected; final void Function(BuildContext, WalletType) onTypeSelected;
final walletTypeImage = Image.asset('assets/images/wallet_type.png'); final walletTypeImage = Image.asset('assets/images/wallet_type.png');
final walletTypeLightImage = final walletTypeLightImage = Image.asset('assets/images/wallet_type_light.png');
Image.asset('assets/images/wallet_type_light.png');
@override @override
String get title => S.current.wallet_list_restore_wallet; String get title => S.current.wallet_list_restore_wallet;
@override @override
Widget body(BuildContext context) => WalletTypeForm( Widget body(BuildContext context) => WalletTypeForm(
onTypeSelected: onTypeSelected, onTypeSelected: onTypeSelected,
walletImage: currentTheme.type == ThemeType.dark walletImage: currentTheme.type == ThemeType.dark ? walletTypeImage : walletTypeLightImage);
? walletTypeImage
: walletTypeLightImage);
} }
class WalletTypeForm extends StatefulWidget { class WalletTypeForm extends StatefulWidget {
WalletTypeForm({required this.onTypeSelected, WalletTypeForm({required this.onTypeSelected, required this.walletImage});
required this.walletImage});
final void Function(BuildContext, WalletType) onTypeSelected; final void Function(BuildContext, WalletType) onTypeSelected;
final Image walletImage; final Image walletImage;
@ -39,22 +36,16 @@ class WalletTypeForm extends StatefulWidget {
} }
class WalletTypeFormState extends State<WalletTypeForm> { class WalletTypeFormState extends State<WalletTypeForm> {
WalletTypeFormState() WalletTypeFormState() : types = availableWalletTypes;
: types = availableWalletTypes;
static const aspectRatioImage = 1.22; static const aspectRatioImage = 1.22;
final moneroIcon = final moneroIcon = Image.asset('assets/images/monero_logo.png', height: 24, width: 24);
Image.asset('assets/images/monero_logo.png', height: 24, width: 24); final bitcoinIcon = Image.asset('assets/images/bitcoin.png', height: 24, width: 24);
final bitcoinIcon = final litecoinIcon = Image.asset('assets/images/litecoin_icon.png', height: 24, width: 24);
Image.asset('assets/images/bitcoin.png', height: 24, width: 24);
final litecoinIcon =
Image.asset('assets/images/litecoin_icon.png', height: 24, width: 24);
final walletTypeImage = Image.asset('assets/images/wallet_type.png'); final walletTypeImage = Image.asset('assets/images/wallet_type.png');
final walletTypeLightImage = final walletTypeLightImage = Image.asset('assets/images/wallet_type_light.png');
Image.asset('assets/images/wallet_type_light.png'); final havenIcon = Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
final havenIcon =
Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
WalletType? selected; WalletType? selected;
List<WalletType> types; List<WalletType> types;
@ -69,43 +60,51 @@ class WalletTypeFormState extends State<WalletTypeForm> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ScrollableWithBottomSection( return ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
content: Column( content: Center(
crossAxisAlignment: CrossAxisAlignment.center, child: ConstrainedBox(
children: <Widget>[ constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
Padding( child: Column(
padding: EdgeInsets.only(left: 12, right: 12), crossAxisAlignment: CrossAxisAlignment.center,
child: AspectRatio( children: <Widget>[
aspectRatio: aspectRatioImage, Padding(
child: FittedBox(child: widget.walletImage, fit: BoxFit.fill)), padding: EdgeInsets.only(left: 12, right: 12),
child: AspectRatio(
aspectRatio: aspectRatioImage,
child: FittedBox(child: widget.walletImage, fit: BoxFit.fill)),
),
Padding(
padding: EdgeInsets.only(top: 48),
child: Text(
S.of(context).choose_wallet_currency,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.headline6!.color!),
),
),
...types.map((type) => Padding(
padding: EdgeInsets.only(top: 24),
child: SelectButton(
image: _iconFor(type),
text: walletTypeToDisplayName(type),
isSelected: selected == type,
onTap: () => setState(() => selected = type)),
))
],
), ),
Padding( ),
padding: EdgeInsets.only(top: 48),
child: Text(
S.of(context).choose_wallet_currency,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.headline6!.color!),
),
),
...types.map((type) => Padding(
padding: EdgeInsets.only(top: 24),
child: SelectButton(
image: _iconFor(type),
text: walletTypeToDisplayName(type),
isSelected: selected == type,
onTap: () => setState(() => selected = type)),
))
],
), ),
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: PrimaryButton( bottomSection: ConstrainedBox(
onPressed: () => onTypeSelected(), constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
text: S.of(context).seed_language_next, child: PrimaryButton(
color: Theme.of(context).accentTextTheme.bodyText1!.color!, onPressed: () => onTypeSelected(),
textColor: Colors.white, text: S.of(context).seed_language_next,
isDisabled: selected == null, color: Theme.of(context).accentTextTheme.bodyText1!.color!,
textColor: Colors.white,
isDisabled: selected == null,
),
), ),
); );
} }
@ -121,7 +120,8 @@ class WalletTypeFormState extends State<WalletTypeForm> {
case WalletType.haven: case WalletType.haven:
return havenIcon; return havenIcon;
default: default:
throw Exception('_iconFor: Incorrect Wallet Type. Cannot find icon for Wallet Type: ${type.toString()}'); throw Exception(
'_iconFor: Incorrect Wallet Type. Cannot find icon for Wallet Type: ${type.toString()}');
} }
} }

View file

@ -1,17 +1,19 @@
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_bar.dart';
import 'package:another_flushbar/flushbar.dart'; import 'package:another_flushbar/flushbar.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter/services.dart';
class PinCodeWidget extends StatefulWidget { class PinCodeWidget extends StatefulWidget {
PinCodeWidget( PinCodeWidget({
{required Key key, required Key key,
required this.onFullPin, required this.onFullPin,
required this.initialPinLength, required this.initialPinLength,
required this.onChangedPin, required this.onChangedPin,
required this.hasLengthSwitcher, required this.hasLengthSwitcher,
this.onChangedPinLength,}) this.onChangedPinLength,
: super(key: key); }) : super(key: key);
final void Function(String pin, PinCodeState state) onFullPin; final void Function(String pin, PinCodeState state) onFullPin;
final void Function(String pin) onChangedPin; final void Function(String pin) onChangedPin;
@ -25,10 +27,10 @@ class PinCodeWidget extends StatefulWidget {
class PinCodeState<T extends PinCodeWidget> extends State<T> { class PinCodeState<T extends PinCodeWidget> extends State<T> {
PinCodeState() PinCodeState()
: _aspectRatio = 0, : _aspectRatio = 0,
pinLength = 0, pinLength = 0,
pin = '', pin = '',
title = ''; title = '';
static const defaultPinLength = fourPinLength; static const defaultPinLength = fourPinLength;
static const sixPinLength = 6; static const sixPinLength = 6;
static const fourPinLength = 4; static const fourPinLength = 4;
@ -75,8 +77,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
void setDefaultPinLength() => changePinLength(widget.initialPinLength); void setDefaultPinLength() => changePinLength(widget.initialPinLength);
void calculateAspectRatio() { void calculateAspectRatio() {
final renderBox = final renderBox = _gridViewKey.currentContext!.findRenderObject() as RenderBox;
_gridViewKey.currentContext!.findRenderObject() as RenderBox;
final cellWidth = renderBox.size.width / 3; final cellWidth = renderBox.size.width / 3;
final cellHeight = renderBox.size.height / 4; final cellHeight = renderBox.size.height / 4;
@ -89,8 +90,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
void changeProcessText(String text) { void changeProcessText(String text) {
hideProgressText(); hideProgressText();
_progressBar = createBar<void>(text, duration: null) _progressBar = createBar<void>(text, duration: null)..show(_key.currentContext!);
..show(_key.currentContext!);
} }
void close() { void close() {
@ -104,8 +104,8 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
} }
@override @override
Widget build(BuildContext context) => Scaffold( Widget build(BuildContext context) =>
key: _key, body: body(context), resizeToAvoidBottomInset: false); Scaffold(key: _key, body: body(context), resizeToAvoidBottomInset: false);
Widget body(BuildContext context) { Widget body(BuildContext context) {
final deleteIconImage = Image.asset( final deleteIconImage = Image.asset(
@ -117,157 +117,184 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
color: Theme.of(context).primaryTextTheme!.headline6!.color!, color: Theme.of(context).primaryTextTheme!.headline6!.color!,
); );
return Container( return RawKeyboardListener(
color: Theme.of(context).backgroundColor, focusNode: FocusNode(),
padding: EdgeInsets.only(left: 40.0, right: 40.0, bottom: 40.0), autofocus: true,
child: Column(children: <Widget>[ onKey: (keyEvent) {
Spacer(flex: 2), if (keyEvent is RawKeyDownEvent) {
Text(title, if (keyEvent.logicalKey.keyLabel == "Backspace") {
style: TextStyle( _pop();
fontSize: 20, return;
fontWeight: FontWeight.w500, }
color: Theme.of(context).primaryTextTheme!.headline6!.color!)), int? number = int.tryParse(keyEvent.character ?? '');
Spacer(flex: 3), if (number != null) {
Container( _push(number);
width: 180, }
child: Row( }
mainAxisAlignment: MainAxisAlignment.spaceBetween, },
children: List.generate(pinLength, (index) { child: Container(
const size = 10.0; color: Theme.of(context).backgroundColor,
final isFilled = pin.length > index ? pin[index] != null : false; padding: EdgeInsets.only(left: 40.0, right: 40.0, bottom: 40.0),
child: Column(
return Container( children: <Widget>[
width: size, Spacer(flex: 2),
height: size, Text(title,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isFilled
? Theme.of(context).primaryTextTheme!.headline6!.color!
: Theme.of(context)
.accentTextTheme!
.bodyText2!
.color!
.withOpacity(0.25),
));
}),
),
),
Spacer(flex: 2),
if (widget.hasLengthSwitcher) ...[
TextButton(
onPressed: () {
changePinLength(pinLength == PinCodeState.fourPinLength
? PinCodeState.sixPinLength
: PinCodeState.fourPinLength);
},
child: Text(
_changePinLengthText(),
style: TextStyle( style: TextStyle(
fontSize: 14.0, fontSize: 20,
fontWeight: FontWeight.normal, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context).primaryTextTheme!.headline6!.color!)),
.accentTextTheme! Spacer(flex: 3),
.bodyText2! Container(
.decorationColor!), width: 180,
)) child: Row(
], mainAxisAlignment: MainAxisAlignment.spaceBetween,
Spacer(flex: 1), children: List.generate(pinLength, (index) {
Flexible( const size = 10.0;
flex: 24, final isFilled = pin.length > index ? pin[index] != null : false;
child: Container(
key: _gridViewKey,
child: _aspectRatio > 0
? GridView.count(
shrinkWrap: true,
crossAxisCount: 3,
childAspectRatio: _aspectRatio,
physics: const NeverScrollableScrollPhysics(),
children: List.generate(12, (index) {
const double marginRight = 15;
const double marginLeft = 15;
if (index == 9) { return Container(
return Container( width: size,
margin: EdgeInsets.only( height: size,
left: marginLeft, right: marginRight), decoration: BoxDecoration(
child: TextButton( shape: BoxShape.circle,
onPressed: () => null, color: isFilled
// (widget.hasLengthSwitcher || ? Theme.of(context).primaryTextTheme!.headline6!.color!
// !settingsStore : Theme.of(context)
// .allowBiometricalAuthentication) .accentTextTheme!
// ? null .bodyText2!
// : () { .color!
// FIXME .withOpacity(0.25),
// if (authStore != null) { ));
// WidgetsBinding.instance.addPostFrameCallback((_) { }),
// final biometricAuth = BiometricAuth(); ),
// biometricAuth.isAuthenticated().then( ),
// (isAuth) { Spacer(flex: 2),
// if (isAuth) { if (widget.hasLengthSwitcher) ...[
// authStore.biometricAuth(); TextButton(
// _key.currentState.showSnackBar( onPressed: () {
// SnackBar( changePinLength(pinLength == PinCodeState.fourPinLength
// content: Text(S.of(context).authenticated), ? PinCodeState.sixPinLength
// backgroundColor: Colors.green, : PinCodeState.fourPinLength);
// ), },
// ); child: Text(
// } _changePinLengthText(),
// } style: TextStyle(
// ); fontSize: 14.0,
// }); fontWeight: FontWeight.normal,
// } color: Theme.of(context).accentTextTheme!.bodyText2!.decorationColor!),
// }, ),
// FIX-ME: Style )
//color: Theme.of(context).backgroundColor, ],
//shape: CircleBorder(), Spacer(flex: 1),
child: Container() Flexible(
// (widget.hasLengthSwitcher || flex: 24,
// !settingsStore child: Center(
// .allowBiometricalAuthentication) child: ConstrainedBox(
// ? Offstage() constraints: BoxConstraints(
// : faceImage, maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint,
),
child: Container(
key: _gridViewKey,
child: _aspectRatio > 0
? ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
child: GridView.count(
shrinkWrap: true,
crossAxisCount: 3,
childAspectRatio: _aspectRatio,
physics: const NeverScrollableScrollPhysics(),
children: List.generate(12, (index) {
const double marginRight = 15;
const double marginLeft = 15;
if (index == 9) {
return Container(
margin: EdgeInsets.only(left: marginLeft, right: marginRight),
child: TextButton(
onPressed: () => null,
// (widget.hasLengthSwitcher ||
// !settingsStore
// .allowBiometricalAuthentication)
// ? null
// : () {
// FIXME
// if (authStore != null) {
// WidgetsBinding.instance.addPostFrameCallback((_) {
// final biometricAuth = BiometricAuth();
// biometricAuth.isAuthenticated().then(
// (isAuth) {
// if (isAuth) {
// authStore.biometricAuth();
// _key.currentState.showSnackBar(
// SnackBar(
// content: Text(S.of(context).authenticated),
// backgroundColor: Colors.green,
// ),
// );
// }
// }
// );
// });
// }
// },
// FIX-ME: Style
//color: Theme.of(context).backgroundColor,
//shape: CircleBorder(),
child: Container()
// (widget.hasLengthSwitcher ||
// !settingsStore
// .allowBiometricalAuthentication)
// ? Offstage()
// : faceImage,
),
);
} else if (index == 10) {
index = 0;
} else if (index == 11) {
return Container(
margin: EdgeInsets.only(left: marginLeft, right: marginRight),
child: TextButton(
onPressed: () => _pop(),
style: TextButton.styleFrom(
backgroundColor: Theme.of(context).backgroundColor,
shape: CircleBorder(),
),
child: deleteIconImage,
),
);
} else {
index++;
}
return Container(
margin: EdgeInsets.only(left: marginLeft, right: marginRight),
child: TextButton(
onPressed: () => _push(index),
style: TextButton.styleFrom(
backgroundColor: Theme.of(context).backgroundColor,
shape: CircleBorder(),
),
child: Text('$index',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.color!)),
), ),
); );
} else if (index == 10) { }),
index = 0;
} else if (index == 11) {
return Container(
margin: EdgeInsets.only(
left: marginLeft, right: marginRight),
child: TextButton(
onPressed: () => _pop(),
// FIX-ME: Style
//color: Theme.of(context).backgroundColor,
//shape: CircleBorder(),
child: deleteIconImage,
),
);
} else {
index++;
}
return Container(
margin: EdgeInsets.only(
left: marginLeft, right: marginRight),
child: TextButton(
onPressed: () => _push(index),
// FIX-ME: Style
//color: Theme.of(context).backgroundColor,
//shape: CircleBorder(),
child: Text('$index',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.color!)),
), ),
); )
}), : null,
) ),
: null)) ),
]), ),
)
],
),
),
); );
} }

View file

@ -1,4 +1,5 @@
import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart';
@ -38,165 +39,130 @@ class WelcomePage extends BasePage {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: Theme backgroundColor: Theme.of(context).backgroundColor,
.of(context)
.backgroundColor,
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
body: body(context)); body: body(context));
} }
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
final welcomeImage = currentTheme.type == ThemeType.dark final welcomeImage = currentTheme.type == ThemeType.dark ? welcomeImageDark : welcomeImageLight;
? welcomeImageDark : welcomeImageLight;
final newWalletImage = Image.asset('assets/images/new_wallet.png', final newWalletImage = Image.asset('assets/images/new_wallet.png',
height: 12, height: 12,
width: 12, width: 12,
color: Theme color: Theme.of(context).accentTextTheme!.headline5!.decorationColor!);
.of(context)
.accentTextTheme!
.headline5!
.decorationColor!);
final restoreWalletImage = Image.asset('assets/images/restore_wallet.png', final restoreWalletImage = Image.asset('assets/images/restore_wallet.png',
height: 12, height: 12, width: 12, color: Theme.of(context).primaryTextTheme!.headline6!.color!);
width: 12,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.color!);
return WillPopScope(onWillPop: () async => false, child: Container( return WillPopScope(
padding: EdgeInsets.only(top: 64, bottom: 24, left: 24, right: 24), onWillPop: () async => false,
child: Column( child: Container(
mainAxisAlignment: MainAxisAlignment.spaceBetween, padding: EdgeInsets.only(top: 64, bottom: 24, left: 24, right: 24),
children: <Widget>[ child: Center(
Flexible( child: ConstrainedBox(
flex: 2, constraints:
child: AspectRatio( BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
aspectRatio: aspectRatioImage,
child: FittedBox(child: welcomeImage, fit: BoxFit.fill)
)
),
Flexible(
flex: 3,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
Column( Flexible(
children: <Widget>[ flex: 2,
Padding( child: AspectRatio(
padding: EdgeInsets.only(top: 24), aspectRatio: aspectRatioImage,
child: Text( child: FittedBox(child: welcomeImage, fit: BoxFit.fill))),
S Flexible(
.of(context) flex: 3,
.welcome, child: Column(
style: TextStyle( mainAxisAlignment: MainAxisAlignment.spaceBetween,
fontSize: 18, children: <Widget>[
fontWeight: FontWeight.w500, Column(
color: Theme children: <Widget>[
.of(context) Padding(
.accentTextTheme! padding: EdgeInsets.only(top: 24),
.headline2! child: Text(
.color!, S.of(context).welcome,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.headline2!.color!,
),
textAlign: TextAlign.center,
),
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
appTitle(context),
style: TextStyle(
fontSize: 36,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
textAlign: TextAlign.center,
),
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
appDescription(context),
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.headline2!.color!,
),
textAlign: TextAlign.center,
),
),
],
), ),
textAlign: TextAlign.center, Column(
), children: <Widget>[
), Text(
Padding( S.of(context).please_make_selection,
padding: EdgeInsets.only(top: 5), style: TextStyle(
child: Text( fontSize: 12,
appTitle(context), fontWeight: FontWeight.normal,
style: TextStyle( color: Theme.of(context).accentTextTheme!.headline2!.color!,
fontSize: 36, ),
fontWeight: FontWeight.bold, textAlign: TextAlign.center,
color: Theme.of(context) ),
.primaryTextTheme! Padding(
.headline6! padding: EdgeInsets.only(top: 24),
.color!, child: PrimaryImageButton(
), onPressed: () =>
textAlign: TextAlign.center, Navigator.pushNamed(context, Routes.newWalletFromWelcome),
), image: newWalletImage,
), text: S.of(context).create_new,
Padding( color: Theme.of(context)
padding: EdgeInsets.only(top: 5), .accentTextTheme!
child: Text( .subtitle2!
appDescription(context), .decorationColor!,
style: TextStyle( textColor: Theme.of(context)
fontSize: 16, .accentTextTheme!
fontWeight: FontWeight.w500, .headline5!
color: Theme .decorationColor!,
.of(context) ),
.accentTextTheme! ),
.headline2! Padding(
.color!, padding: EdgeInsets.only(top: 10),
), child: PrimaryImageButton(
textAlign: TextAlign.center, onPressed: () {
), Navigator.pushNamed(context, Routes.restoreOptions);
), },
], image: restoreWalletImage,
), text: S.of(context).restore_wallet,
Column( color: Theme.of(context).accentTextTheme!.caption!.color!,
children: <Widget>[ textColor:
Text( Theme.of(context).primaryTextTheme!.headline6!.color!),
S )
.of(context) ],
.please_make_selection, )
style: TextStyle( ],
fontSize: 12, ))
fontWeight: FontWeight.normal,
color: Theme.of(context)
.accentTextTheme!
.headline2!
.color!,
),
textAlign: TextAlign.center,
),
Padding(
padding: EdgeInsets.only(top: 24),
child: PrimaryImageButton(
onPressed: () =>
Navigator.pushNamed(context,
Routes.newWalletFromWelcome),
image: newWalletImage,
text: S.of(context).create_new,
color: Theme.of(context)
.accentTextTheme!
.subtitle2!
.decorationColor!,
textColor: Theme
.of(context)
.accentTextTheme!
.headline5!
.decorationColor!,
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: PrimaryImageButton(
onPressed: () {
Navigator.pushNamed(context, Routes.restoreOptions);
},
image: restoreWalletImage,
text: S
.of(context)
.restore_wallet,
color: Theme.of(context)
.accentTextTheme!
.caption!
.color!,
textColor: Theme.of(context)
.primaryTextTheme!
.headline6!
.color!),
)
],
)
], ],
) ),
) ),
], )));
)
));
} }
} }

View file

@ -17,6 +17,9 @@ class MarketPlaceItem extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return InkWell(
onTap: onTap, onTap: onTap,
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
child: Stack( child: Stack(
children: [ children: [
Container( Container(

View file

@ -74,7 +74,7 @@ class NavBar extends StatelessWidget implements ObstructingPreferredSizeWidget {
children: [ children: [
if (leading != null) Flexible(child: leading!), if (leading != null) Flexible(child: leading!),
if (middle != null) middle!, if (middle != null) middle!,
if (trailing != null) trailing!, trailing ?? const SizedBox(),
], ],
), ),
), ),

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
class ResponsiveLayoutUtil { class ResponsiveLayoutUtil {
static const double _kMobileThreshold = 900; static const double _kMobileThreshold = 900;
static const double kDesktopMaxWidthConstraint = 400;
const ResponsiveLayoutUtil._(); const ResponsiveLayoutUtil._();