Generic fixes (#1173)

* - Catch get balance network issues
- Disable remove button when adding node

* Update packages and android gradle version
minor enhancements

* Backup issue fix

* update workflow java version

* Remove useless permission check for saving file

* minor enhancements

* only delete secure storage key before overriding it on MacOS

* Minor UI changes

* Remove debug prints [skip ci]

* Revert FR localization changes
This commit is contained in:
Omar Hatem 2023-11-18 00:15:15 +02:00 committed by GitHub
parent 539eb9b3eb
commit e092509264
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 168 additions and 116 deletions

View file

@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: '8.x'
java-version: '11.x'
- name: Flutter action
uses: subosito/flutter-action@v1

View file

@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: "8.x"
java-version: "11.x"
- name: Flutter action
uses: subosito/flutter-action@v1

View file

@ -75,7 +75,6 @@ android {
shrinkResources false
minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}

View file

@ -3,6 +3,7 @@
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

View file

@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.6.21'
ext.kotlin_version = '1.7.10'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.3'
classpath 'com.android.tools.build:gradle:7.3.0'
classpath 'com.google.gms:google-services:4.3.8'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}

View file

@ -38,8 +38,13 @@ class EthereumClient {
// });
}
Future<EtherAmount> getBalance(EthereumAddress address) async =>
await _client!.getBalance(address);
Future<EtherAmount> getBalance(EthereumAddress address) async {
try {
return await _client!.getBalance(address);
} catch (_) {
return EtherAmount.zero();
}
}
Future<int> getGasUnitPrice() async {
try {

View file

@ -2,14 +2,14 @@ group 'com.cakewallet.cw_haven'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.3.50'
ext.kotlin_version = '1.7.10'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View file

@ -2,14 +2,14 @@ group 'com.cakewallet.monero'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.3.50'
ext.kotlin_version = '1.7.10'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.4'
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View file

@ -2,14 +2,14 @@ group 'com.cakewallet.cw_shared_external'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.3.50'
ext.kotlin_version = '1.7.10'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:cake_wallet/core/totp_request_details.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
@ -40,7 +42,9 @@ class AuthService with Store {
final encodedPassword = encodedPinCode(pin: password);
// secure storage has a weird bug on macOS, where overwriting a key doesn't work, unless
// we delete what's there first:
await secureStorage.delete(key: key);
if (Platform.isMacOS) {
await secureStorage.delete(key: key);
}
await secureStorage.write(key: key, value: encodedPassword);
}

View file

@ -295,7 +295,7 @@ class BackupService {
await _sharedPreferences.setInt(
PreferencesKey.currentTransactionPriorityKeyLegacy, currentTransactionPriorityKeyLegacy);
if (Platform.isMacOS || Platform.isLinux) {
if (DeviceInfo.instance.isDesktop) {
await _sharedPreferences.setBool(PreferencesKey.allowBiometricalAuthenticationKey, false);
} else if (allowBiometricalAuthentication != null) {
await _sharedPreferences.setBool(

View file

@ -6,7 +6,6 @@ import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/ionia/ionia_api.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/ionia/ionia_category.dart';
import 'package:platform_device_id/platform_device_id.dart';
class IoniaService {
IoniaService(this.secureStorage, this.ioniaApi);
@ -112,9 +111,9 @@ class IoniaService {
required String currency}) async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
final deviceId = await PlatformDeviceId.getDeviceId;
final deviceId = '';
return ioniaApi.purchaseGiftCard(
requestedUUID: deviceId!,
requestedUUID: deviceId,
merchId: merchId,
amount: amount,
currency: currency,

View file

@ -7,7 +7,7 @@ import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/balance.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/sync_status.dart';
import 'package:wakelock/wakelock.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
ReactionDisposer? _onWalletSyncStatusChangeReaction;
@ -27,10 +27,10 @@ void startWalletSyncStatusChangeReaction(
}
}
if (status is SyncingSyncStatus) {
await Wakelock.enable();
await WakelockPlus.enable();
}
if (status is SyncedSyncStatus || status is FailedSyncStatus) {
await Wakelock.disable();
await WakelockPlus.disable();
}
} catch(e) {
print(e.toString());

View file

@ -17,7 +17,6 @@ import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:permission_handler/permission_handler.dart';
class BackupPage extends BasePage {
BackupPage(this.backupViewModelBase);
@ -129,15 +128,8 @@ class BackupPage extends BasePage {
alertTitle: S.of(context).export_backup,
alertContent: S.of(context).select_destination,
rightButtonText: S.of(context).save_to_downloads,
leftButtonText:S.of(context).share,
leftButtonText: S.of(context).share,
actionRightButton: () async {
final permission = await Permission.storage.request();
if (permission.isDenied) {
Navigator.of(dialogContext).pop();
return;
}
await backupViewModelBase.saveToDownload(backup.name, backup.content);
Navigator.of(dialogContext).pop();
},

View file

@ -34,16 +34,6 @@ class BuyOptionsPage extends BasePage {
constraints: BoxConstraints(maxWidth: 330),
child: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 24),
child: OptionTile(
image: iconRobinhood,
title: "Robinhood Connect",
description: S.of(context).robinhood_option_description,
onPressed: () async =>
await getIt.get<RobinhoodBuyProvider>().launchProvider(context),
),
),
Padding(
padding: EdgeInsets.only(top: 24),
child: OptionTile(
@ -54,6 +44,16 @@ class BuyOptionsPage extends BasePage {
await getIt.get<OnRamperBuyProvider>().launchProvider(context),
),
),
Padding(
padding: EdgeInsets.only(top: 24),
child: OptionTile(
image: iconRobinhood,
title: "Robinhood Connect",
description: S.of(context).robinhood_option_description,
onPressed: () async =>
await getIt.get<RobinhoodBuyProvider>().launchProvider(context),
),
),
Spacer(),
Padding(
padding: EdgeInsets.fromLTRB(24, 24, 24, 32),

View file

@ -15,7 +15,7 @@ class MoneroAccountListPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
double itemHeight = 80;
double itemHeight = 65;
double buttonHeight = 62;
return Observer(builder: (_) {
@ -31,7 +31,7 @@ class MoneroAccountListPage extends StatelessWidget {
child: ListView.separated(
padding: EdgeInsets.zero,
controller: controller,
separatorBuilder: (context, index) => const VerticalSectionDivider(),
separatorBuilder: (context, index) => const HorizontalSectionDivider(),
itemCount: accounts.length,
itemBuilder: (context, index) {
final account = accounts[index];

View file

@ -1,5 +1,4 @@
import 'package:cake_wallet/themes/extensions/account_list_theme.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:cake_wallet/generated/i18n.dart';
@ -33,7 +32,7 @@ class AccountTile extends StatelessWidget {
final Widget cell = GestureDetector(
onTap: onTap,
child: Container(
height: 77,
height: 60,
width: double.infinity,
padding: EdgeInsets.only(left: 24, right: 24),
color: color,

View file

@ -78,7 +78,7 @@ class NodeCreateOrEditPage extends BasePage {
'assets/images/qr_code_icon.png',
),
);
final NodeCreateOrEditViewModel nodeCreateOrEditViewModel;
final Node? editingNode;
final bool? isSelected;
@ -133,27 +133,20 @@ class NodeCreateOrEditPage extends BasePage {
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: Container(
padding: EdgeInsets.only(right: 8.0),
child: LoadingPrimaryButton(
child: Container(
padding: EdgeInsets.only(right: 8.0),
child: LoadingPrimaryButton(
onPressed: () async {
final confirmed = await showPopUp<bool>(
context: context,
builder: (BuildContext context) {
return AlertWithTwoActions(
alertTitle:
S.of(context).remove_node,
alertContent: S
.of(context)
.remove_node_message,
rightButtonText:
S.of(context).remove,
leftButtonText:
S.of(context).cancel,
actionRightButton: () =>
Navigator.pop(context, true),
actionLeftButton: () =>
Navigator.pop(context, false));
alertTitle: S.of(context).remove_node,
alertContent: S.of(context).remove_node_message,
rightButtonText: S.of(context).remove,
leftButtonText: S.of(context).cancel,
actionRightButton: () => Navigator.pop(context, true),
actionLeftButton: () => Navigator.pop(context, false));
}) ??
false;
@ -163,11 +156,14 @@ class NodeCreateOrEditPage extends BasePage {
}
},
text: S.of(context).delete,
isDisabled: !nodeCreateOrEditViewModel.isReady ||
isDisabled: editingNode == null ||
!nodeCreateOrEditViewModel.isReady ||
(isSelected ?? false),
color: Palette.red,
textColor: Colors.white),
)),
textColor: Colors.white,
),
),
),
Flexible(
child: Container(
padding: EdgeInsets.only(left: 8.0),

View file

@ -4,7 +4,6 @@ import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/view_model/restore_from_backup_view_model.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
@ -31,10 +30,11 @@ class RestoreFromBackupPage extends BasePage {
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertContent: state.error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
alertTitle: S.of(context).error,
alertContent: state.error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop(),
);
});
});
}
@ -44,42 +44,97 @@ class RestoreFromBackupPage extends BasePage {
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
child: Padding(
padding: EdgeInsets.only(bottom: 24, left: 24, right: 24),
child: Column(children: [
padding: EdgeInsets.only(bottom: 24, left: 24, right: 24),
child: Column(
children: [
Expanded(
child: Container(
child: Center(
child: TextFormField(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
obscureText: true,
enableSuggestions: false,
autocorrect: false,
decoration: InputDecoration(
hintText: S.of(context).enter_backup_password),
decoration:
InputDecoration(hintText: S.of(context).enter_backup_password),
keyboardType: TextInputType.visiblePassword,
controller: textEditingController,
style: TextStyle(fontSize: 26, color: Colors.black))),
style: TextStyle(fontSize: 26, color: Colors.black),
),
Observer(
builder: (_) {
if (restoreFromBackupViewModel.filePath.isNotEmpty) {
return Column(
children: [
const SizedBox(height: 100),
Row(
children: [
Text(
"File Name: ",
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: titleColor(context),
),
),
Expanded(
child: Text(
restoreFromBackupViewModel.filePath.split("/").last,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: titleColor(context),
),
),
),
],
),
],
);
}
return const SizedBox();
},
),
],
),
),
),
),
Container(
child: Row(children: [
Expanded(
child: PrimaryButton(
child: Row(
children: [
Expanded(
child: PrimaryButton(
onPressed: () => presentFilePicker(),
text: S.of(context).select_backup_file,
color: Colors.grey,
textColor: Colors.white)),
SizedBox(width: 20),
Expanded(child: Observer(builder: (_) {
return LoadingPrimaryButton(
isLoading:
restoreFromBackupViewModel.state is IsExecutingState,
onPressed: () => onImportHandler(context),
text: S.of(context).import,
color: Theme.of(context).primaryColor,
textColor: Colors.white);
}))
])),
])),
textColor: Colors.white,
),
),
SizedBox(width: 20),
Expanded(
child: Observer(
builder: (_) {
return LoadingPrimaryButton(
isLoading: restoreFromBackupViewModel.state is IsExecutingState,
onPressed: () => onImportHandler(context),
text: S.of(context).import,
color: Theme.of(context).primaryColor,
textColor: Colors.white);
},
),
),
],
),
),
],
),
),
),
);
}
@ -87,7 +142,7 @@ class RestoreFromBackupPage extends BasePage {
Future<void> presentFilePicker() async {
final result = await FilePicker.platform.pickFiles();
if (result?.files?.isEmpty ?? true) {
if (result?.files.isEmpty ?? true) {
return;
}
@ -95,8 +150,7 @@ class RestoreFromBackupPage extends BasePage {
}
Future<void> onImportHandler(BuildContext context) async {
if (textEditingController.text.isEmpty ||
(restoreFromBackupViewModel.filePath.isEmpty ?? true)) {
if (textEditingController.text.isEmpty || (restoreFromBackupViewModel.filePath.isEmpty)) {
await showPopUp<void>(
context: context,
builder: (_) {

View file

@ -21,7 +21,6 @@ class RestoreOptionsPage extends BasePage {
@override
String get title => S.current.restore_restore_wallet;
final bool isNewInstall;
final imageSeedKeys = Image.asset('assets/images/restore_wallet_image.png');
final imageBackup = Image.asset('assets/images/backup.png');
@ -38,8 +37,7 @@ class RestoreOptionsPage extends BasePage {
child: Column(
children: <Widget>[
OptionTile(
onPressed: () => Navigator.pushNamed(
context, Routes.restoreWalletFromSeedKeys,
onPressed: () => Navigator.pushNamed(context, Routes.restoreWalletFromSeedKeys,
arguments: isNewInstall),
image: imageSeedKeys,
title: S.of(context).restore_title_from_seed_keys,
@ -58,7 +56,7 @@ class RestoreOptionsPage extends BasePage {
child: OptionTile(
onPressed: () async {
bool isCameraPermissionGranted =
await PermissionHandler.checkPermission(Permission.camera, context);
await PermissionHandler.checkPermission(Permission.camera, context);
if (!isCameraPermissionGranted) return;
bool isPinSet = false;
if (isNewInstall) {
@ -73,7 +71,8 @@ class RestoreOptionsPage extends BasePage {
final restoreWallet =
await WalletRestoreFromQRCode.scanQRCodeForRestoring(context);
final restoreFromQRViewModel = getIt.get<WalletRestorationFromQRVM>(param1: restoreWallet.type);
final restoreFromQRViewModel =
getIt.get<WalletRestorationFromQRVM>(param1: restoreWallet.type);
await restoreFromQRViewModel.create(restoreWallet: restoreWallet);
if (restoreFromQRViewModel.state is FailureState) {

View file

@ -3,7 +3,6 @@ import 'dart:ui';
import 'package:cake_wallet/src/widgets/section_divider.dart';
import 'package:cake_wallet/themes/extensions/alert_theme.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
class BaseAlertDialog extends StatelessWidget {
String get titleText => '';
@ -49,7 +48,7 @@ class BaseAlertDialog extends StatelessWidget {
Widget actionButtons(BuildContext context) {
return Container(
height: 52,
height: 60,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,

View file

@ -52,7 +52,7 @@ class OptionTile extends StatelessWidget {
child: Text(
description,
style: TextStyle(
fontSize: 16,
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context).extension<OptionTileTheme>()!.descriptionColor,
),

View file

@ -17,7 +17,9 @@ class PermissionHandler {
var status = await permission.status;
if (status.isDenied) {
status = await permission.request();
try {
status = await permission.request();
} catch (_) {}
}
if (status.isPermanentlyDenied || status.isDenied) {

View file

@ -12,13 +12,12 @@ import devicelocale
import flutter_secure_storage_macos
import in_app_review
import package_info
import package_info_plus
import path_provider_foundation
import platform_device_id
import platform_device_id_macos
import share_plus_macos
import shared_preferences_foundation
import url_launcher_macos
import wakelock_macos
import wakelock_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
@ -28,11 +27,10 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
PlatformDeviceIdMacosPlugin.register(with: registry.registrar(forPlugin: "PlatformDeviceIdMacosPlugin"))
PlatformDeviceIdMacosPlugin.register(with: registry.registrar(forPlugin: "PlatformDeviceIdMacosPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
}

View file

@ -60,16 +60,21 @@ dependencies:
another_flushbar: ^1.12.29
archive: ^3.3.0
cryptography: ^2.0.5
file_picker: ^5.2.5
file_picker:
git:
url: https://github.com/cake-tech/flutter_file_picker.git
ref: master
unorm_dart: ^0.2.0
# check unorm_dart for usage and for replace
permission_handler: ^10.0.0
device_display_brightness: ^0.0.6
device_display_brightness:
git:
url: https://github.com/cake-tech/device_display_brightness.git
ref: master
workmanager: ^0.5.1
platform_device_id: ^1.0.1
wakelock: ^0.6.2
wakelock_plus: ^1.1.3
flutter_mailer: ^2.0.2
device_info_plus: 8.1.0
device_info_plus: ^9.1.0
base32: 2.1.3
in_app_review: ^2.0.6
cake_backup:

View file

@ -722,8 +722,8 @@
"awaitDAppProcessing": "Veuillez attendre que l'application décentralisée (dApp) termine le traitement.",
"copyWalletConnectLink": "Copiez le lien WalletConnect depuis l'application décentralisée (dApp) et collez-le ici",
"enterWalletConnectURI": "Saisissez l'URI de WalletConnect.",
"seed_key": "Clé de graines",
"enter_seed_phrase": "Entrez votre phrase de semence",
"seed_key": "Clé secrète (seed key)",
"enter_seed_phrase": "Entrez votre phrase secrète (seed)",
"change_rep_successful": "Représentant changé avec succès",
"add_contact": "Ajouter le contact",
"exchange_provider_unsupported": "${providerName} n'est plus pris en charge !",