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>
This commit is contained in:
Godwin Asuquo 2023-06-14 02:04:52 +03:00 committed by GitHub
parent e84d02f661
commit affc35f335
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 144 additions and 110 deletions

View file

@ -4,9 +4,9 @@ PODS:
- MTBBarcodeScanner
- SwiftProtobuf
- BigInt (5.2.0)
- connectivity (0.0.1):
- connectivity_plus (0.0.1):
- Flutter
- Reachability
- ReachabilitySwift
- CryptoSwift (1.6.0)
- cw_haven (0.0.1):
- cw_haven/Boost (= 0.0.1)
@ -126,11 +126,11 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- permission_handler_apple (9.0.4):
- permission_handler_apple (9.1.0):
- Flutter
- platform_device_id (0.0.1):
- Flutter
- Reachability (3.2)
- ReachabilitySwift (5.0.0)
- SDWebImage (5.15.5):
- SDWebImage/Core (= 5.15.5)
- SDWebImage/Core (5.15.5)
@ -153,7 +153,7 @@ PODS:
DEPENDENCIES:
- barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
- connectivity (from `.symlinks/plugins/connectivity/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- CryptoSwift
- cw_haven (from `.symlinks/plugins/cw_haven/ios`)
- cw_monero (from `.symlinks/plugins/cw_monero/ios`)
@ -188,7 +188,7 @@ SPEC REPOS:
- DKPhotoGallery
- MTBBarcodeScanner
- OrderedSet
- Reachability
- ReachabilitySwift
- SDWebImage
- SwiftProtobuf
- SwiftyGif
@ -197,8 +197,8 @@ SPEC REPOS:
EXTERNAL SOURCES:
barcode_scan2:
:path: ".symlinks/plugins/barcode_scan2/ios"
connectivity:
:path: ".symlinks/plugins/connectivity/ios"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
cw_haven:
:path: ".symlinks/plugins/cw_haven/ios"
cw_monero:
@ -249,7 +249,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
BigInt: f668a80089607f521586bbe29513d708491ef2f7
connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
CryptoSwift: 562f8eceb40e80796fffc668b0cad9313284cfa6
cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a
cw_monero: 4cf3b96f2da8e95e2ef7d6703dd4d2c509127b7d
@ -271,9 +271,9 @@ SPEC CHECKSUMS:
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
permission_handler_apple: 8f116445eff3c0e7c65ad60f5fef5490aa94b4e4
platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c

View file

@ -390,7 +390,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = arm64;
VERSIONING_SYSTEM = "apple-generic";
};
@ -537,7 +537,7 @@
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = arm64;
VERSIONING_SYSTEM = "apple-generic";
};
@ -574,7 +574,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = arm64;
VERSIONING_SYSTEM = "apple-generic";
};

View file

@ -1,21 +1,25 @@
{
"images" : [
{
"filename" : "Icon-App-40x40@1x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "Icon-App-20x20@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "Icon-App-29x29@2x 1.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "Icon-App-29x29@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
@ -26,6 +30,7 @@
"size" : "40x40"
},
{
"filename" : "Icon-App-40x40@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
@ -43,26 +48,31 @@
"size" : "60x60"
},
{
"filename" : "Icon-App-20x20@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "Icon-App-20x20@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "Icon-App-29x29@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "Icon-App-29x29@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "Icon-App-40x40@1x 1.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
@ -73,16 +83,19 @@
"size" : "40x40"
},
{
"filename" : "Icon-App-76x76@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "Icon-App-76x76@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "Icon-App-83.5x83.5@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -36,6 +36,7 @@ import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
import 'package:cake_wallet/view_model/anonpay_details_view_model.dart';
@ -244,7 +245,7 @@ Future setup({
nodeSource: _nodeSource,
isBitcoinBuyEnabled: isBitcoinBuyEnabled,
// Enforce darkTheme on platforms other than mobile till the design for other themes is completed
initialTheme: DeviceInfo.instance.isMobile ? null : ThemeList.darkTheme,
initialTheme: ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile ? null : ThemeList.darkTheme,
);
if (_isSetupFinished) {

View file

@ -6,6 +6,7 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/wallet_type.dart';

View file

@ -6,6 +6,7 @@ import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/locales/locale.dart';
import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -194,7 +195,9 @@ class App extends StatefulWidget {
class AppState extends State<App> with SingleTickerProviderStateMixin {
AppState() : yatStore = getIt.get<YatStore>() {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
ResponsiveLayoutUtil.instance.isIpad ?
[DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight] :
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
}
YatStore yatStore;

View file

@ -43,7 +43,7 @@ class DashboardPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ResponsiveLayoutUtil.instance.isMobile(context)
body: ResponsiveLayoutUtil.instance.isMobile
? _DashboardPageView(
balancePage: balancePage,
dashboardViewModel: dashboardViewModel,

View file

@ -73,7 +73,7 @@ class AddressPage extends BasePage {
? closeButtonImageDarkTheme
: closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
return MergeSemantics(
child: SizedBox(

View file

@ -120,19 +120,22 @@ class BalancePage extends StatelessWidget {
.backgroundColor!,
height: 1)),
SizedBox(height: 5),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
AutoSizeText(availableBalance,
style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
fontWeight: FontWeight.w900,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded(
child: AutoSizeText(availableBalance,
style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
fontWeight: FontWeight.w900,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.start),
),
Text(currency,
style: TextStyle(
fontSize: 28,

View file

@ -31,7 +31,7 @@ class TransactionsPage extends StatelessWidget {
onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing =
!dashboardViewModel.balanceViewModel.isReversing,
child: Container(
color: ResponsiveLayoutUtil.instance.isMobile(context)
color: ResponsiveLayoutUtil.instance.isMobile
? null
: Theme.of(context).colorScheme.background,
padding: EdgeInsets.only(top: 24, bottom: 24),

View file

@ -117,7 +117,7 @@ class ExchangePage extends BasePage {
final _closeButton = currentTheme.type == ThemeType.dark
? closeButtonImageDarkTheme : closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
return MergeSemantics(
child: SizedBox(
@ -731,7 +731,7 @@ class ExchangePage extends BasePage {
},
));
if (ResponsiveLayoutUtil.instance.isMobile(context)) {
if (ResponsiveLayoutUtil.instance.isMobile) {
return MobileExchangeCardsSection(
firstExchangeCard: firstExchangeCard,
secondExchangeCard: secondExchangeCard,

View file

@ -9,6 +9,7 @@ import 'package:cake_wallet/src/screens/receive/widgets/anonpay_input_form.dart'
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
import 'package:flutter/material.dart';
@ -88,32 +89,30 @@ class AnonPayInvoicePage extends BasePage {
.accentTextTheme!
.bodyLarge!
.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _amountFocusNode,
toolbarButtons: [(_) => KeyboardDoneButton()],
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _amountFocusNode,
toolbarButtons: [(_) => KeyboardDoneButton()],
),
]),
child: Container(
color: Theme.of(context).colorScheme.background,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24),
content: Container(
decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
gradient: LinearGradient(
colors: [
Theme.of(context).primaryTextTheme!.titleSmall!.color!,
Theme.of(context).primaryTextTheme!.titleSmall!.decorationColor!,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
]),
child: Container(
color: Theme.of(context).colorScheme.background,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24),
content: Container(
decoration: DeviceInfo.instance.isMobile
? BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
gradient: LinearGradient(
colors: [
Theme.of(context).primaryTextTheme!.titleSmall!.color!,
Theme.of(context).primaryTextTheme!.titleSmall!.decorationColor!,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
)
: null,
) : null,
child: Observer(builder: (_) {
return Padding(
padding: EdgeInsets.fromLTRB(24, 120, 24, 0),

View file

@ -1,4 +1,5 @@
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cw_core/currency.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -9,7 +10,8 @@ class CurrencyInputField extends StatelessWidget {
required this.onTapPicker,
required this.selectedCurrency,
this.focusNode,
required this.controller, required this.isLight,
required this.controller,
required this.isLight,
});
final Function() onTapPicker;
@ -22,13 +24,12 @@ class CurrencyInputField extends StatelessWidget {
Widget build(BuildContext context) {
final arrowBottomPurple = Image.asset(
'assets/images/arrow_bottom_purple_icon.png',
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
height: 8,
);
final _width = MediaQuery.of(context).size.width;
// This magic number for wider screen sets the text input focus at center of the inputfield
final _width =
ResponsiveLayoutUtil.instance.isMobile ? MediaQuery.of(context).size.width : 500;
return Column(
children: [
@ -42,10 +43,12 @@ class CurrencyInputField extends StatelessWidget {
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.|\,)?\d{0,8}'))],
hintText: '0.000',
placeholderTextStyle: isLight ? null : TextStyle(
color: Theme.of(context).primaryTextTheme!.headlineSmall!.color!,
fontWeight: FontWeight.w600,
),
placeholderTextStyle: isLight
? null
: TextStyle(
color: Theme.of(context).primaryTextTheme!.headlineSmall!.color!,
fontWeight: FontWeight.w600,
),
borderColor: Theme.of(context).accentTextTheme!.titleLarge!.backgroundColor!,
textColor: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
textStyle: TextStyle(
@ -72,7 +75,10 @@ class CurrencyInputField extends StatelessWidget {
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
),
),
if (selectedCurrency.tag != null)
@ -107,8 +113,10 @@ class CurrencyInputField extends StatelessWidget {
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 20,
color:
Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
),
),
),

View file

@ -62,7 +62,7 @@ class SendPage extends BasePage {
final _closeButton = currentTheme.type == ThemeType.dark
? closeButtonImageDarkTheme : closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
return MergeSemantics(
child: SizedBox(
@ -92,7 +92,7 @@ class SendPage extends BasePage {
double _sendCardHeight(BuildContext context) {
final double initialHeight = sendViewModel.isElectrumWallet ? 490 : 465;
if (!ResponsiveLayoutUtil.instance.isMobile(context)) {
if (!ResponsiveLayoutUtil.instance.isMobile) {
return initialHeight - 66;
}
return initialHeight;

View file

@ -122,7 +122,7 @@ class SendCardState extends State<SendCard>
color: Colors.transparent,
)),
Container(
decoration: ResponsiveLayoutUtil.instance.isMobile(context) ? BoxDecoration(
decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(24),
bottomRight: Radius.circular(24)),
@ -137,9 +137,9 @@ class SendCardState extends State<SendCard>
child: Padding(
padding: EdgeInsets.fromLTRB(
24,
ResponsiveLayoutUtil.instance.isMobile(context) ? 100 : 55,
ResponsiveLayoutUtil.instance.isMobile ? 100 : 55,
24,
ResponsiveLayoutUtil.instance.isMobile(context) ? 32 : 0,
ResponsiveLayoutUtil.instance.isMobile ? 32 : 0,
),
child: SingleChildScrollView(
child: Observer(builder: (_) => Column(

View file

@ -8,6 +8,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
import 'package:flutter/material.dart';
@ -29,11 +30,11 @@ class DisplaySettingsPage extends BasePage {
child: Column(
children: [
SettingsSwitcherCell(
title: S.current.settings_display_balance,
value: _displaySettingsViewModel.shouldDisplayBalance,
onValueChange: (_, bool value) {
_displaySettingsViewModel.setShouldDisplayBalance(value);
}),
title: S.current.settings_display_balance,
value: _displaySettingsViewModel.shouldDisplayBalance,
onValueChange: (_, bool value) {
_displaySettingsViewModel.setShouldDisplayBalance(value);
}),
SettingsSwitcherCell(
title: S.current.show_market_place,
value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
@ -42,14 +43,17 @@ class DisplaySettingsPage extends BasePage {
},
),
//if (!isHaven) it does not work correctly
if(!_displaySettingsViewModel.disabledFiatApiMode)
if (!_displaySettingsViewModel.disabledFiatApiMode)
SettingsPickerCell<FiatCurrency>(
title: S.current.settings_currency,
searchHintText: S.current.search_currency,
items: FiatCurrency.all,
selectedItem: _displaySettingsViewModel.fiatCurrency,
onItemSelected: (FiatCurrency currency) => _displaySettingsViewModel.setFiatCurrency(currency),
images: FiatCurrency.all.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")).toList(),
onItemSelected: (FiatCurrency currency) =>
_displaySettingsViewModel.setFiatCurrency(currency),
images: FiatCurrency.all
.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png"))
.toList(),
isGridView: true,
matchingCriteria: (FiatCurrency currency, String searchText) {
return currency.title.toLowerCase().contains(searchText) ||
@ -66,13 +70,14 @@ class DisplaySettingsPage extends BasePage {
selectedItem: _displaySettingsViewModel.languageCode,
onItemSelected: _displaySettingsViewModel.onLanguageSelected,
images: LanguageService.list.keys
.map((e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
.map((e) => Image.asset(
"assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
.toList(),
matchingCriteria: (String code, String searchText) {
return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
},
),
if (DeviceInfo.instance.isMobile)
if (ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile)
SettingsChoicesCell(
ChoicesListItem<ThemeBase>(
title: S.current.color_theme,

View file

@ -1,6 +1,6 @@
import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
@ -229,7 +229,7 @@ class WalletListBodyState extends State<WalletListBody> {
await hideProgressText();
// only pop the wallets route in mobile as it will go back to dashboard page
// in desktop platforms the navigation tree is different
if (DeviceInfo.instance.isMobile) {
if (ResponsiveLayoutUtil.instance.isMobile) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pop();
});

View file

@ -26,7 +26,7 @@ class AddTemplateButton extends StatelessWidget {
child: Container(
height: 34,
padding: EdgeInsets.symmetric(
horizontal: ResponsiveLayoutUtil.instance.isMobile(context) ? 10 : 30),
horizontal: ResponsiveLayoutUtil.instance.isMobile ? 10 : 30),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),

View file

@ -1,6 +1,6 @@
import 'dart:io';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/routes.dart';
@ -105,7 +105,7 @@ class AddressTextField extends StatelessWidget {
width: prefixIconWidth * options.length +
(spaceBetweenPrefixIcons * options.length),
child: Row(
mainAxisAlignment: DeviceInfo.instance.isMobile
mainAxisAlignment: ResponsiveLayoutUtil.instance.isMobile
? MainAxisAlignment.spaceBetween : MainAxisAlignment.end,
children: [
SizedBox(width: 5),

View file

@ -130,17 +130,16 @@ class ExceptionHandler {
_ignoredErrors.any((element) => error.contains(element));
static const List<String> _ignoredErrors = const [
"errno = 9", // SocketException: Bad file descriptor
"errno = 28", // OS Error: No space left on device
"errno = 32", // SocketException: Write failed (OS Error: Broken pipe)
"errno = 49", // SocketException: Can't assign requested address
"errno = 54", // SocketException: Connection reset by peer
"errno = 57", // SocketException: Read failed (OS Error: Socket is not connected)
"errno = 60", // SocketException: Operation timed out
"errno = 65", // SocketException: No route to host
"errno = 103", // SocketException: Software caused connection abort
"errno = 104", // SocketException: Connection reset by peer
"errno = 110", // SocketException: Connection timed out
"Bad file descriptor",
"No space left on device",
"Write failed (OS Error: Broken pipe)",
"Can't assign requested address",
"Read failed (OS Error: Socket is not connected)",
"Operation timed out",
"No route to host",
"Software caused connection abort",
"Connection reset by peer",
"Connection timed out",
"Connection reset by peer",
"Connection closed before full header was received",
"Connection terminated during handshake",

View file

@ -1,33 +1,35 @@
import 'package:flutter/material.dart';
class ResponsiveLayoutUtil {
static const double _kMobileThreshold = 900;
static const double _kMobileThreshold = 768;
static const double kDesktopMaxWidthConstraint = 400;
static const double kPopupWidth = 400;
static const double kPopupSpaceHeight = 100;
static const _kIpadMaxWidth = 2560.0;
const ResponsiveLayoutUtil._();
static final instance = ResponsiveLayoutUtil._();
bool isMobile(BuildContext context) {
final MediaQueryData mediaQueryData = MediaQuery.of(context);
return mediaQueryData.size.width < _kMobileThreshold;
bool get isMobile =>
WidgetsBinding.instance.platformDispatcher.views.first.physicalSize.width < _kMobileThreshold;
bool get isIpad {
final width = WidgetsBinding.instance.platformDispatcher.views.first.physicalSize.width;
return width >= _kMobileThreshold && !(width > _kIpadMaxWidth);
}
/// Returns dynamic size.
///
/// If screen size is mobile, it returns 66% ([scale]) of the [originalValue].
double getDynamicSize(
BuildContext context,
double originalValue, {
double? mobileSize,
double? scale,
}) {
scale ??= 2 / 3;
mobileSize ??= originalValue * scale;
final value = isMobile(context) ? mobileSize : originalValue;
final value = isMobile ? mobileSize : originalValue;
return value.roundToDouble();
}