diff --git a/README.md b/README.md index a8432e75e..96f59e704 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,10 @@ Edit the applicable `strings_XX.arb` file in `res/values/` and open a pull reque - Japanese - Chinese - Korean +- Thai - Arabic -- Burmese - Turkish +- Burmese ## Add a new language diff --git a/lib/main.dart b/lib/main.dart index f3fb3acdd..a8d0064f4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,14 +1,22 @@ import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:isolate'; import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/entities/language_service.dart'; import 'package:cake_wallet/buy/order.dart'; +import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/ionia/ionia_category.dart'; import 'package:cake_wallet/ionia/ionia_merchant.dart'; +import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/store/yat/yat_store.dart'; +import 'package:cake_wallet/themes/theme_list.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_mailer/flutter_mailer.dart'; import 'package:hive/hive.dart'; import 'package:cake_wallet/di.dart'; import 'package:path_provider/path_provider.dart'; @@ -44,9 +52,22 @@ final rootKey = GlobalKey(); final RouteObserver routeObserver = RouteObserver(); Future main() async { - try { + + await runZonedGuarded(() async { WidgetsFlutterBinding.ensureInitialized(); + FlutterError.onError = (errorDetails) { + _onError(errorDetails); + }; + + /// A callback that is invoked when an unhandled error occurs in the root + /// isolate. + PlatformDispatcher.instance.onError = (error, stack) { + _onError(FlutterErrorDetails(exception: error, stack: stack)); + + return true; + }; + final appDir = await getApplicationDocumentsDirectory(); await Hive.close(); Hive.init(appDir.path); @@ -132,20 +153,86 @@ Future main() async { secureStorage: secureStorage, initialMigrationVersion: 19); runApp(App()); - } catch (e, stacktrace) { - runApp(MaterialApp( - debugShowCheckedModeBanner: true, - home: Scaffold( - body: Container( - margin: - EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20), - child: Text( - 'Error:\n${e.toString()}\nStacktrace: $stacktrace', - style: TextStyle(fontSize: 22), - ))))); + }, (error, stackTrace) async { + _onError(FlutterErrorDetails(exception: error, stack: stackTrace)); + }); +} + +void _saveException(String? error, StackTrace? stackTrace) async { + final appDocDir = await getApplicationDocumentsDirectory(); + + final file = File('${appDocDir.path}/error.txt'); + final exception = { + "${DateTime.now()}": { + "Error": error, + "StackTrace": stackTrace.toString(), + } + }; + + const String separator = + '''\n\n========================================================== + ==========================================================\n\n'''; + + await file.writeAsString( + jsonEncode(exception) + separator, + mode: FileMode.append, + ); +} + +void _sendExceptionFile() async { + try { + final appDocDir = await getApplicationDocumentsDirectory(); + + final file = File('${appDocDir.path}/error.txt'); + + final MailOptions mailOptions = MailOptions( + subject: 'Mobile App Issue', + recipients: ['support@cakewallet.com'], + attachments: [file.path], + ); + + final result = await FlutterMailer.send(mailOptions); + + // Clear file content if the error was sent or saved. + // On android we can't know if it was sent or saved + if (result.name == MailerResponse.sent.name || + result.name == MailerResponse.saved.name || + result.name == MailerResponse.android.name) { + file.writeAsString("", mode: FileMode.write); + } + } catch (e, s) { + _saveException(e.toString(), s); } } +void _onError(FlutterErrorDetails errorDetails) { + _saveException(errorDetails.exception.toString(), errorDetails.stack); + + WidgetsBinding.instance.addPostFrameCallback( + (timeStamp) { + showPopUp( + context: navigatorKey.currentContext!, + builder: (context) { + return AlertWithTwoActions( + isDividerExist: true, + alertTitle: S.of(context).error, + alertContent: S.of(context).error_dialog_content, + rightButtonText: S.of(context).send, + leftButtonText: S.of(context).do_not_send, + actionRightButton: () { + Navigator.of(context).pop(); + _sendExceptionFile(); + }, + actionLeftButton: () { + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + ); +} + Future initialSetup( {required SharedPreferences sharedPreferences, required Box nodes, diff --git a/lib/src/screens/nodes/widgets/node_list_row.dart b/lib/src/screens/nodes/widgets/node_list_row.dart index 580aba170..90bb3eba1 100644 --- a/lib/src/screens/nodes/widgets/node_list_row.dart +++ b/lib/src/screens/nodes/widgets/node_list_row.dart @@ -1,9 +1,5 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/src/screens/nodes/widgets/node_indicator.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class NodeListRow extends StandardListRow { @@ -23,7 +19,7 @@ class NodeListRow extends StandardListRow { builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.done: - return NodeIndicator(isLive: (snapshot.data as bool)??false); + return NodeIndicator(isLive: (snapshot.data as bool?) ?? false); default: return NodeIndicator(isLive: false); } @@ -40,7 +36,7 @@ class NodeHeaderListRow extends StandardListRow { return SizedBox( width: 20, child: Icon(Icons.add, - color: Theme.of(context).accentTextTheme!.subtitle1!.color!, size: 24.0), + color: Theme.of(context).accentTextTheme.subtitle1?.color, size: 24.0), ); } } diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 8c9b75379..b37fd519c 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -61,6 +61,7 @@ dependencies: permission_handler: ^10.0.0 device_display_brightness: ^0.0.6 platform_device_id: ^1.0.1 + flutter_mailer: ^2.0.2 cake_backup: git: url: https://github.com/cake-tech/cake_backup.git diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 2e71e8ce9..a3fd4f585 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "Die Währung Ihres aktuellen Wallets stimmt nicht mit der des gescannten QR überein", "orbot_running_alert": "Bitte stellen Sie sicher, dass Orbot läuft, bevor Sie sich mit diesem Knoten verbinden.", "contact_list_contacts": "Kontakte", - "contact_list_wallets": "Meine Geldbörsen" + "contact_list_wallets": "Meine Geldbörsen", + "do_not_send": "Nicht senden", + "error_dialog_content": "Hoppla, wir haben einen Fehler.\n\nBitte senden Sie den Absturzbericht an unser Support-Team, um die Anwendung zu verbessern." } diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index a2b1cc702..87629cbd8 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "Your current wallet's currency does not match that of the scanned QR", "orbot_running_alert": "Please make sure Orbot is running prior to connecting to this node.", "contact_list_contacts": "Contacts", - "contact_list_wallets": "My Wallets" + "contact_list_wallets": "My Wallets", + "do_not_send": "Don't send", + "error_dialog_content": "Oops, we got some error.\n\nPlease send the crash report to our support team to make the application better." } diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 6cbfa627a..b6d4cd358 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "La moneda de su billetera actual no coincide con la del QR escaneado", "orbot_running_alert": "Asegúrese de que Orbot se esté ejecutando antes de conectarse a este nodo.", "contact_list_contacts": "Contactos", - "contact_list_wallets": "Mis billeteras" + "contact_list_wallets": "Mis billeteras", + "do_not_send": "no enviar", + "error_dialog_content": "Vaya, tenemos un error.\n\nEnvíe el informe de bloqueo a nuestro equipo de soporte para mejorar la aplicación." } diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 185466813..7b9e8da07 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -678,5 +678,7 @@ "orbot_running_alert": "Veuillez vous assurer qu'Orbot est en cours d'exécution avant de vous connecter à ce nœud.", "unmatched_currencies": "La devise de votre portefeuille (wallet) actuel ne correspond pas à celle du QR code scanné", "contact_list_contacts": "Contacts", - "contact_list_wallets": "Mes portefeuilles (wallets)" + "contact_list_wallets": "Mes portefeuilles (wallets)", + "do_not_send": "N'envoyez pas", + "error_dialog_content": "Oups, nous avons eu une erreur.\n\nVeuillez envoyer le rapport de plantage à notre équipe d'assistance pour améliorer l'application." } diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index e906b3cc4..c8e454aae 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -680,5 +680,7 @@ "orbot_running_alert": "कृपया सुनिश्चित करें कि इस नोड से कनेक्ट करने से पहले Orbot चल रहा है।", "unmatched_currencies": "आपके वर्तमान वॉलेट की मुद्रा स्कैन किए गए क्यूआर से मेल नहीं खाती" , "contact_list_contacts": "संपर्क", - "contact_list_wallets": "मेरा बटुआ" + "contact_list_wallets": "मेरा बटुआ", + "do_not_send": "मत भेजो", + "error_dialog_content": "ओह, हमसे कुछ गड़बड़ी हुई है.\n\nएप्लिकेशन को बेहतर बनाने के लिए कृपया क्रैश रिपोर्ट हमारी सहायता टीम को भेजें।" } diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index b44d2d6c3..239a175c2 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "Valuta vašeg trenutnog novčanika ne odgovara onoj na skeniranom QR-u", "orbot_running_alert": "Provjerite radi li Orbot prije spajanja na ovaj čvor.", "contact_list_contacts": "Kontakti", - "contact_list_wallets": "Moji novčanici" + "contact_list_wallets": "Moji novčanici", + "do_not_send": "Ne šalji", + "error_dialog_content": "Ups, imamo grešku.\n\nPošaljite izvješće o padu našem timu za podršku kako bismo poboljšali aplikaciju." } diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 6885fefa8..f3ddf8af2 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "La valuta del tuo portafoglio attuale non corrisponde a quella del QR scansionato", "orbot_running_alert": "Assicurati che Orbot sia in esecuzione prima di connetterti a questo nodo.", "contact_list_contacts": "Contatti", - "contact_list_wallets": "I miei portafogli" + "contact_list_wallets": "I miei portafogli", + "do_not_send": "Non inviare", + "error_dialog_content": "Ups, imamo grešku.\n\nPošaljite izvješće o padu našem timu za podršku kako bismo poboljšali aplikaciju." } diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index f02b76598..b3746aaa1 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "現在のウォレットの通貨がスキャンされたQRの通貨と一致しません", "orbot_running_alert": "このノードに接続する前に、Orbot が実行されていることを確認してください", "contact_list_contacts": "連絡先", - "contact_list_wallets": "マイウォレット" + "contact_list_wallets": "マイウォレット", + "do_not_send": "送信しない", + "error_dialog_content": "Spiacenti, abbiamo riscontrato un errore.\n\nSi prega di inviare il rapporto sull'arresto anomalo al nostro team di supporto per migliorare l'applicazione." } diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index b7678fa85..db6778fd6 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "현재 지갑의 통화가 스캔한 QR의 통화와 일치하지 않습니다.", "orbot_running_alert": "이 노드에 연결하기 전에 Orbot이 실행 중인지 확인하십시오.", "contact_list_contacts": "콘택트 렌즈", - "contact_list_wallets": "내 지갑" + "contact_list_wallets": "내 지갑", + "do_not_send": "보내지 마세요", + "error_dialog_content": "죄송합니다. 오류가 발생했습니다.\n\n응용 프로그램을 개선하려면 지원 팀에 충돌 보고서를 보내주십시오." } diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 802c0e9ac..faac8f702 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "De valuta van uw huidige portemonnee komt niet overeen met die van de gescande QR", "orbot_running_alert": "Zorg ervoor dat Orbot actief is voordat u verbinding maakt met dit knooppunt.", "contact_list_contacts": "Contacten", - "contact_list_wallets": "Mijn portefeuilles" + "contact_list_wallets": "Mijn portefeuilles", + "do_not_send": "Niet sturen", + "error_dialog_content": "Oeps, er is een fout opgetreden.\n\nStuur het crashrapport naar ons ondersteuningsteam om de applicatie te verbeteren." } diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 1b49c6ef1..0f0e14959 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -680,5 +680,7 @@ "tor_only": "Tylko sieć Tor", "unmatched_currencies": "Waluta Twojego obecnego portfela nie zgadza się z waluctą zeskanowanego kodu QR", "contact_list_contacts": "Łączność", - "contact_list_wallets": "Moje portfele" + "contact_list_wallets": "Moje portfele", + "do_not_send": "Nie wysyłaj", + "error_dialog_content": "Ups, wystąpił błąd.\n\nPrześlij raport o awarii do naszego zespołu wsparcia, aby ulepszyć aplikację." } diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 8daba6193..90d477369 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -679,5 +679,7 @@ "unmatched_currencies": "A moeda da sua carteira atual não corresponde à do QR digitalizado", "orbot_running_alert": "Certifique-se de que o Orbot esteja em execução antes de se conectar a este nó.", "contact_list_contacts": "Contatos", - "contact_list_wallets": "minhas carteiras" + "contact_list_wallets": "minhas carteiras", + "do_not_send": "não envie", + "error_dialog_content": "Ops, houve algum erro.\n\nPor favor, envie o relatório de falha para nossa equipe de suporte para melhorar o aplicativo." } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 17640af6d..8789dd4a0 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "Валюта вашего текущего кошелька не соответствует валюте отсканированного QR-кода.", "orbot_running_alert": "Перед подключением к этому узлу убедитесь, что Orbot запущен.", "contact_list_contacts": "Контакты", - "contact_list_wallets": "Мои кошельки" + "contact_list_wallets": "Мои кошельки", + "do_not_send": "Не отправлять", + "error_dialog_content": "Ой, у нас какая-то ошибка.\n\nПожалуйста, отправьте отчет о сбое в нашу службу поддержки, чтобы сделать приложение лучше." } diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 6934d9630..5e1428fac 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -678,5 +678,7 @@ "unmatched_currencies" : "สกุลเงินของกระเป๋าปัจจุบันของคุณไม่ตรงกับของ QR ที่สแกน", "orbot_running_alert": "โปรดตรวจสอบว่า Orbot กำลังทำงานก่อนที่จะเชื่อมต่อกับโหนดนี้", "contact_list_contacts": "ติดต่อ", - "contact_list_wallets": "กระเป๋าเงินของฉัน" + "contact_list_wallets": "กระเป๋าเงินของฉัน", + "do_not_send": "อย่าส่ง", + "error_dialog_content": "อ๊ะ เราพบข้อผิดพลาดบางอย่าง\n\nโปรดส่งรายงานข้อขัดข้องไปยังทีมสนับสนุนของเราเพื่อปรับปรุงแอปพลิเคชันให้ดียิ่งขึ้น" } diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index b9311e8ef..b6ac3a511 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -679,5 +679,7 @@ "unmatched_currencies": "Валюта вашого гаманця не збігається з валютою сканованого QR-коду", "orbot_running_alert": "Перед підключенням до цього вузла переконайтеся, що Orbot запущено.", "contact_list_contacts": "Контакти", - "contact_list_wallets": "Мої гаманці" + "contact_list_wallets": "Мої гаманці", + "do_not_send": "Не надсилайте", + "error_dialog_content": "На жаль, ми отримали помилку.\n\nБудь ласка, надішліть звіт про збій нашій команді підтримки, щоб покращити додаток." } diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 5b6608671..ba2f3f839 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -678,5 +678,7 @@ "unmatched_currencies": "您当前钱包的货币与扫描的 QR 的货币不匹配", "orbot_running_alert": "请确保 Orbot 在连接到此节点之前正在运行。", "contact_list_contacts": "联系人", - "contact_list_wallets": "我的钱包" + "contact_list_wallets": "我的钱包", + "do_not_send": "不要发送", + "error_dialog_content": "糟糕,我们遇到了一些错误。\n\n请将崩溃报告发送给我们的支持团队,以改进应用程序。" }