From 5d09341277ecd001ccacc8d8dabd7892cb9956b9 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Sun, 14 Aug 2022 20:43:34 -0700 Subject: [PATCH 1/2] fix importBundle error handling and dupping of events --- LIBCWTCH-GO-MACOS.version | 2 +- LIBCWTCH-GO.version | 2 +- lib/errorHandler.dart | 31 ------------------------ lib/views/addcontactview.dart | 44 +++++++++++++++++++++-------------- 4 files changed, 29 insertions(+), 50 deletions(-) diff --git a/LIBCWTCH-GO-MACOS.version b/LIBCWTCH-GO-MACOS.version index b9c00d44..1f60fe4a 100644 --- a/LIBCWTCH-GO-MACOS.version +++ b/LIBCWTCH-GO-MACOS.version @@ -1 +1 @@ -2022-07-22-12-41-v1.8.0-7-g7b3e842 \ No newline at end of file +2022-08-13-14-33-v1.8.0-10-gb99e35e \ No newline at end of file diff --git a/LIBCWTCH-GO.version b/LIBCWTCH-GO.version index d6908319..78736c86 100644 --- a/LIBCWTCH-GO.version +++ b/LIBCWTCH-GO.version @@ -1 +1 @@ -2022-07-22-16-41-v1.8.0-7-g7b3e842 \ No newline at end of file +2022-08-13-18-34-v1.8.0-10-gb99e35e \ No newline at end of file diff --git a/lib/errorHandler.dart b/lib/errorHandler.dart index 156b708a..de543650 100644 --- a/lib/errorHandler.dart +++ b/lib/errorHandler.dart @@ -5,13 +5,9 @@ class ErrorHandler extends ChangeNotifier { static const String successErrorType = "success"; // Add Contact Specific Errors... - static const String addContactErrorPrefix = "addcontact"; static const String changePasswordErrorPrefix = "changepassword"; static const String invalidImportStringErrorType = "invalid_import_string"; static const String contactAlreadyExistsErrorType = "contact_already_exists"; - bool invalidImportStringError = false; - bool contactAlreadyExistsError = false; - bool explicitAddContactSuccess = false; // ChangePassword bool changePasswordError = false; @@ -31,10 +27,6 @@ class ErrorHandler extends ChangeNotifier { bool deletedServerSuccess = false; reset() { - invalidImportStringError = false; - contactAlreadyExistsError = false; - explicitAddContactSuccess = false; - importBundleError = false; importBundleSuccess = false; @@ -57,9 +49,6 @@ class ErrorHandler extends ChangeNotifier { String errorType = parts[1]; switch (prefix) { - case addContactErrorPrefix: - handleAddContactError(errorType); - break; case importBundleErrorPrefix: handleImportBundleError(errorType); break; @@ -76,26 +65,6 @@ class ErrorHandler extends ChangeNotifier { notifyListeners(); } - handleAddContactError(String errorType) { - // Reset add contact errors - invalidImportStringError = false; - contactAlreadyExistsError = false; - explicitAddContactSuccess = false; - - switch (errorType) { - case invalidImportStringErrorType: - invalidImportStringError = true; - break; - case contactAlreadyExistsErrorType: - contactAlreadyExistsError = true; - break; - case successErrorType: - explicitAddContactSuccess = true; - importBundleSuccess = true; - break; - } - } - handleImportBundleError(String errorType) { // Reset add contact errors importBundleError = false; diff --git a/lib/views/addcontactview.dart b/lib/views/addcontactview.dart index 1a8bf56a..e4db4955 100644 --- a/lib/views/addcontactview.dart +++ b/lib/views/addcontactview.dart @@ -36,6 +36,9 @@ class _AddContactViewState extends State { final ctrlrContact = TextEditingController(text: ""); final ctrlrGroupName = TextEditingController(text: ""); String server = ""; + // flutter textfield onChange often fires twice and since we need contexts, we can't easily use a controler/listener + String lastContactValue = ""; + @override Widget build(BuildContext context) { @@ -144,34 +147,41 @@ class _AddContactViewState extends State { ), CwtchTextField( testKey: Key("txtAddP2P"), + key: Key("txtAddP2P"), controller: ctrlrContact, validator: (value) { if (value == "") { return null; } - if (globalErrorHandler.invalidImportStringError) { + if (globalErrorHandler.importBundleError) { return AppLocalizations.of(context)!.invalidImportString; - } else if (globalErrorHandler.contactAlreadyExistsError) { - return AppLocalizations.of(context)!.contactAlreadyExists; - } else if (globalErrorHandler.explicitAddContactSuccess) {} + } else if (globalErrorHandler.importBundleSuccess) { return null; } return null; }, onChanged: (String importBundle) async { - var profileOnion = Provider.of(bcontext, listen: false).onion; - Provider.of(bcontext, listen: false).cwtch.ImportBundle(profileOnion, importBundle.replaceFirst("cwtch:", "")); + if (lastContactValue != importBundle) { + lastContactValue = importBundle; + var profileOnion = Provider + .of(bcontext, listen: false) + .onion; + Provider + .of(bcontext, listen: false) + .cwtch + .ImportBundle(profileOnion, importBundle.replaceFirst("cwtch:", "")); - Future.delayed(const Duration(milliseconds: 500), () { - if (globalErrorHandler.importBundleSuccess) { - // TODO: This isn't ideal, but because onChange can be fired during this future check - // and because the context can change after being popped we have this kind of double assertion... - // There is probably a better pattern to handle this... - if (AppLocalizations.of(bcontext) != null) { - final snackBar = SnackBar(content: Text(AppLocalizations.of(bcontext)!.successfullAddedContact + importBundle)); - ScaffoldMessenger.of(bcontext).showSnackBar(snackBar); - Navigator.popUntil(bcontext, (route) => route.settings.name == "conversations"); + Future.delayed(const Duration(milliseconds: 500), () { + if (globalErrorHandler.importBundleSuccess) { + // TODO: This isn't ideal, but because onChange can be fired during this future check + // and because the context can change after being popped we have this kind of double assertion... + // There is probably a better pattern to handle this... + if (AppLocalizations.of(bcontext) != null) { + final snackBar = SnackBar(content: Text(AppLocalizations.of(bcontext)!.successfullAddedContact + importBundle)); + ScaffoldMessenger.of(bcontext).showSnackBar(snackBar); + Navigator.popUntil(bcontext, (route) => route.settings.name == "conversations"); + } } - } - }); + }); + } }, hintText: '', ) From d550c23fbd8ed61a162b08ad68864d15abc48017 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 15 Aug 2022 22:33:09 -0700 Subject: [PATCH 2/2] importBundle returns result --- LIBCWTCH-GO-MACOS.version | 2 +- LIBCWTCH-GO.version | 2 +- .../kotlin/im/cwtch/flwtch/MainActivity.kt | 2 +- lib/cwtch/cwtch.dart | 2 +- lib/cwtch/ffi.dart | 11 ++++--- lib/cwtch/gomobile.dart | 4 +-- lib/errorHandler.dart | 26 ---------------- lib/views/addcontactview.dart | 31 +++++++++---------- 8 files changed, 28 insertions(+), 52 deletions(-) diff --git a/LIBCWTCH-GO-MACOS.version b/LIBCWTCH-GO-MACOS.version index 1f60fe4a..b9797578 100644 --- a/LIBCWTCH-GO-MACOS.version +++ b/LIBCWTCH-GO-MACOS.version @@ -1 +1 @@ -2022-08-13-14-33-v1.8.0-10-gb99e35e \ No newline at end of file +2022-08-16-10-59-v1.8.0-12-gf1de9b1 \ No newline at end of file diff --git a/LIBCWTCH-GO.version b/LIBCWTCH-GO.version index 78736c86..e7cb348d 100644 --- a/LIBCWTCH-GO.version +++ b/LIBCWTCH-GO.version @@ -1 +1 @@ -2022-08-13-18-34-v1.8.0-10-gb99e35e \ No newline at end of file +2022-08-16-14-59-v1.8.0-12-gf1de9b1 \ No newline at end of file diff --git a/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt b/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt index d8f50e2b..5ff736d3 100644 --- a/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt +++ b/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt @@ -442,7 +442,7 @@ class MainActivity: FlutterActivity() { "ImportBundle" -> { val profile: String = call.argument("ProfileOnion") ?: "" val bundle: String = call.argument("bundle") ?: "" - Cwtch.importBundle(profile, bundle) + result.success(Cwtch.importBundle(profile, bundle)) } "CreateGroup" -> { val profile: String = call.argument("ProfileOnion") ?: "" diff --git a/lib/cwtch/cwtch.dart b/lib/cwtch/cwtch.dart index e672438a..128ddda6 100644 --- a/lib/cwtch/cwtch.dart +++ b/lib/cwtch/cwtch.dart @@ -91,7 +91,7 @@ abstract class Cwtch { void CreateGroup(String profile, String server, String groupName); // ignore: non_constant_identifier_names - void ImportBundle(String profile, String bundle); + Future ImportBundle(String profile, String bundle); // ignore: non_constant_identifier_names void SetProfileAttribute(String profile, String key, String val); // ignore: non_constant_identifier_names diff --git a/lib/cwtch/ffi.dart b/lib/cwtch/ffi.dart index 805e33fd..0ebcb460 100644 --- a/lib/cwtch/ffi.dart +++ b/lib/cwtch/ffi.dart @@ -505,15 +505,18 @@ class CwtchFfi implements Cwtch { @override // ignore: non_constant_identifier_names - void ImportBundle(String profileOnion, String bundle) { - var importBundle = library.lookup>("c_ImportBundle"); + Future ImportBundle(String profileOnion, String bundle) async { + var importBundle = library.lookup>("c_ImportBundle"); // ignore: non_constant_identifier_names - final ImportBundle = importBundle.asFunction(); + final ImportBundle = importBundle.asFunction(); final u1 = profileOnion.toNativeUtf8(); final u2 = bundle.toNativeUtf8(); - ImportBundle(u1, u1.length, u2, u2.length); + Pointer responsePtr = ImportBundle(u1, u1.length, u2, u2.length); + String response = responsePtr.toDartString(); + _UnsafeFreePointerAnyUseOfThisFunctionMustBeDoubleApproved(responsePtr); malloc.free(u1); malloc.free(u2); + return response; } @override diff --git a/lib/cwtch/gomobile.dart b/lib/cwtch/gomobile.dart index 19515e85..16fd0f99 100644 --- a/lib/cwtch/gomobile.dart +++ b/lib/cwtch/gomobile.dart @@ -190,8 +190,8 @@ class CwtchGomobile implements Cwtch { @override // ignore: non_constant_identifier_names - void ImportBundle(String profileOnion, String bundle) { - cwtchPlatform.invokeMethod("ImportBundle", {"ProfileOnion": profileOnion, "bundle": bundle}); + Future ImportBundle(String profileOnion, String bundle) { + return cwtchPlatform.invokeMethod("ImportBundle", {"ProfileOnion": profileOnion, "bundle": bundle}); } @override diff --git a/lib/errorHandler.dart b/lib/errorHandler.dart index de543650..d5c9b0bf 100644 --- a/lib/errorHandler.dart +++ b/lib/errorHandler.dart @@ -13,11 +13,6 @@ class ErrorHandler extends ChangeNotifier { bool changePasswordError = false; bool explicitChangePasswordSuccess = false; - // Import Bundle Specific Errors - static const String importBundleErrorPrefix = "importBundle"; - bool importBundleError = false; - bool importBundleSuccess = false; - static const String deleteProfileErrorPrefix = "deleteprofile"; bool deleteProfileError = false; bool deleteProfileSuccess = false; @@ -27,9 +22,6 @@ class ErrorHandler extends ChangeNotifier { bool deletedServerSuccess = false; reset() { - importBundleError = false; - importBundleSuccess = false; - deleteProfileError = false; deleteProfileSuccess = false; @@ -49,9 +41,6 @@ class ErrorHandler extends ChangeNotifier { String errorType = parts[1]; switch (prefix) { - case importBundleErrorPrefix: - handleImportBundleError(errorType); - break; case deleteProfileErrorPrefix: handleDeleteProfileError(errorType); break; @@ -65,21 +54,6 @@ class ErrorHandler extends ChangeNotifier { notifyListeners(); } - handleImportBundleError(String errorType) { - // Reset add contact errors - importBundleError = false; - importBundleSuccess = false; - - switch (errorType) { - case successErrorType: - importBundleSuccess = true; - break; - default: - importBundleError = true; - break; - } - } - handleDeleteProfileError(String errorType) { // Reset add contact errors deleteProfileError = false; diff --git a/lib/views/addcontactview.dart b/lib/views/addcontactview.dart index e4db4955..b7a681d2 100644 --- a/lib/views/addcontactview.dart +++ b/lib/views/addcontactview.dart @@ -38,6 +38,7 @@ class _AddContactViewState extends State { String server = ""; // flutter textfield onChange often fires twice and since we need contexts, we can't easily use a controler/listener String lastContactValue = ""; + bool failedImport = false; @override @@ -153,9 +154,9 @@ class _AddContactViewState extends State { if (value == "") { return null; } - if (globalErrorHandler.importBundleError) { + if (failedImport) { return AppLocalizations.of(context)!.invalidImportString; - } else if (globalErrorHandler.importBundleSuccess) { return null; } + } return null; }, onChanged: (String importBundle) async { @@ -167,20 +168,18 @@ class _AddContactViewState extends State { Provider .of(bcontext, listen: false) .cwtch - .ImportBundle(profileOnion, importBundle.replaceFirst("cwtch:", "")); - - Future.delayed(const Duration(milliseconds: 500), () { - if (globalErrorHandler.importBundleSuccess) { - // TODO: This isn't ideal, but because onChange can be fired during this future check - // and because the context can change after being popped we have this kind of double assertion... - // There is probably a better pattern to handle this... - if (AppLocalizations.of(bcontext) != null) { - final snackBar = SnackBar(content: Text(AppLocalizations.of(bcontext)!.successfullAddedContact + importBundle)); - ScaffoldMessenger.of(bcontext).showSnackBar(snackBar); - Navigator.popUntil(bcontext, (route) => route.settings.name == "conversations"); - } - } - }); + .ImportBundle(profileOnion, importBundle.replaceFirst("cwtch:", "")).then((result) { + if (result == "importBundle.success") { + failedImport = false; + if (AppLocalizations.of(bcontext) != null) { + final snackBar = SnackBar(content: Text(AppLocalizations.of(bcontext)!.successfullAddedContact + importBundle)); + ScaffoldMessenger.of(bcontext).showSnackBar(snackBar); + Navigator.popUntil(bcontext, (route) => route.settings.name == "conversations"); + } + } else { + failedImport = true; + } + }); } }, hintText: '',