Fix Constrained width screens UI

This commit is contained in:
OmarHatem 2023-02-10 23:27:19 +02:00
parent c1bf0ee7aa
commit 5fa50c7668
4 changed files with 299 additions and 280 deletions

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';
@ -29,9 +30,6 @@ class NewWalletPage extends BasePage {
@override @override
String get title => S.current.new_wallet; String get title => S.current.new_wallet;
@override
Widget trailing(BuildContext context) => SizedBox.shrink();
@override @override
Widget body(BuildContext context) => WalletNameForm( Widget body(BuildContext context) => WalletNameForm(
_walletNewVM, currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage); _walletNewVM, currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage);
@ -89,136 +87,143 @@ class _WalletNameFormState extends State<WalletNameForm> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
child: Center( child: ScrollableWithBottomSection(
child: ConstrainedBox( contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
constraints: BoxConstraints(maxWidth: 600), content: Center(
child: ScrollableWithBottomSection( child: ConstrainedBox(
contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), constraints:
content: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
Padding( child: Column(
padding: EdgeInsets.only(left: 12, right: 12), crossAxisAlignment: CrossAxisAlignment.center,
child: AspectRatio( children: [
aspectRatio: aspectRatioImage, Padding(
child: FittedBox(child: widget.walletImage, fit: BoxFit.fill)), padding: EdgeInsets.only(left: 12, right: 12),
), child: AspectRatio(
Padding( aspectRatio: aspectRatioImage,
padding: EdgeInsets.only(top: 24), child: FittedBox(child: widget.walletImage, fit: BoxFit.fill)),
child: Form( ),
key: _formKey, Padding(
child: Stack( padding: EdgeInsets.only(top: 24),
alignment: Alignment.centerRight, child: Form(
children: [ key: _formKey,
TextFormField( child: Stack(
onChanged: (value) => _walletNewVM.name = value, alignment: Alignment.centerRight,
controller: _controller, children: [
textAlign: TextAlign.center, TextFormField(
style: TextStyle( onChanged: (value) => _walletNewVM.name = value,
fontSize: 20.0, controller: _controller,
fontWeight: FontWeight.w600, textAlign: TextAlign.center,
color: 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).accentTextTheme!.headline2!.color!), hintStyle: TextStyle(
hintText: S.of(context).wallet_name, fontSize: 18.0,
focusedBorder: UnderlineInputBorder( fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.headline2!.color!),
hintText: S.of(context).wallet_name,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentTextTheme!
.headline2!
.decorationColor!,
width: 1.0)),
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),
enabledBorder: UnderlineInputBorder( ),
borderSide: BorderSide( suffixIcon: IconButton(
color: Theme.of(context) onPressed: () async {
.accentTextTheme! final rName = await generateName();
.headline2! FocusManager.instance.primaryFocus?.unfocus();
.decorationColor!,
width: 1.0),
),
suffixIcon: IconButton(
onPressed: () async {
final rName = await generateName();
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) ...[
if (_walletNewVM.hasLanguageSelector) ...[ Padding(
Padding( padding: EdgeInsets.only(top: 40),
padding: EdgeInsets.only(top: 40), child: Text(
child: Text( S.of(context).seed_language_choose,
S.of(context).seed_language_choose, textAlign: TextAlign.center,
textAlign: TextAlign.center, style: TextStyle(
style: TextStyle( fontSize: 16.0,
fontSize: 16.0, fontWeight: FontWeight.w500,
fontWeight: FontWeight.w500, color: Theme.of(context).primaryTextTheme!.headline6!.color!),
color: Theme.of(context).primaryTextTheme!.headline6!.color!), ),
), ),
), Padding(
Padding( padding: EdgeInsets.only(top: 24),
padding: EdgeInsets.only(top: 24), child: SeedLanguageSelector(
child: SeedLanguageSelector( key: _languageSelectorKey, initialSelected: defaultSeedLanguage),
key: _languageSelectorKey, initialSelected: defaultSeedLanguage), )
) ]
]
]),
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),
),
], ],
)), ),
), ),
), ),
bottomSectionPadding: EdgeInsets.all(24),
bottomSection: ConstrainedBox(
constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
child: 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';
@ -18,9 +19,6 @@ class NewWalletTypePage extends BasePage {
@override @override
String get title => S.current.wallet_list_restore_wallet; String get title => S.current.wallet_list_restore_wallet;
@override
Widget trailing(BuildContext context) => SizedBox.shrink();
@override @override
Widget body(BuildContext context) => WalletTypeForm( Widget body(BuildContext context) => WalletTypeForm(
onTypeSelected: onTypeSelected, onTypeSelected: onTypeSelected,
@ -60,12 +58,12 @@ class WalletTypeFormState extends State<WalletTypeForm> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Center( return ScrollableWithBottomSection(
child: ConstrainedBox( contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
constraints: BoxConstraints(maxWidth: 600), content: Center(
child: ScrollableWithBottomSection( child: ConstrainedBox(
contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
content: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Padding( Padding(
@ -95,14 +93,17 @@ class WalletTypeFormState extends State<WalletTypeForm> {
)) ))
], ],
), ),
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), ),
bottomSection: PrimaryButton( ),
onPressed: () => onTypeSelected(), bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
text: S.of(context).seed_language_next, bottomSection: ConstrainedBox(
color: Theme.of(context).accentTextTheme.bodyText1!.color!, constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
textColor: Colors.white, child: PrimaryButton(
isDisabled: selected == null, onPressed: () => onTypeSelected(),
), text: S.of(context).seed_language_next,
color: Theme.of(context).accentTextTheme.bodyText1!.color!,
textColor: Colors.white,
isDisabled: selected == null,
), ),
), ),
); );

View file

@ -1,3 +1,4 @@
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';
@ -134,154 +135,165 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
child: Container( child: Container(
color: Theme.of(context).backgroundColor, color: Theme.of(context).backgroundColor,
padding: EdgeInsets.only(left: 40.0, right: 40.0, bottom: 40.0), padding: EdgeInsets.only(left: 40.0, right: 40.0, bottom: 40.0),
child: Column(children: <Widget>[ child: Column(
Spacer(flex: 2), children: <Widget>[
Text(title, Spacer(flex: 2),
style: TextStyle( Text(title,
fontSize: 20,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme!.headline6!.color!)),
Spacer(flex: 3),
Container(
width: 180,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(pinLength, (index) {
const size = 10.0;
final isFilled = pin.length > index ? pin[index] != null : false;
return Container(
width: size,
height: size,
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).accentTextTheme!.bodyText2!.decorationColor!), color: Theme.of(context).primaryTextTheme!.headline6!.color!)),
Spacer(flex: 3),
Container(
width: 180,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(pinLength, (index) {
const size = 10.0;
final isFilled = pin.length > index ? pin[index] != null : false;
return Container(
width: size,
height: size,
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(
fontSize: 14.0,
fontWeight: FontWeight.normal,
color: Theme.of(context).accentTextTheme!.bodyText2!.decorationColor!),
),
)
],
Spacer(flex: 1),
Flexible(
flex: 24,
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints(
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!)),
),
);
}),
),
)
: null,
),
),
), ),
) )
], ],
Spacer(flex: 1), ),
Flexible(
flex: 24,
child: Center(
child: Container(
height: MediaQuery.of(context).size.height * 0.6,
width: MediaQuery.of(context).size.height * 0.6,
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!)),
),
);
}),
),
)
: null,
),
),
)
],
), ),
); );
} }

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._();