CW-342 Enable Mac Layout on iPad (#958)
* Add iPad responsive layout * Set magic number to position input field on wider screens * Adjust screen resolution * Update target device family for ios * Add icons for iPad * Revert width adjustment for ipad * Fix overflowing balance * Fix overflowing balance * Fix PR issues * Remove unused icons [skip ci] --------- Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
Godwin Asuquo committed
Jun 14, 2023 at 02:04 UTC
affc35f3355f20740f9ba47458ef93028ebda699
34 files changed
+144
-110
ios/Podfile.lock
+11
-11
@@ -4,9 +4,9 @@ PODS:
4
- MTBBarcodeScanner
5
- SwiftProtobuf
6
- BigInt (5.2.0)
7
- - connectivity (0.0.1):
7
+ - connectivity_plus (0.0.1):
8
- Flutter
9
- - Reachability
9
+ - ReachabilitySwift
10
- CryptoSwift (1.6.0)
11
- cw_haven (0.0.1):
12
- cw_haven/Boost (= 0.0.1)
@@ -126,11 +126,11 @@ PODS:
126
- path_provider_foundation (0.0.1):
127
- Flutter
128
- FlutterMacOS
129
- - permission_handler_apple (9.0.4):
129
+ - permission_handler_apple (9.1.0):
130
- Flutter
131
- platform_device_id (0.0.1):
132
- Flutter
133
- - Reachability (3.2)
133
+ - ReachabilitySwift (5.0.0)
134
- SDWebImage (5.15.5):
135
- SDWebImage/Core (= 5.15.5)
136
- SDWebImage/Core (5.15.5)
@@ -153,7 +153,7 @@ PODS:
153
154
DEPENDENCIES:
155
- barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
156
- - connectivity (from `.symlinks/plugins/connectivity/ios`)
156
+ - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
157
- CryptoSwift
158
- cw_haven (from `.symlinks/plugins/cw_haven/ios`)
159
- cw_monero (from `.symlinks/plugins/cw_monero/ios`)
@@ -188,7 +188,7 @@ SPEC REPOS:
188
- DKPhotoGallery
189
- MTBBarcodeScanner
190
- OrderedSet
191
- - Reachability
191
+ - ReachabilitySwift
192
- SDWebImage
193
- SwiftProtobuf
194
- SwiftyGif
@@ -197,8 +197,8 @@ SPEC REPOS:
197
EXTERNAL SOURCES:
198
barcode_scan2:
199
:path: ".symlinks/plugins/barcode_scan2/ios"
200
- connectivity:
201
- :path: ".symlinks/plugins/connectivity/ios"
200
+ connectivity_plus:
201
+ :path: ".symlinks/plugins/connectivity_plus/ios"
202
cw_haven:
203
:path: ".symlinks/plugins/cw_haven/ios"
204
cw_monero:
@@ -249,7 +249,7 @@ EXTERNAL SOURCES:
249
SPEC CHECKSUMS:
250
barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
251
BigInt: f668a80089607f521586bbe29513d708491ef2f7
252
- connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
252
+ connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
253
CryptoSwift: 562f8eceb40e80796fffc668b0cad9313284cfa6
254
cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a
255
cw_monero: 4cf3b96f2da8e95e2ef7d6703dd4d2c509127b7d
@@ -271,9 +271,9 @@ SPEC CHECKSUMS:
271
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
272
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
273
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
274
- permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
274
+ permission_handler_apple: 8f116445eff3c0e7c65ad60f5fef5490aa94b4e4
275
platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5
276
- Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
276
+ ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
277
SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe
278
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
279
shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c
ios/Runner.xcodeproj/project.pbxproj
+3
-3
@@ -390,7 +390,7 @@
390
PRODUCT_NAME = "$(TARGET_NAME)";
391
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
392
SWIFT_VERSION = 5.0;
393
- TARGETED_DEVICE_FAMILY = 1;
393
+ TARGETED_DEVICE_FAMILY = "1,2";
394
VALID_ARCHS = arm64;
395
VERSIONING_SYSTEM = "apple-generic";
396
};
@@ -537,7 +537,7 @@
537
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
538
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
539
SWIFT_VERSION = 5.0;
540
- TARGETED_DEVICE_FAMILY = 1;
540
+ TARGETED_DEVICE_FAMILY = "1,2";
541
VALID_ARCHS = arm64;
542
VERSIONING_SYSTEM = "apple-generic";
543
};
@@ -574,7 +574,7 @@
574
PRODUCT_NAME = "$(TARGET_NAME)";
575
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
576
SWIFT_VERSION = 5.0;
577
- TARGETED_DEVICE_FAMILY = 1;
577
+ TARGETED_DEVICE_FAMILY = "1,2";
578
VALID_ARCHS = arm64;
579
VERSIONING_SYSTEM = "apple-generic";
580
};
ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
+13
@@ -1,21 +1,25 @@
1
{
2
"images" : [
3
{
4
+ "filename" : "Icon-App-40x40@1x.png",
5
"idiom" : "iphone",
6
"scale" : "2x",
7
"size" : "20x20"
8
},
9
{
10
+ "filename" : "Icon-App-20x20@3x.png",
11
"idiom" : "iphone",
12
"scale" : "3x",
13
"size" : "20x20"
14
},
15
{
16
+ "filename" : "Icon-App-29x29@2x 1.png",
17
"idiom" : "iphone",
18
"scale" : "2x",
19
"size" : "29x29"
20
},
21
{
22
+ "filename" : "Icon-App-29x29@3x.png",
23
"idiom" : "iphone",
24
"scale" : "3x",
25
"size" : "29x29"
@@ -26,6 +30,7 @@
30
"size" : "40x40"
31
},
32
{
33
+ "filename" : "Icon-App-40x40@3x.png",
34
"idiom" : "iphone",
35
"scale" : "3x",
36
"size" : "40x40"
@@ -43,26 +48,31 @@
48
"size" : "60x60"
49
},
50
{
51
+ "filename" : "Icon-App-20x20@1x.png",
52
"idiom" : "ipad",
53
"scale" : "1x",
54
"size" : "20x20"
55
},
56
{
57
+ "filename" : "Icon-App-20x20@2x.png",
58
"idiom" : "ipad",
59
"scale" : "2x",
60
"size" : "20x20"
61
},
62
{
63
+ "filename" : "Icon-App-29x29@1x.png",
64
"idiom" : "ipad",
65
"scale" : "1x",
66
"size" : "29x29"
67
},
68
{
69
+ "filename" : "Icon-App-29x29@2x.png",
70
"idiom" : "ipad",
71
"scale" : "2x",
72
"size" : "29x29"
73
},
74
{
75
+ "filename" : "Icon-App-40x40@1x 1.png",
76
"idiom" : "ipad",
77
"scale" : "1x",
78
"size" : "40x40"
@@ -73,16 +83,19 @@
83
"size" : "40x40"
84
},
85
{
86
+ "filename" : "Icon-App-76x76@1x.png",
87
"idiom" : "ipad",
88
"scale" : "1x",
89
"size" : "76x76"
90
},
91
{
92
+ "filename" : "Icon-App-76x76@2x.png",
93
"idiom" : "ipad",
94
"scale" : "2x",
95
"size" : "76x76"
96
},
97
{
98
+ "filename" : "Icon-App-83.5x83.5@2x.png",
99
"idiom" : "ipad",
100
"scale" : "2x",
101
"size" : "83.5x83.5"
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x 1.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x 1.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x 1.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x 1.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
lib/di.dart
+2
-1
@@ -36,6 +36,7 @@ import 'package:cake_wallet/themes/theme_list.dart';
36
import 'package:cake_wallet/utils/device_info.dart';
37
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
38
import 'package:cake_wallet/utils/payment_request.dart';
39
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
40
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
41
import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
42
import 'package:cake_wallet/view_model/anonpay_details_view_model.dart';
@@ -244,7 +245,7 @@ Future setup({
245
nodeSource: _nodeSource,
246
isBitcoinBuyEnabled: isBitcoinBuyEnabled,
247
// Enforce darkTheme on platforms other than mobile till the design for other themes is completed
247
- initialTheme: DeviceInfo.instance.isMobile ? null : ThemeList.darkTheme,
248
+ initialTheme: ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile ? null : ThemeList.darkTheme,
249
);
250
251
if (_isSetupFinished) {
lib/entities/main_actions.dart
+1
@@ -6,6 +6,7 @@ import 'package:cake_wallet/generated/i18n.dart';
6
import 'package:cake_wallet/routes.dart';
7
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
8
import 'package:cake_wallet/utils/device_info.dart';
9
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
10
import 'package:cake_wallet/utils/show_pop_up.dart';
11
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
12
import 'package:cw_core/wallet_type.dart';
lib/main.dart
+4
-1
@@ -6,6 +6,7 @@ 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/exception_handler.dart';
9
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
10
import 'package:flutter/foundation.dart';
11
import 'package:flutter/material.dart';
12
import 'package:flutter/services.dart';
@@ -194,7 +195,9 @@ class App extends StatefulWidget {
195
class AppState extends State<App> with SingleTickerProviderStateMixin {
196
AppState() : yatStore = getIt.get<YatStore>() {
197
SystemChrome.setPreferredOrientations(
197
- [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
198
+ ResponsiveLayoutUtil.instance.isIpad ?
199
+ [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight] :
200
+ [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
201
}
202
203
YatStore yatStore;
lib/src/screens/dashboard/dashboard_page.dart
+1
-1
@@ -43,7 +43,7 @@ class DashboardPage extends StatelessWidget {
43
@override
44
Widget build(BuildContext context) {
45
return Scaffold(
46
- body: ResponsiveLayoutUtil.instance.isMobile(context)
46
+ body: ResponsiveLayoutUtil.instance.isMobile
47
? _DashboardPageView(
48
balancePage: balancePage,
49
dashboardViewModel: dashboardViewModel,
lib/src/screens/dashboard/widgets/address_page.dart
+1
-1
@@ -73,7 +73,7 @@ class AddressPage extends BasePage {
73
? closeButtonImageDarkTheme
74
: closeButtonImage;
75
76
- bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
76
+ bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
77
78
return MergeSemantics(
79
child: SizedBox(
lib/src/screens/dashboard/widgets/balance_page.dart
+16
-13
@@ -120,19 +120,22 @@ class BalancePage extends StatelessWidget {
120
.backgroundColor!,
121
height: 1)),
122
SizedBox(height: 5),
123
- Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
124
- AutoSizeText(availableBalance,
125
- style: TextStyle(
126
- fontSize: 24,
127
- fontFamily: 'Lato',
128
- fontWeight: FontWeight.w900,
129
- color: Theme.of(context)
130
- .accentTextTheme!
131
- .displayMedium!
132
- .backgroundColor!,
133
- height: 1),
134
- maxLines: 1,
135
- textAlign: TextAlign.center),
123
+ Row(
124
+ mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
125
+ Expanded(
126
+ child: AutoSizeText(availableBalance,
127
+ style: TextStyle(
128
+ fontSize: 24,
129
+ fontFamily: 'Lato',
130
+ fontWeight: FontWeight.w900,
131
+ color: Theme.of(context)
132
+ .accentTextTheme!
133
+ .displayMedium!
134
+ .backgroundColor!,
135
+ height: 1),
136
+ maxLines: 1,
137
+ textAlign: TextAlign.start),
138
+ ),
139
Text(currency,
140
style: TextStyle(
141
fontSize: 28,
lib/src/screens/dashboard/widgets/transactions_page.dart
+1
-1
@@ -31,7 +31,7 @@ class TransactionsPage extends StatelessWidget {
31
onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing =
32
!dashboardViewModel.balanceViewModel.isReversing,
33
child: Container(
34
- color: ResponsiveLayoutUtil.instance.isMobile(context)
34
+ color: ResponsiveLayoutUtil.instance.isMobile
35
? null
36
: Theme.of(context).colorScheme.background,
37
padding: EdgeInsets.only(top: 24, bottom: 24),
lib/src/screens/exchange/exchange_page.dart
+2
-2
@@ -117,7 +117,7 @@ class ExchangePage extends BasePage {
117
final _closeButton = currentTheme.type == ThemeType.dark
118
? closeButtonImageDarkTheme : closeButtonImage;
119
120
- bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
120
+ bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
121
122
return MergeSemantics(
123
child: SizedBox(
@@ -731,7 +731,7 @@ class ExchangePage extends BasePage {
731
},
732
));
733
734
- if (ResponsiveLayoutUtil.instance.isMobile(context)) {
734
+ if (ResponsiveLayoutUtil.instance.isMobile) {
735
return MobileExchangeCardsSection(
736
firstExchangeCard: firstExchangeCard,
737
secondExchangeCard: secondExchangeCard,
lib/src/screens/receive/anonpay_invoice_page.dart
+24
-25
@@ -9,6 +9,7 @@ import 'package:cake_wallet/src/screens/receive/widgets/anonpay_input_form.dart'
9
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
10
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
11
import 'package:cake_wallet/utils/device_info.dart';
12
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
13
import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
14
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
15
import 'package:flutter/material.dart';
@@ -88,32 +89,30 @@ class AnonPayInvoicePage extends BasePage {
89
.accentTextTheme!
90
.bodyLarge!
91
.backgroundColor!,
91
- nextFocus: false,
92
- actions: [
93
- KeyboardActionsItem(
94
- focusNode: _amountFocusNode,
95
- toolbarButtons: [(_) => KeyboardDoneButton()],
92
+ nextFocus: false,
93
+ actions: [
94
+ KeyboardActionsItem(
95
+ focusNode: _amountFocusNode,
96
+ toolbarButtons: [(_) => KeyboardDoneButton()],
97
+ ),
98
+ ]),
99
+ child: Container(
100
+ color: Theme.of(context).colorScheme.background,
101
+ child: ScrollableWithBottomSection(
102
+ contentPadding: EdgeInsets.only(bottom: 24),
103
+ content: Container(
104
+ decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration(
105
+ borderRadius: BorderRadius.only(
106
+ bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
107
+ gradient: LinearGradient(
108
+ colors: [
109
+ Theme.of(context).primaryTextTheme!.titleSmall!.color!,
110
+ Theme.of(context).primaryTextTheme!.titleSmall!.decorationColor!,
111
+ ],
112
+ begin: Alignment.topLeft,
113
+ end: Alignment.bottomRight,
114
),
97
- ]),
98
- child: Container(
99
- color: Theme.of(context).colorScheme.background,
100
- child: ScrollableWithBottomSection(
101
- contentPadding: EdgeInsets.only(bottom: 24),
102
- content: Container(
103
- decoration: DeviceInfo.instance.isMobile
104
- ? BoxDecoration(
105
- borderRadius: BorderRadius.only(
106
- bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
107
- gradient: LinearGradient(
108
- colors: [
109
- Theme.of(context).primaryTextTheme!.titleSmall!.color!,
110
- Theme.of(context).primaryTextTheme!.titleSmall!.decorationColor!,
111
- ],
112
- begin: Alignment.topLeft,
113
- end: Alignment.bottomRight,
114
- ),
115
- )
116
- : null,
115
+ ) : null,
116
child: Observer(builder: (_) {
117
return Padding(
118
padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
lib/src/screens/receive/widgets/currency_input_field.dart
+21
-13
@@ -1,4 +1,5 @@
1
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
2
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
3
import 'package:cw_core/currency.dart';
4
import 'package:flutter/material.dart';
5
import 'package:flutter/services.dart';
@@ -9,7 +10,8 @@ class CurrencyInputField extends StatelessWidget {
10
required this.onTapPicker,
11
required this.selectedCurrency,
12
this.focusNode,
12
- required this.controller, required this.isLight,
13
+ required this.controller,
14
+ required this.isLight,
15
});
16
17
final Function() onTapPicker;
@@ -22,13 +24,12 @@ class CurrencyInputField extends StatelessWidget {
24
Widget build(BuildContext context) {
25
final arrowBottomPurple = Image.asset(
26
'assets/images/arrow_bottom_purple_icon.png',
25
- color: Theme.of(context)
26
- .accentTextTheme!
27
- .displayMedium!
28
- .backgroundColor!,
27
+ color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
28
height: 8,
29
);
31
- final _width = MediaQuery.of(context).size.width;
30
+ // This magic number for wider screen sets the text input focus at center of the inputfield
31
+ final _width =
32
+ ResponsiveLayoutUtil.instance.isMobile ? MediaQuery.of(context).size.width : 500;
33
34
return Column(
35
children: [
@@ -42,10 +43,12 @@ class CurrencyInputField extends StatelessWidget {
43
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
44
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.|\,)?\d{0,8}'))],
45
hintText: '0.000',
45
- placeholderTextStyle: isLight ? null : TextStyle(
46
- color: Theme.of(context).primaryTextTheme!.headlineSmall!.color!,
47
- fontWeight: FontWeight.w600,
48
- ),
46
+ placeholderTextStyle: isLight
47
+ ? null
48
+ : TextStyle(
49
+ color: Theme.of(context).primaryTextTheme!.headlineSmall!.color!,
50
+ fontWeight: FontWeight.w600,
51
+ ),
52
borderColor: Theme.of(context).accentTextTheme!.titleLarge!.backgroundColor!,
53
textColor: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
54
textStyle: TextStyle(
@@ -72,7 +75,10 @@ class CurrencyInputField extends StatelessWidget {
75
style: TextStyle(
76
fontWeight: FontWeight.w600,
77
fontSize: 16,
75
- color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
78
+ color: Theme.of(context)
79
+ .accentTextTheme!
80
+ .displayMedium!
81
+ .backgroundColor!,
82
),
83
),
84
if (selectedCurrency.tag != null)
@@ -107,8 +113,10 @@ class CurrencyInputField extends StatelessWidget {
113
style: TextStyle(
114
fontWeight: FontWeight.w600,
115
fontSize: 20,
110
- color:
111
- Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
116
+ color: Theme.of(context)
117
+ .accentTextTheme!
118
+ .displayMedium!
119
+ .backgroundColor!,
120
),
121
),
122
),
lib/src/screens/send/send_page.dart
+2
-2
@@ -62,7 +62,7 @@ class SendPage extends BasePage {
62
final _closeButton = currentTheme.type == ThemeType.dark
63
? closeButtonImageDarkTheme : closeButtonImage;
64
65
- bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
65
+ bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
66
67
return MergeSemantics(
68
child: SizedBox(
@@ -92,7 +92,7 @@ class SendPage extends BasePage {
92
double _sendCardHeight(BuildContext context) {
93
final double initialHeight = sendViewModel.isElectrumWallet ? 490 : 465;
94
95
- if (!ResponsiveLayoutUtil.instance.isMobile(context)) {
95
+ if (!ResponsiveLayoutUtil.instance.isMobile) {
96
return initialHeight - 66;
97
}
98
return initialHeight;
lib/src/screens/send/widgets/send_card.dart
+3
-3
@@ -122,7 +122,7 @@ class SendCardState extends State<SendCard>
122
color: Colors.transparent,
123
)),
124
Container(
125
- decoration: ResponsiveLayoutUtil.instance.isMobile(context) ? BoxDecoration(
125
+ decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration(
126
borderRadius: BorderRadius.only(
127
bottomLeft: Radius.circular(24),
128
bottomRight: Radius.circular(24)),
@@ -137,9 +137,9 @@ class SendCardState extends State<SendCard>
137
child: Padding(
138
padding: EdgeInsets.fromLTRB(
139
24,
140
- ResponsiveLayoutUtil.instance.isMobile(context) ? 100 : 55,
140
+ ResponsiveLayoutUtil.instance.isMobile ? 100 : 55,
141
24,
142
- ResponsiveLayoutUtil.instance.isMobile(context) ? 32 : 0,
142
+ ResponsiveLayoutUtil.instance.isMobile ? 32 : 0,
143
),
144
child: SingleChildScrollView(
145
child: Observer(builder: (_) => Column(
lib/src/screens/settings/display_settings_page.dart
+15
-10
@@ -8,6 +8,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.
8
import 'package:cake_wallet/themes/theme_base.dart';
9
import 'package:cake_wallet/themes/theme_list.dart';
10
import 'package:cake_wallet/utils/device_info.dart';
11
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
12
import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
13
import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
14
import 'package:flutter/material.dart';
@@ -29,11 +30,11 @@ class DisplaySettingsPage extends BasePage {
30
child: Column(
31
children: [
32
SettingsSwitcherCell(
32
- title: S.current.settings_display_balance,
33
- value: _displaySettingsViewModel.shouldDisplayBalance,
34
- onValueChange: (_, bool value) {
35
- _displaySettingsViewModel.setShouldDisplayBalance(value);
36
- }),
33
+ title: S.current.settings_display_balance,
34
+ value: _displaySettingsViewModel.shouldDisplayBalance,
35
+ onValueChange: (_, bool value) {
36
+ _displaySettingsViewModel.setShouldDisplayBalance(value);
37
+ }),
38
SettingsSwitcherCell(
39
title: S.current.show_market_place,
40
value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
@@ -42,14 +43,17 @@ class DisplaySettingsPage extends BasePage {
43
},
44
),
45
//if (!isHaven) it does not work correctly
45
- if(!_displaySettingsViewModel.disabledFiatApiMode)
46
+ if (!_displaySettingsViewModel.disabledFiatApiMode)
47
SettingsPickerCell<FiatCurrency>(
48
title: S.current.settings_currency,
49
searchHintText: S.current.search_currency,
50
items: FiatCurrency.all,
51
selectedItem: _displaySettingsViewModel.fiatCurrency,
51
- onItemSelected: (FiatCurrency currency) => _displaySettingsViewModel.setFiatCurrency(currency),
52
- images: FiatCurrency.all.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")).toList(),
52
+ onItemSelected: (FiatCurrency currency) =>
53
+ _displaySettingsViewModel.setFiatCurrency(currency),
54
+ images: FiatCurrency.all
55
+ .map((e) => Image.asset("assets/images/flags/${e.countryCode}.png"))
56
+ .toList(),
57
isGridView: true,
58
matchingCriteria: (FiatCurrency currency, String searchText) {
59
return currency.title.toLowerCase().contains(searchText) ||
@@ -66,13 +70,14 @@ class DisplaySettingsPage extends BasePage {
70
selectedItem: _displaySettingsViewModel.languageCode,
71
onItemSelected: _displaySettingsViewModel.onLanguageSelected,
72
images: LanguageService.list.keys
69
- .map((e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
73
+ .map((e) => Image.asset(
74
+ "assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
75
.toList(),
76
matchingCriteria: (String code, String searchText) {
77
return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
78
},
79
),
75
- if (DeviceInfo.instance.isMobile)
80
+ if (ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile)
81
SettingsChoicesCell(
82
ChoicesListItem<ThemeBase>(
83
title: S.current.color_theme,
lib/src/screens/wallet_list/wallet_list_page.dart
+2
-2
@@ -1,6 +1,6 @@
1
import 'package:cake_wallet/core/auth_service.dart';
2
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
3
-import 'package:cake_wallet/utils/device_info.dart';
3
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
4
import 'package:cake_wallet/utils/show_bar.dart';
5
import 'package:cake_wallet/utils/show_pop_up.dart';
6
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
@@ -229,7 +229,7 @@ class WalletListBodyState extends State<WalletListBody> {
229
await hideProgressText();
230
// only pop the wallets route in mobile as it will go back to dashboard page
231
// in desktop platforms the navigation tree is different
232
- if (DeviceInfo.instance.isMobile) {
232
+ if (ResponsiveLayoutUtil.instance.isMobile) {
233
WidgetsBinding.instance.addPostFrameCallback((_) {
234
Navigator.of(context).pop();
235
});
lib/src/widgets/add_template_button.dart
+1
-1
@@ -26,7 +26,7 @@ class AddTemplateButton extends StatelessWidget {
26
child: Container(
27
height: 34,
28
padding: EdgeInsets.symmetric(
29
- horizontal: ResponsiveLayoutUtil.instance.isMobile(context) ? 10 : 30),
29
+ horizontal: ResponsiveLayoutUtil.instance.isMobile ? 10 : 30),
30
alignment: Alignment.center,
31
decoration: BoxDecoration(
32
borderRadius: BorderRadius.all(Radius.circular(20)),
lib/src/widgets/address_text_field.dart
+2
-2
@@ -1,6 +1,6 @@
1
-import 'dart:io';
1
2
import 'package:cake_wallet/utils/device_info.dart';
3
+import 'package:cake_wallet/utils/responsive_layout_util.dart';
4
import 'package:flutter/services.dart';
5
import 'package:flutter/material.dart';
6
import 'package:cake_wallet/routes.dart';
@@ -105,7 +105,7 @@ class AddressTextField extends StatelessWidget {
105
width: prefixIconWidth * options.length +
106
(spaceBetweenPrefixIcons * options.length),
107
child: Row(
108
- mainAxisAlignment: DeviceInfo.instance.isMobile
108
+ mainAxisAlignment: ResponsiveLayoutUtil.instance.isMobile
109
? MainAxisAlignment.spaceBetween : MainAxisAlignment.end,
110
children: [
111
SizedBox(width: 5),
lib/utils/exception_handler.dart
+10
-11
@@ -130,17 +130,16 @@ class ExceptionHandler {
130
_ignoredErrors.any((element) => error.contains(element));
131
132
static const List<String> _ignoredErrors = const [
133
- "errno = 9", // SocketException: Bad file descriptor
134
- "errno = 28", // OS Error: No space left on device
135
- "errno = 32", // SocketException: Write failed (OS Error: Broken pipe)
136
- "errno = 49", // SocketException: Can't assign requested address
137
- "errno = 54", // SocketException: Connection reset by peer
138
- "errno = 57", // SocketException: Read failed (OS Error: Socket is not connected)
139
- "errno = 60", // SocketException: Operation timed out
140
- "errno = 65", // SocketException: No route to host
141
- "errno = 103", // SocketException: Software caused connection abort
142
- "errno = 104", // SocketException: Connection reset by peer
143
- "errno = 110", // SocketException: Connection timed out
133
+ "Bad file descriptor",
134
+ "No space left on device",
135
+ "Write failed (OS Error: Broken pipe)",
136
+ "Can't assign requested address",
137
+ "Read failed (OS Error: Socket is not connected)",
138
+ "Operation timed out",
139
+ "No route to host",
140
+ "Software caused connection abort",
141
+ "Connection reset by peer",
142
+ "Connection timed out",
143
"Connection reset by peer",
144
"Connection closed before full header was received",
145
"Connection terminated during handshake",
lib/utils/responsive_layout_util.dart
+9
-7
@@ -1,33 +1,35 @@
1
import 'package:flutter/material.dart';
2
3
class ResponsiveLayoutUtil {
4
- static const double _kMobileThreshold = 900;
4
+ static const double _kMobileThreshold = 768;
5
static const double kDesktopMaxWidthConstraint = 400;
6
static const double kPopupWidth = 400;
7
static const double kPopupSpaceHeight = 100;
8
-
8
+ static const _kIpadMaxWidth = 2560.0;
9
10
const ResponsiveLayoutUtil._();
11
12
static final instance = ResponsiveLayoutUtil._();
13
14
- bool isMobile(BuildContext context) {
15
- final MediaQueryData mediaQueryData = MediaQuery.of(context);
16
- return mediaQueryData.size.width < _kMobileThreshold;
14
+ bool get isMobile =>
15
+ WidgetsBinding.instance.platformDispatcher.views.first.physicalSize.width < _kMobileThreshold;
16
+
17
+ bool get isIpad {
18
+ final width = WidgetsBinding.instance.platformDispatcher.views.first.physicalSize.width;
19
+ return width >= _kMobileThreshold && !(width > _kIpadMaxWidth);
20
}
21
22
/// Returns dynamic size.
23
///
24
/// If screen size is mobile, it returns 66% ([scale]) of the [originalValue].
25
double getDynamicSize(
23
- BuildContext context,
26
double originalValue, {
27
double? mobileSize,
28
double? scale,
29
}) {
30
scale ??= 2 / 3;
31
mobileSize ??= originalValue * scale;
30
- final value = isMobile(context) ? mobileSize : originalValue;
32
+ final value = isMobile ? mobileSize : originalValue;
33
34
return value.roundToDouble();
35
}