CW-511-Tablet-iPad-keyboard-issue (#1143)

* fix keyboard issue * Update responsive_layout_util.dart * fix close button color * minor fix * [skip ci] Update pin_code_widget.dart * Update main.dart * fix qr widget overflow issue * Fix minor UI issue --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

Serhii committed Nov 3, 2023 at 07:42 UTC 2d454e0e486bf0afa81d977d8ef33506636f6a2e
31 files changed +215 -199
lib/di.dart
+1 -1
@@ -280,7 +280,7 @@ Future<void> setup({
280 powNodeSource: _powNodeSource,
281 isBitcoinBuyEnabled: isBitcoinBuyEnabled,
282 // Enforce darkTheme on platforms other than mobile till the design for other themes is completed
283 - initialTheme: ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile
283 + initialTheme: responsiveLayoutUtil.shouldRenderMobileUI && DeviceInfo.instance.isMobile
284 ? null
285 : ThemeList.darkTheme,
286 );
lib/main.dart
+11 -12
@@ -5,6 +5,7 @@ import 'package:cake_wallet/entities/language_service.dart';
5 import 'package:cake_wallet/buy/order.dart';
6 import 'package:cake_wallet/locales/locale.dart';
7 import 'package:cake_wallet/store/yat/yat_store.dart';
8 +import 'package:cake_wallet/utils/device_info.dart';
9 import 'package:cake_wallet/utils/exception_handler.dart';
10 import 'package:cw_core/address_info.dart';
11 import 'package:cake_wallet/utils/responsive_layout_util.dart';
@@ -322,22 +323,20 @@ class _Home extends StatefulWidget {
323 class _HomeState extends State<_Home> {
324 @override
325 void didChangeDependencies() {
325 - if (!ResponsiveLayoutUtil.instance.isMobile) {
326 - _setOrientation(context);
327 - }
326 + _setOrientation(context);
327 +
328 super.didChangeDependencies();
329 }
330
331 void _setOrientation(BuildContext context) {
332 - final orientation = MediaQuery.of(context).orientation;
333 - final width = MediaQuery.of(context).size.width;
334 - final height = MediaQuery.of(context).size.height;
335 - if (orientation == Orientation.portrait && width < height) {
336 - SystemChrome.setPreferredOrientations(
337 - [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
338 - } else if (orientation == Orientation.landscape && width > height) {
339 - SystemChrome.setPreferredOrientations(
340 - [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
332 + if (!DeviceInfo.instance.isDesktop) {
333 + if (responsiveLayoutUtil.shouldRenderMobileUI) {
334 + SystemChrome.setPreferredOrientations(
335 + [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
336 + } else {
337 + SystemChrome.setPreferredOrientations(
338 + [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
339 + }
340 }
341 }
342
lib/src/screens/dashboard/dashboard_page.dart
+13 -16
@@ -52,26 +52,23 @@ class DashboardPage extends StatelessWidget {
52 @override
53 Widget build(BuildContext context) {
54 return Scaffold(
55 - body: LayoutBuilder(
56 - builder: (context, constraints) {
55 + body: Observer(
56 + builder: (_) {
57 + final dashboardPageView = _DashboardPageView(
58 + balancePage: balancePage,
59 + bottomSheetService: bottomSheetService,
60 + dashboardViewModel: dashboardViewModel,
61 + addressListViewModel: addressListViewModel,
62 + );
63 +
64 if (DeviceInfo.instance.isDesktop) {
58 - if (constraints.maxWidth > ResponsiveLayoutUtil.kDesktopMaxDashBoardWidthConstraint) {
65 + if (responsiveLayoutUtil.screenWidth > ResponsiveLayoutUtilBase.kDesktopMaxDashBoardWidthConstraint) {
66 return getIt.get<DesktopSidebarWrapper>();
67 } else {
61 - return _DashboardPageView(
62 - balancePage: balancePage,
63 - bottomSheetService: bottomSheetService,
64 - dashboardViewModel: dashboardViewModel,
65 - addressListViewModel: addressListViewModel,
66 - );
68 + return dashboardPageView;
69 }
68 - } else if (ResponsiveLayoutUtil.instance.shouldRenderMobileUI()) {
69 - return _DashboardPageView(
70 - bottomSheetService: bottomSheetService,
71 - balancePage: balancePage,
72 - dashboardViewModel: dashboardViewModel,
73 - addressListViewModel: addressListViewModel,
74 - );
70 + } else if (responsiveLayoutUtil.shouldRenderMobileUI) {
71 + return dashboardPageView;
72 } else {
73 return getIt.get<DesktopSidebarWrapper>();
74 }
lib/src/screens/dashboard/widgets/address_page.dart
+10 -2
@@ -64,7 +64,15 @@ class AddressPage extends BasePage {
64
65 @override
66 Widget? leading(BuildContext context) {
67 - bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
67 + final _backButton = Icon(
68 + Icons.arrow_back_ios,
69 + color: titleColor(context),
70 + size: 16,
71 + );
72 + final _closeButton =
73 + currentTheme.type == ThemeType.dark ? closeButtonImageDarkTheme : closeButtonImage;
74 +
75 + bool isMobileView = responsiveLayoutUtil.shouldRenderMobileUI;
76
77 return MergeSemantics(
78 child: SizedBox(
@@ -79,7 +87,7 @@ class AddressPage extends BasePage {
87 overlayColor: MaterialStateColor.resolveWith((states) => Colors.transparent),
88 ),
89 onPressed: () => onClose(context),
82 - child: !isMobileView ? closeButton(context) : backButton(context),
90 + child: !isMobileView ? _closeButton : _backButton,
91 ),
92 ),
93 ),
lib/src/screens/dashboard/widgets/transactions_page.dart
+1 -1
@@ -34,7 +34,7 @@ class TransactionsPage extends StatelessWidget {
34 onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing =
35 !dashboardViewModel.balanceViewModel.isReversing,
36 child: Container(
37 - color: ResponsiveLayoutUtil.instance.isMobile
37 + color: responsiveLayoutUtil.shouldRenderMobileUI
38 ? null
39 : Theme.of(context).colorScheme.background,
40 padding: EdgeInsets.only(top: 24, bottom: 24),
lib/src/screens/exchange/exchange_page.dart
+2 -2
@@ -127,7 +127,7 @@ class ExchangePage extends BasePage {
127 final _closeButton =
128 currentTheme.type == ThemeType.dark ? closeButtonImageDarkTheme : closeButtonImage;
129
130 - bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
130 + bool isMobileView = responsiveLayoutUtil.shouldRenderMobileUI;
131
132 return MergeSemantics(
133 child: SizedBox(
@@ -705,7 +705,7 @@ class ExchangePage extends BasePage {
705 },
706 ));
707
708 - if (ResponsiveLayoutUtil.instance.isMobile) {
708 + if (responsiveLayoutUtil.shouldRenderMobileUI) {
709 return MobileExchangeCardsSection(
710 firstExchangeCard: firstExchangeCard,
711 secondExchangeCard: secondExchangeCard,
lib/src/screens/new_wallet/new_wallet_page.dart
+1 -1
@@ -96,7 +96,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
96 content: Center(
97 child: ConstrainedBox(
98 constraints:
99 - BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
99 + BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
100 child: Column(
101 crossAxisAlignment: CrossAxisAlignment.center,
102 children: [
lib/src/screens/new_wallet/new_wallet_type_page.dart
+1 -1
@@ -70,7 +70,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
70 Widget build(BuildContext context) {
71 return Center(
72 child: ConstrainedBox(
73 - constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
73 + constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
74 child: Column(
75 children: [
76 Padding(
lib/src/screens/pin_code/pin_code_widget.dart
+1 -1
@@ -191,7 +191,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
191 child: Center(
192 child: ConstrainedBox(
193 constraints: BoxConstraints(
194 - maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint,
194 + maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint,
195 ),
196 child: Container(
197 key: _gridViewKey,
lib/src/screens/receive/anonpay_invoice_page.dart
+1 -1
@@ -99,7 +99,7 @@ class AnonPayInvoicePage extends BasePage {
99 child: ScrollableWithBottomSection(
100 contentPadding: EdgeInsets.only(bottom: 24),
101 content: Container(
102 - decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration(
102 + decoration: responsiveLayoutUtil.shouldRenderMobileUI ? BoxDecoration(
103 borderRadius: BorderRadius.only(
104 bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
105 gradient: LinearGradient(
lib/src/screens/receive/widgets/currency_input_field.dart
+1 -1
@@ -32,7 +32,7 @@ class CurrencyInputField extends StatelessWidget {
32 );
33 // This magic number for wider screen sets the text input focus at center of the inputfield
34 final _width =
35 - ResponsiveLayoutUtil.instance.isMobile ? MediaQuery.of(context).size.width : 500;
35 + responsiveLayoutUtil.shouldRenderMobileUI ? MediaQuery.of(context).size.width : 500;
36
37 return Column(
38 children: [
lib/src/screens/receive/widgets/qr_widget.dart
+106 -101
@@ -38,129 +38,134 @@ class QRWidget extends StatelessWidget {
38 final copyImage = Image.asset('assets/images/copy_address.png',
39 color: Theme.of(context).extension<QRCodeTheme>()!.qrWidgetCopyButtonColor);
40
41 - return Column(
42 - mainAxisSize: MainAxisSize.min,
43 - mainAxisAlignment: MainAxisAlignment.center,
44 - crossAxisAlignment: CrossAxisAlignment.center,
45 - children: <Widget>[
46 - Column(
47 - children: [
48 - Padding(
49 - padding: const EdgeInsets.only(bottom: 12),
50 - child: Text(
51 - S.of(context).qr_fullscreen,
52 - style: TextStyle(
53 - fontSize: 14,
54 - fontWeight: FontWeight.w500,
55 - color: Theme.of(context).extension<DashboardPageTheme>()!.textColor),
56 - ),
57 - ),
58 - Row(
59 - children: <Widget>[
60 - Spacer(flex: 3),
61 - Observer(
62 - builder: (_) => Flexible(
63 - flex: 5,
64 - child: GestureDetector(
65 - onTap: () {
66 - BrightnessUtil.changeBrightnessForFunction(
67 - () async {
68 - await Navigator.pushNamed(context, Routes.fullscreenQR,
69 - arguments: QrViewData(
70 - data: addressListViewModel.uri.toString(),
71 - heroTag: heroTag,
72 - ));
41 + return Center(
42 + child: SingleChildScrollView(
43 + child: Column(
44 + mainAxisSize: MainAxisSize.min,
45 + mainAxisAlignment: MainAxisAlignment.center,
46 + crossAxisAlignment: CrossAxisAlignment.center,
47 + children: <Widget>[
48 + Column(
49 + children: [
50 + Padding(
51 + padding: const EdgeInsets.only(bottom: 12),
52 + child: Text(
53 + S.of(context).qr_fullscreen,
54 + style: TextStyle(
55 + fontSize: 14,
56 + fontWeight: FontWeight.w500,
57 + color: Theme.of(context).extension<DashboardPageTheme>()!.textColor),
58 + ),
59 + ),
60 + Row(
61 + children: <Widget>[
62 + Spacer(flex: 3),
63 + Observer(
64 + builder: (_) => Flexible(
65 + flex: 5,
66 + child: GestureDetector(
67 + onTap: () {
68 + BrightnessUtil.changeBrightnessForFunction(
69 + () async {
70 + await Navigator.pushNamed(context, Routes.fullscreenQR,
71 + arguments: QrViewData(
72 + data: addressListViewModel.uri.toString(),
73 + heroTag: heroTag,
74 + ));
75 + },
76 + );
77 },
74 - );
75 - },
76 - child: Hero(
77 - tag: Key(heroTag ?? addressListViewModel.uri.toString()),
78 - child: Center(
79 - child: AspectRatio(
80 - aspectRatio: 1.0,
81 - child: Container(
82 - padding: EdgeInsets.all(5),
83 - decoration: BoxDecoration(
84 - border: Border.all(
85 - width: 3,
86 - color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
87 - ),
88 - ),
89 - child: Container(
78 + child: Hero(
79 + tag: Key(heroTag ?? addressListViewModel.uri.toString()),
80 + child: Center(
81 + child: AspectRatio(
82 + aspectRatio: 1.0,
83 + child: Container(
84 + padding: EdgeInsets.all(5),
85 decoration: BoxDecoration(
86 border: Border.all(
87 width: 3,
93 - color:Colors.white,
88 + color:
89 + Theme.of(context).extension<DashboardPageTheme>()!.textColor,
90 ),
91 ),
96 - child: QrImage(data: addressListViewModel.uri.toString())),
92 + child: Container(
93 + decoration: BoxDecoration(
94 + border: Border.all(
95 + width: 3,
96 + color: Colors.white,
97 + ),
98 + ),
99 + child: QrImage(data: addressListViewModel.uri.toString())),
100 + ),
101 + ),
102 ),
103 ),
104 ),
105 ),
106 ),
102 - ),
103 - ),
104 - Spacer(flex: 3)
105 - ],
106 - ),
107 - ],
108 - ),
109 - Observer(builder: (_) {
110 - return Padding(
111 - padding: EdgeInsets.only(top: 10),
112 - child: Row(
113 - children: <Widget>[
114 - Expanded(
115 - child: Form(
116 - key: formKey,
117 - child: CurrencyInputField(
118 - focusNode: amountTextFieldFocusNode,
119 - controller: amountController,
120 - onTapPicker: () => _presentPicker(context),
121 - selectedCurrency: addressListViewModel.selectedCurrency,
122 - isLight: isLight,
123 - ),
124 - ),
107 + Spacer(flex: 3)
108 + ],
109 ),
110 ],
111 ),
128 - );
129 - }),
130 - Padding(
131 - padding: EdgeInsets.only(top: 20, bottom: 8),
132 - child: Builder(
133 - builder: (context) => Observer(
134 - builder: (context) => GestureDetector(
135 - onTap: () {
136 - Clipboard.setData(ClipboardData(text: addressListViewModel.address.address));
137 - showBar<void>(context, S.of(context).copied_to_clipboard);
138 - },
112 + Observer(builder: (_) {
113 + return Padding(
114 + padding: EdgeInsets.only(top: 10),
115 child: Row(
140 - mainAxisSize: MainAxisSize.max,
141 - crossAxisAlignment: CrossAxisAlignment.start,
116 children: <Widget>[
117 Expanded(
144 - child: Text(
145 - addressListViewModel.address.address,
146 - textAlign: TextAlign.center,
147 - style: TextStyle(
148 - fontSize: 15,
149 - fontWeight: FontWeight.w500,
150 - color: Theme.of(context).extension<DashboardPageTheme>()!.textColor),
118 + child: Form(
119 + key: formKey,
120 + child: CurrencyInputField(
121 + focusNode: amountTextFieldFocusNode,
122 + controller: amountController,
123 + onTapPicker: () => _presentPicker(context),
124 + selectedCurrency: addressListViewModel.selectedCurrency,
125 + isLight: isLight,
126 + ),
127 ),
128 ),
153 - Padding(
154 - padding: EdgeInsets.only(left: 12),
155 - child: copyImage,
156 - )
129 ],
130 ),
131 + );
132 + }),
133 + Padding(
134 + padding: EdgeInsets.only(top: 20, bottom: 8),
135 + child: Builder(
136 + builder: (context) => Observer(
137 + builder: (context) => GestureDetector(
138 + onTap: () {
139 + Clipboard.setData(ClipboardData(text: addressListViewModel.address.address));
140 + showBar<void>(context, S.of(context).copied_to_clipboard);
141 + },
142 + child: Row(
143 + mainAxisSize: MainAxisSize.max,
144 + crossAxisAlignment: CrossAxisAlignment.start,
145 + children: <Widget>[
146 + Expanded(
147 + child: Text(
148 + addressListViewModel.address.address,
149 + textAlign: TextAlign.center,
150 + style: TextStyle(
151 + fontSize: 15,
152 + fontWeight: FontWeight.w500,
153 + color: Theme.of(context).extension<DashboardPageTheme>()!.textColor),
154 + ),
155 + ),
156 + Padding(
157 + padding: EdgeInsets.only(left: 12),
158 + child: copyImage,
159 + )
160 + ],
161 + ),
162 + ),
163 + ),
164 ),
160 - ),
161 - ),
162 - )
163 - ],
165 + )
166 + ],
167 + ),
168 + ),
169 );
170 }
171
lib/src/screens/restore/restore_from_backup_page.dart
+1 -1
@@ -42,7 +42,7 @@ class RestoreFromBackupPage extends BasePage {
42
43 return Center(
44 child: ConstrainedBox(
45 - constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
45 + constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
46 child: Padding(
47 padding: EdgeInsets.only(bottom: 24, left: 24, right: 24),
48 child: Column(children: [
lib/src/screens/restore/restore_options_page.dart
+1 -1
@@ -31,7 +31,7 @@ class RestoreOptionsPage extends BasePage {
31 Widget body(BuildContext context) {
32 return Center(
33 child: Container(
34 - width: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint,
34 + width: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint,
35 height: double.infinity,
36 padding: EdgeInsets.symmetric(vertical: 24, horizontal: 24),
37 child: SingleChildScrollView(
lib/src/screens/restore/wallet_restore_page.dart
+1 -1
@@ -163,7 +163,7 @@ class WalletRestorePage extends BasePage {
163 color: Theme.of(context).colorScheme.background,
164 child: Center(
165 child: ConstrainedBox(
166 - constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
166 + constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
167 child: Column(
168 mainAxisAlignment: MainAxisAlignment.center,
169 children: [
lib/src/screens/seed/pre_seed_page.dart
+1 -1
@@ -35,7 +35,7 @@ class PreSeedPage extends BasePage {
35 alignment: Alignment.center,
36 padding: EdgeInsets.all(24),
37 child: ConstrainedBox(
38 - constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
38 + constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
39 child: Column(
40 mainAxisAlignment: MainAxisAlignment.spaceBetween,
41 children: <Widget>[
lib/src/screens/seed/wallet_seed_page.dart
+1 -1
@@ -93,7 +93,7 @@ class WalletSeedPage extends BasePage {
93 padding: EdgeInsets.all(24),
94 alignment: Alignment.center,
95 child: ConstrainedBox(
96 - constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
96 + constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
97 child: Column(
98 mainAxisAlignment: MainAxisAlignment.spaceBetween,
99 children: <Widget>[
lib/src/screens/send/send_page.dart
+2 -2
@@ -69,7 +69,7 @@ class SendPage extends BasePage {
69 final _closeButton =
70 currentTheme.type == ThemeType.dark ? closeButtonImageDarkTheme : closeButtonImage;
71
72 - bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
72 + bool isMobileView = responsiveLayoutUtil.shouldRenderMobileUI;
73
74 return MergeSemantics(
75 child: SizedBox(
@@ -98,7 +98,7 @@ class SendPage extends BasePage {
98 double _sendCardHeight(BuildContext context) {
99 final double initialHeight = sendViewModel.hasCoinControl ? 500 : 465;
100
101 - if (!ResponsiveLayoutUtil.instance.isMobile) {
101 + if (!responsiveLayoutUtil.shouldRenderMobileUI) {
102 return initialHeight - 66;
103 }
104 return initialHeight;
lib/src/screens/send/widgets/send_card.dart
+3 -3
@@ -122,7 +122,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
122 ),
123 ),
124 Container(
125 - decoration: ResponsiveLayoutUtil.instance.isMobile
125 + decoration: responsiveLayoutUtil.shouldRenderMobileUI
126 ? BoxDecoration(
127 borderRadius: BorderRadius.only(
128 bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
@@ -139,9 +139,9 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
139 child: Padding(
140 padding: EdgeInsets.fromLTRB(
141 24,
142 - ResponsiveLayoutUtil.instance.isMobile ? 100 : 55,
142 + responsiveLayoutUtil.shouldRenderMobileUI ? 100 : 55,
143 24,
144 - ResponsiveLayoutUtil.instance.isMobile ? 32 : 0,
144 + responsiveLayoutUtil.shouldRenderMobileUI ? 32 : 0,
145 ),
146 child: SingleChildScrollView(
147 child: Observer(
lib/src/screens/settings/display_settings_page.dart
+1 -1
@@ -75,7 +75,7 @@ class DisplaySettingsPage extends BasePage {
75 return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
76 },
77 ),
78 - if (ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile)
78 + if (responsiveLayoutUtil.shouldRenderMobileUI && DeviceInfo.instance.isMobile)
79 SettingsThemeChoicesCell(_displaySettingsViewModel),
80 ],
81 ),
lib/src/screens/wallet_list/wallet_list_page.dart
+1 -1
@@ -275,7 +275,7 @@ class WalletListBodyState extends State<WalletListBody> {
275 await hideProgressText();
276 // only pop the wallets route in mobile as it will go back to dashboard page
277 // in desktop platforms the navigation tree is different
278 - if (ResponsiveLayoutUtil.instance.shouldRenderMobileUI()) {
278 + if (responsiveLayoutUtil.shouldRenderMobileUI) {
279 WidgetsBinding.instance.addPostFrameCallback((_) {
280 Navigator.of(context).pop();
281 });
lib/src/screens/welcome/welcome_page.dart
+1 -1
@@ -70,7 +70,7 @@ class WelcomePage extends BasePage {
70 padding: EdgeInsets.only(top: 64, bottom: 24, left: 24, right: 24),
71 child: ConstrainedBox(
72 constraints: BoxConstraints(
73 - maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
73 + maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
74 child: Column(
75 mainAxisAlignment: MainAxisAlignment.spaceBetween,
76 children: <Widget>[
lib/src/widgets/add_template_button.dart
+1 -1
@@ -27,7 +27,7 @@ class AddTemplateButton extends StatelessWidget {
27 child: Container(
28 height: 34,
29 padding: EdgeInsets.symmetric(
30 - horizontal: ResponsiveLayoutUtil.instance.isMobile ? 10 : 30),
30 + horizontal: responsiveLayoutUtil.shouldRenderMobileUI ? 10 : 30),
31 alignment: Alignment.center,
32 decoration: BoxDecoration(
33 borderRadius: BorderRadius.all(Radius.circular(20)),
lib/src/widgets/address_text_field.dart
+1 -1
@@ -100,7 +100,7 @@ class AddressTextField extends StatelessWidget {
100 child: SizedBox(
101 width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length),
102 child: Row(
103 - mainAxisAlignment: ResponsiveLayoutUtil.instance.isMobile
103 + mainAxisAlignment: responsiveLayoutUtil.shouldRenderMobileUI
104 ? MainAxisAlignment.spaceBetween
105 : MainAxisAlignment.end,
106 children: [
lib/src/widgets/alert_background.dart
+1 -1
@@ -25,7 +25,7 @@ class AlertBackground extends StatelessWidget {
25 Theme.of(context).extension<AlertTheme>()!.backdropColor),
26 child: Center(
27 child: Container(
28 - width: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint,
28 + width: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint,
29 child: child,
30 ),
31 ),
lib/src/widgets/check_box_picker.dart
+1 -1
@@ -61,7 +61,7 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
61 child: ConstrainedBox(
62 constraints: BoxConstraints(
63 maxHeight: MediaQuery.of(context).size.height * 0.65,
64 - maxWidth: ResponsiveLayoutUtil.kPopupWidth,
64 + maxWidth: ResponsiveLayoutUtilBase.kPopupWidth,
65 ),
66 child: Column(
67 mainAxisSize: MainAxisSize.min,
lib/src/widgets/picker.dart
+1 -1
@@ -151,7 +151,7 @@ class _PickerState<Item> extends State<Picker<Item>> {
151 child: ConstrainedBox(
152 constraints: BoxConstraints(
153 maxHeight: containerHeight,
154 - maxWidth: ResponsiveLayoutUtil.kPopupWidth,
154 + maxWidth: ResponsiveLayoutUtilBase.kPopupWidth,
155 ),
156 child: Column(
157 mainAxisSize: MainAxisSize.min,
lib/src/widgets/picker_inner_wrapper_widget.dart
+2 -2
@@ -52,7 +52,7 @@ class PickerInnerWrapperWidget extends StatelessWidget {
52 itemsHeight != null && itemsHeight! <= containerHeight
53 ? itemsHeight!
54 : containerHeight,
55 - maxWidth: ResponsiveLayoutUtil.kPopupWidth,
55 + maxWidth: ResponsiveLayoutUtilBase.kPopupWidth,
56 ),
57 child: Column(
58 children: children,
@@ -77,7 +77,7 @@ class PickerInnerWrapperWidget extends StatelessWidget {
77 child: ConstrainedBox(
78 constraints: BoxConstraints(
79 maxHeight: containerHeight,
80 - maxWidth: ResponsiveLayoutUtil.kPopupWidth,
80 + maxWidth: ResponsiveLayoutUtilBase.kPopupWidth,
81 ),
82 child: Column(
83 children: children,
lib/src/widgets/picker_wrapper_widget.dart
+1 -1
@@ -44,7 +44,7 @@ class PickerWrapperWidget extends StatelessWidget {
44 mainAxisSize: MainAxisSize.min,
45 children: children,
46 ),
47 - SizedBox(height: ResponsiveLayoutUtil.kPopupSpaceHeight),
47 + SizedBox(height: ResponsiveLayoutUtilBase.kPopupSpaceHeight),
48 AlertCloseButton(bottom: closeButtonBottom),
49 ],
50 ),
lib/src/widgets/primary_button.dart
+4 -4
@@ -26,7 +26,7 @@ class PrimaryButton extends StatelessWidget {
26 @override
27 Widget build(BuildContext context) {
28 final content = ConstrainedBox(
29 - constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
29 + constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
30 child: SizedBox(
31 width: double.infinity,
32 height: 52.0,
@@ -82,7 +82,7 @@ class LoadingPrimaryButton extends StatelessWidget {
82 @override
83 Widget build(BuildContext context) {
84 return ConstrainedBox(
85 - constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
85 + constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
86 child: SizedBox(
87 width: double.infinity,
88 height: 52.0,
@@ -138,7 +138,7 @@ class PrimaryIconButton extends StatelessWidget {
138 @override
139 Widget build(BuildContext context) {
140 return ConstrainedBox(
141 - constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
141 + constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
142 child: SizedBox(
143 width: double.infinity,
144 height: 52.0,
@@ -201,7 +201,7 @@ class PrimaryImageButton extends StatelessWidget {
201 @override
202 Widget build(BuildContext context) {
203 return ConstrainedBox(
204 - constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
204 + constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
205 child: SizedBox(
206 width: double.infinity,
207 height: 52.0,
lib/utils/responsive_layout_util.dart
+41 -34
@@ -1,46 +1,53 @@
1 import 'package:flutter/material.dart';
2 +import 'package:mobx/mobx.dart';
3
3 -class ResponsiveLayoutUtil {
4 +part 'responsive_layout_util.g.dart';
5 +
6 +class _ResponsiveLayoutUtil = ResponsiveLayoutUtilBase with _$_ResponsiveLayoutUtil;
7 +
8 +abstract class ResponsiveLayoutUtilBase with Store, WidgetsBindingObserver {
9 static const double _kMobileThreshold = 550;
10 static const double kDesktopMaxWidthConstraint = 400;
11 static const double kDesktopMaxDashBoardWidthConstraint = 900;
12 static const double kPopupWidth = 400;
13 static const double kPopupSpaceHeight = 100;
14
10 - const ResponsiveLayoutUtil._();
11 -
12 - static final instance = ResponsiveLayoutUtil._();
13 -
14 - bool get isMobile =>
15 - MediaQueryData.fromWindow(WidgetsBinding.instance.window).size.shortestSide <=
16 - _kMobileThreshold;
17 -
18 - bool shouldRenderMobileUI() {
19 - final mediaQuery = MediaQueryData.fromWindow(WidgetsBinding.instance.window);
20 - final orientation = mediaQuery.orientation;
21 - final width = mediaQuery.size.width;
22 - final height = mediaQuery.size.height;
23 - if (isMobile ||
24 - (orientation == Orientation.portrait && width < height) ||
25 - (orientation == Orientation.landscape && width < height)) {
26 - return true;
27 - } else {
28 - return false;
29 - }
15 + ResponsiveLayoutUtilBase() {
16 + WidgetsBinding.instance.addObserver(this);
17 + final initialMediaQuery = MediaQueryData.fromView(WidgetsBinding.instance!.window);
18 + updateDeviceInfo(initialMediaQuery);
19 }
20
32 - /// Returns dynamic size.
33 - ///
34 - /// If screen size is mobile, it returns 66% ([scale]) of the [originalValue].
35 - double getDynamicSize(
36 - double originalValue, {
37 - double? mobileSize,
38 - double? scale,
39 - }) {
40 - scale ??= 2 / 3;
41 - mobileSize ??= originalValue * scale;
42 - final value = isMobile ? mobileSize : originalValue;
43 -
44 - return value.roundToDouble();
21 + @override
22 + void didChangeMetrics() {
23 + final mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance!.window);
24 + updateDeviceInfo(mediaQuery);
25 + }
26 +
27 + @observable
28 + double screenWidth = 0.0;
29 +
30 + @observable
31 + double screenHeight = 0.0;
32 +
33 + @observable
34 + Orientation orientation = Orientation.portrait;
35 +
36 + @action
37 + void updateDeviceInfo(MediaQueryData mediaQuery) {
38 + orientation = mediaQuery.orientation;
39 + screenWidth = mediaQuery.size.width;
40 + screenHeight = mediaQuery.size.height;
41 + }
42 +
43 + @computed
44 + bool get shouldRenderMobileUI {
45 + return (screenWidth <= _kMobileThreshold) ||
46 + (orientation == Orientation.portrait && screenWidth < screenHeight) ||
47 + (orientation == Orientation.landscape && screenWidth < screenHeight);
48 }
49 }
50 +
51 +_ResponsiveLayoutUtil _singletonResponsiveLayoutUtil = _ResponsiveLayoutUtil();
52 +
53 +_ResponsiveLayoutUtil get responsiveLayoutUtil => _singletonResponsiveLayoutUtil;