From 331029618be00919a65d3d2a19059752e04821e3 Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 19 Jan 2024 15:12:37 +0330 Subject: [PATCH 001/103] impl: Updated packages & Added network info --- pubspec.lock | 68 ++++++++++++++++++++-------------------------------- pubspec.yaml | 5 ++-- 2 files changed, 29 insertions(+), 44 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 9efd6c45..2dbfaadd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -879,6 +879,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + network_info_plus: + dependency: "direct main" + description: + name: network_info_plus + sha256: "2d9e88b9a459e5d4e224f828d26cc38ea140511e89b943116939994324be5c96" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + network_info_plus_platform_interface: + dependency: transitive + description: + name: network_info_plus_platform_interface + sha256: "881f5029c5edaf19c616c201d3d8b366c5b1384afd5c1da5a49e4345de82fb8b" + url: "https://pub.dev" + source: hosted + version: "1.1.3" nm: dependency: transitive description: @@ -915,50 +931,18 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: f62d7253edc197fe3c88d7c2ddab82d68f555e778d55390ccc3537eca8e8d637 - url: "https://pub.dev" - source: hosted - version: "1.4.3+1" - package_info_plus_linux: - dependency: transitive - description: - name: package_info_plus_linux - sha256: "04b575f44233d30edbb80a94e57cad9107aada334fc02aabb42b6becd13c43fc" + sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" url: "https://pub.dev" source: hosted - version: "1.0.5" - package_info_plus_macos: - dependency: transitive - description: - name: package_info_plus_macos - sha256: a2ad8b4acf4cd479d4a0afa5a74ea3f5b1c7563b77e52cc32b3ee6956d5482a6 - url: "https://pub.dev" - source: hosted - version: "1.3.0" + version: "4.2.0" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: f7a0c8f1e7e981bc65f8b64137a53fd3c195b18d429fba960babc59a5a1c7ae8 - url: "https://pub.dev" - source: hosted - version: "1.0.2" - package_info_plus_web: - dependency: transitive - description: - name: package_info_plus_web - sha256: f0829327eb534789e0a16ccac8936a80beed4e2401c4d3a74f3f39094a822d3b - url: "https://pub.dev" - source: hosted - version: "1.0.6" - package_info_plus_windows: - dependency: transitive - description: - name: package_info_plus_windows - sha256: "79524f11c42dd9078b96d797b3cf79c0a2883a50c4920dc43da8562c115089bc" + sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.0.1" path: dependency: transitive description: @@ -1235,18 +1219,18 @@ packages: dependency: "direct main" description: name: share_plus - sha256: b1f15232d41e9701ab2f04181f21610c36c83a12ae426b79b4bd011c567934b1 + sha256: f74fc3f1cbd99f39760182e176802f693fa0ec9625c045561cfad54681ea93dd url: "https://pub.dev" source: hosted - version: "6.3.4" + version: "7.2.1" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface - sha256: "357412af4178d8e11d14f41723f80f12caea54cf0d5cd29af9dcdab85d58aea7" + sha256: df08bc3a07d01f5ea47b45d03ffcba1fa9cd5370fb44b3f38c70e42cced0f956 url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.1" shimmer: dependency: "direct main" description: @@ -1535,10 +1519,10 @@ packages: dependency: transitive description: name: win32 - sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4 + sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "4.1.4" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 9fb46f89..0c9c97e0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -71,8 +71,9 @@ dependencies: path: packages/shared/logic mxc_ui: path: packages/shared/ui + network_info_plus: ^4.1.0 open_mail_app: ^0.4.5 - package_info_plus: ^1.0.0 + package_info_plus: ^4.2.0 path_provider: ^2.0.12 permission_handler: ^10.4.1 qr_code_scanner: ^1.0.1 @@ -81,7 +82,7 @@ dependencies: retry: ^3.1.1 riverpod: ^1.0.3 sha3: ^0.2.0 - share_plus: ^6.3.4 + share_plus: ^7.2.1 shimmer: ^2.0.0 sliver_tools: ^0.2.5 url_launcher: ^6.1.11 From f4f6979b0b492a9f8fcfdff892a782ee006bd58d Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 19 Jan 2024 15:16:45 +0330 Subject: [PATCH 002/103] impl: New ios capabilities --- ios/Runner/Runner.entitlements | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index 92267aa8..75e36a14 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -1,8 +1,10 @@ - - aps-environment - development - + + aps-environment + development + com.apple.developer.networking.wifi-info + + From 4d995816f74b9c39f1eeb98068ec79647058174c Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 19 Jan 2024 15:18:07 +0330 Subject: [PATCH 003/103] impl: wifi info test on ios --- lib/core/src/firebase/firebase.dart | 40 ++++++++++++++++++- .../notifications_presenter.dart | 1 - packages/shared | 2 +- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/lib/core/src/firebase/firebase.dart b/lib/core/src/firebase/firebase.dart index 5fc0d58b..de390819 100644 --- a/lib/core/src/firebase/firebase.dart +++ b/lib/core/src/firebase/firebase.dart @@ -5,7 +5,10 @@ import 'package:datadashwallet/common/common.dart'; import 'package:datadashwallet/core/src/notification.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; import 'package:mxc_logic/mxc_logic.dart'; +import 'package:network_info_plus/network_info_plus.dart'; import 'firebase_options.dart'; export 'firebase_options.dart'; @@ -84,11 +87,44 @@ class AXSFireBase { return isGranted; } - static void incrementBuildTap() { + static void incrementBuildTap() async { buildTap++; if (buildTap == 10) { - FlutterClipboard.copy(firebaseToken ?? ''); + FlutterClipboard.copy(await checkWifiName()); buildTap = 0; } } + + static Future checkWifiName() async { + String? wifiName, wifiBSSID; + // request permissions to get more info + final _networkInfo = NetworkInfo(); + + try { + // ignore: deprecated_member_use + var status = await _networkInfo.getLocationServiceAuthorization(); + if (status == LocationAuthorizationStatus.notDetermined) { + // ignore: deprecated_member_use + status = await _networkInfo.requestLocationServiceAuthorization(); + } + wifiName = await _networkInfo.getWifiName(); + } on PlatformException catch (e) { + wifiName = 'Failed to get Wifi Name'; + } + + try { + // ignore: deprecated_member_use + var status = await _networkInfo.getLocationServiceAuthorization(); + if (status == LocationAuthorizationStatus.notDetermined) { + // ignore: deprecated_member_use + status = await _networkInfo.requestLocationServiceAuthorization(); + } + + wifiBSSID = await _networkInfo.getWifiBSSID(); + } on PlatformException catch (e) { + wifiBSSID = 'Failed to get Wifi BSSID'; + } + + return "Wifi name: $wifiName Wifi BSSID : $wifiBSSID"; + } } diff --git a/lib/features/settings/subfeatures/notifications/notifications_presenter.dart b/lib/features/settings/subfeatures/notifications/notifications_presenter.dart index 7037396c..6e83309c 100644 --- a/lib/features/settings/subfeatures/notifications/notifications_presenter.dart +++ b/lib/features/settings/subfeatures/notifications/notifications_presenter.dart @@ -7,7 +7,6 @@ import 'package:flutter/cupertino.dart'; import 'package:datadashwallet/core/core.dart'; import 'package:background_fetch/background_fetch.dart' as bgFetch; import 'package:mxc_logic/mxc_logic.dart'; -import '../../../../main.dart'; import 'notifications_state.dart'; final notificationsContainer = diff --git a/packages/shared b/packages/shared index b97e7d8e..c8d2abe1 160000 --- a/packages/shared +++ b/packages/shared @@ -1 +1 @@ -Subproject commit b97e7d8e93c355e5bf78026df472379df3cd75e5 +Subproject commit c8d2abe1237b933819e0a49c9b6a2066d984c6c9 From a2fd1455905304842b374bf432615a7c6af4ab2b Mon Sep 17 00:00:00 2001 From: Reza <53487920+reasje@users.noreply.github.com> Date: Mon, 22 Jan 2024 12:55:38 +0330 Subject: [PATCH 004/103] test: increased version for testing wifi info --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 2e37699a..96a81cb0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 2.2.2 +version: 2.2.3 environment: sdk: ">=2.19.0 <3.0.0" From efdd8d2d00d20aa34dfc20b61205033bce3badca Mon Sep 17 00:00:00 2001 From: reasje Date: Mon, 22 Jan 2024 19:55:35 +0330 Subject: [PATCH 005/103] config : ios dapp hooks identifier --- ios/Runner/Info.plist | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index aeb2de3c..db1fd901 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -145,6 +145,7 @@ com.transistorsoft.fetch com.mxc.axswallet.periodicalTasks + com.mxc.axswallet.dappHooksTasks UIViewControllerBasedStatusBarAppearance From da956b43ef225ee32bc4ae0b9cb4d6549057d3d9 Mon Sep 17 00:00:00 2001 From: reasje Date: Wed, 24 Jan 2024 16:15:58 +0330 Subject: [PATCH 006/103] config: ios new bg task identifier --- ios/Runner/Info.plist | 16 ++++++++-------- .../notifications/notifications_presenter.dart | 5 +---- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index db1fd901..4f4f7e60 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,6 +2,12 @@ + BGTaskSchedulerPermittedIdentifiers + + com.transistorsoft.fetch + com.mxc.axswallet.periodicalTasks + com.mxc.axswallet.dappHooksTasks + CADisableMinimumFrameDurationOnPhone CFBundleDevelopmentRegion @@ -91,7 +97,7 @@ NSCalendarsUsageDescription Would you allow AXS Wallet to use the Calendar? NSCameraUsageDescription - AXS Wallet needs camera access to scan QR codes for transactions. Scanned data is stored locally and isn't shared. + AXS Wallet needs camera access to scan QR codes for transactions. Scanned data is stored locally and isn't shared. NSContactsUsageDescription Would you allow AXS Wallet to use the Contacts? NSFaceIDUsageDescription @@ -105,7 +111,7 @@ NSLocationWhenInUseUsageDescription Would you allow AXS Wallet to use the Location? NSMicrophoneUsageDescription - AXS Wallet needs microphone access to scan QR codes for transactions. Scanned data is stored locally and isn't shared. + AXS Wallet needs microphone access to scan QR codes for transactions. Scanned data is stored locally and isn't shared. NSMotionUsageDescription Would you allow AXS Wallet to use the Motion? NSPhotoLibraryAddUsageDescription @@ -141,12 +147,6 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - BGTaskSchedulerPermittedIdentifiers - - com.transistorsoft.fetch - com.mxc.axswallet.periodicalTasks - com.mxc.axswallet.dappHooksTasks - UIViewControllerBasedStatusBarAppearance diff --git a/lib/features/settings/subfeatures/notifications/notifications_presenter.dart b/lib/features/settings/subfeatures/notifications/notifications_presenter.dart index 6e83309c..c639a302 100644 --- a/lib/features/settings/subfeatures/notifications/notifications_presenter.dart +++ b/lib/features/settings/subfeatures/notifications/notifications_presenter.dart @@ -23,10 +23,7 @@ class NotificationsPresenter extends CompletePresenter ref.read(backgroundFetchConfigUseCaseProvider); late final _chainConfigurationUseCase = ref.read(chainConfigurationUseCaseProvider); - - // this is used to show the bg fetch dialog - bool noneEnabled = true; - + final TextEditingController lowBalanceController = TextEditingController(); final TextEditingController transactionFeeController = TextEditingController(); From 5a980219a4cdb7f2dfedb12af2474a460dbf6783 Mon Sep 17 00:00:00 2001 From: reasje Date: Wed, 24 Jan 2024 16:16:20 +0330 Subject: [PATCH 007/103] config: ios bg location --- ios/Runner/Info.plist | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 4f4f7e60..7bb2a80e 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -127,6 +127,7 @@ UIBackgroundModes fetch + location processing remote-notification From 1615ee0b6a1b9cb36873c0e7d489b9d21b126393 Mon Sep 17 00:00:00 2001 From: reasje Date: Wed, 24 Jan 2024 16:17:20 +0330 Subject: [PATCH 008/103] feat: Added h3 package --- pubspec.lock | 40 ++++++++++++++++++++++++++++++++++++++++ pubspec.yaml | 1 + 2 files changed, 41 insertions(+) diff --git a/pubspec.lock b/pubspec.lock index 2dbfaadd..53fa23f2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -602,6 +602,14 @@ packages: url: "https://pub.dev" source: hosted version: "10.4.0" + geojson2h3: + dependency: transitive + description: + name: geojson2h3 + sha256: "9786d9fa144f1a64063b63cfaf8e7b3ddec40d64f873f3ae9773500593080cd9" + url: "https://pub.dev" + source: hosted + version: "0.6.1" gql: dependency: transitive description: @@ -666,6 +674,38 @@ packages: url: "https://pub.dev" source: hosted version: "5.2.0-beta.4" + h3_common: + dependency: transitive + description: + name: h3_common + sha256: "1d92424c97c0db1a2f4bd1ccd51f865934d01f211be9d33edaf12a2c68f8427f" + url: "https://pub.dev" + source: hosted + version: "0.6.1" + h3_ffi: + dependency: transitive + description: + name: h3_ffi + sha256: "9b13cf77ad867d3ef3362d86771f4930398cd88b657d9e154aba4ca0bda93540" + url: "https://pub.dev" + source: hosted + version: "0.6.2" + h3_flutter: + dependency: "direct main" + description: + name: h3_flutter + sha256: ccc62394641c43fccf87fec063a639a851ba0f30ec0caa0afeb455aebe581297 + url: "https://pub.dev" + source: hosted + version: "0.6.6" + h3_web: + dependency: transitive + description: + name: h3_web + sha256: "0997e3bcebefd2dcecbb3396b9e0a9dc6d9619c5eb2dfe6809b4046e05c7b0ac" + url: "https://pub.dev" + source: hosted + version: "0.6.1" hex: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 0c9c97e0..5ef77ae0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,6 +61,7 @@ dependencies: flutter_mailer: ^2.0.2 flutter_staggered_grid_view: ^0.7.0 flutter_svg: ^2.0.1 + h3_flutter: ^0.6.6 hooks_riverpod: ^1.0.3 jdenticon_dart: ^2.0.0 local_auth: From e8843ae407d25cdd9d74d9f3df905b8a36a96eb3 Mon Sep 17 00:00:00 2001 From: reasje Date: Wed, 24 Jan 2024 19:28:27 +0330 Subject: [PATCH 009/103] config: dapp division update --- packages/shared | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared b/packages/shared index c8d2abe1..75a962ea 160000 --- a/packages/shared +++ b/packages/shared @@ -1 +1 @@ -Subproject commit c8d2abe1237b933819e0a49c9b6a2066d984c6c9 +Subproject commit 75a962ea8f80809c3be89a54aca1251cfe20562d From ebb9261fbcfa30b5d619db2d2f1e40541229e8a9 Mon Sep 17 00:00:00 2001 From: reasje Date: Thu, 25 Jan 2024 11:07:18 +0330 Subject: [PATCH 010/103] config: android bg location --- android/app/src/main/AndroidManifest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index acfeb3bf..39ad8c5c 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -27,6 +27,8 @@ + + From f7c45cac90454f2640a6f3a0b7ad0ee8a7786ea2 Mon Sep 17 00:00:00 2001 From: reasje Date: Thu, 25 Jan 2024 11:09:39 +0330 Subject: [PATCH 011/103] feat: new translation for dapp hooks --- assets/flutter_i18n/en.json | 14 ++++++++++---- .../notifications/notifications_presenter.dart | 14 ++++++++------ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/assets/flutter_i18n/en.json b/assets/flutter_i18n/en.json index 6e1504f7..8578d89a 100644 --- a/assets/flutter_i18n/en.json +++ b/assets/flutter_i18n/en.json @@ -325,9 +325,6 @@ "background_fetch_notice_title": "Optimize Your AXS Wallet Experience", "background_fetch_notice_text": "To ensure peak performance of the AXS Wallet, we recommend keeping the app active in the background and excluding it from battery optimization settings. This helps maintain seamless functionality and uninterrupted access to your wallet.", "acknowledge": "Acknowledge", - "background_notifications_service_launched_successfully": "Background notifications service launched successfully.", - "unable_to_launch_background_notification_service": "Unable to launch background notification service.", - "background_notifications_service_disabled_successfully": "Background notifications service disabled successfully.", "low_balance": "Low balance", "expected_transaction_fee": "Expected transaction fee", "expected_epoch_occur": "Expected epoch occurrence", @@ -335,5 +332,14 @@ "occurrence": "Occurrence", "frequency": "Frequency", "experiencing_issues": "Experiencing issues?", - "background_service_solution": "Try re-enabling the app or check the battery optimization settings." + "background_service_solution": "Try re-enabling the app or check the battery optimization settings.", + "dapp_hooks": "DApp hooks", + "wifi_hooks": "Wifi hooks", + "miner_hooks": "Miner hooks", + "location_permission_required_title": "Location permission required.", + "location_permission_required_text": "Oops, location permission is denied, It's essential for us to have location permission in order for wifi hooks to perform actively, Please grant location by going to settings.", + "open_settings": "Open settings", + "service_launched_successfully": "{0} service launched successfully.", + "unable_to_launch_service": "Unable to launch {0} service.", + "service_disabled_successfully": "{0} service disabled successfully." } \ No newline at end of file diff --git a/lib/features/settings/subfeatures/notifications/notifications_presenter.dart b/lib/features/settings/subfeatures/notifications/notifications_presenter.dart index c639a302..4ca90015 100644 --- a/lib/features/settings/subfeatures/notifications/notifications_presenter.dart +++ b/lib/features/settings/subfeatures/notifications/notifications_presenter.dart @@ -23,7 +23,7 @@ class NotificationsPresenter extends CompletePresenter ref.read(backgroundFetchConfigUseCaseProvider); late final _chainConfigurationUseCase = ref.read(chainConfigurationUseCaseProvider); - + final TextEditingController lowBalanceController = TextEditingController(); final TextEditingController transactionFeeController = TextEditingController(); @@ -224,22 +224,24 @@ class NotificationsPresenter extends CompletePresenter void showBGFetchFailureSnackBar() { showSnackBar( context: context!, - content: translate('unable_to_launch_background_notification_service')!, + content: translate('unable_to_launch_service')! + .replaceAll('{0}', translate('background_notifications')!) + .toLowerCase(), type: SnackBarType.fail); } void showBGFetchSuccessSnackBar() { showSnackBar( context: context!, - content: translate( - 'background_notifications_service_launched_successfully')!); + content: translate('service_launched_successfully')! + .replaceAll('{0}', translate('background_notifications')!)); } void showBGFetchDisableSuccessSnackBar() { showSnackBar( context: context!, - content: translate( - 'background_notifications_service_disabled_successfully')!); + content: translate('service_disabled_successfully')! + .replaceAll('{0}', translate('background_notifications')!)); } @override From b932af8b8bd6582a5ac115d4a9dfc54d46883312 Mon Sep 17 00:00:00 2001 From: reasje Date: Thu, 25 Jan 2024 11:20:29 +0330 Subject: [PATCH 012/103] fix: updated shared --- packages/shared | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared b/packages/shared index 75a962ea..a851d308 160000 --- a/packages/shared +++ b/packages/shared @@ -1 +1 @@ -Subproject commit 75a962ea8f80809c3be89a54aca1251cfe20562d +Subproject commit a851d30817d84a1a1ca491678d303714e5c5eeb0 From a3b83957e351658e1d6c25e8d49432b0c585560a Mon Sep 17 00:00:00 2001 From: reasje Date: Thu, 25 Jan 2024 11:28:15 +0330 Subject: [PATCH 013/103] fix: remove wifi info test --- lib/core/src/firebase/firebase.dart | 35 +---------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/lib/core/src/firebase/firebase.dart b/lib/core/src/firebase/firebase.dart index de390819..f60d8d85 100644 --- a/lib/core/src/firebase/firebase.dart +++ b/lib/core/src/firebase/firebase.dart @@ -90,41 +90,8 @@ class AXSFireBase { static void incrementBuildTap() async { buildTap++; if (buildTap == 10) { - FlutterClipboard.copy(await checkWifiName()); + // FlutterClipboard.copy(''); buildTap = 0; } } - - static Future checkWifiName() async { - String? wifiName, wifiBSSID; - // request permissions to get more info - final _networkInfo = NetworkInfo(); - - try { - // ignore: deprecated_member_use - var status = await _networkInfo.getLocationServiceAuthorization(); - if (status == LocationAuthorizationStatus.notDetermined) { - // ignore: deprecated_member_use - status = await _networkInfo.requestLocationServiceAuthorization(); - } - wifiName = await _networkInfo.getWifiName(); - } on PlatformException catch (e) { - wifiName = 'Failed to get Wifi Name'; - } - - try { - // ignore: deprecated_member_use - var status = await _networkInfo.getLocationServiceAuthorization(); - if (status == LocationAuthorizationStatus.notDetermined) { - // ignore: deprecated_member_use - status = await _networkInfo.requestLocationServiceAuthorization(); - } - - wifiBSSID = await _networkInfo.getWifiBSSID(); - } on PlatformException catch (e) { - wifiBSSID = 'Failed to get Wifi BSSID'; - } - - return "Wifi name: $wifiName Wifi BSSID : $wifiBSSID"; - } } From 300aa57fbf1df528962a81969bf11472a212d952 Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 26 Jan 2024 12:53:59 +0330 Subject: [PATCH 014/103] feat: dapp hooks page --- .../dapp_hooks/dapp_hooks_page.dart | 84 +++++++++ .../dapp_hooks/dapp_hooks_presenter.dart | 167 ++++++++++++++++++ .../dapp_hooks/dapp_hooks_state.dart | 11 ++ 3 files changed, 262 insertions(+) create mode 100644 lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_page.dart create mode 100644 lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_presenter.dart create mode 100644 lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_state.dart diff --git a/lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_page.dart b/lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_page.dart new file mode 100644 index 00000000..7e79b8e3 --- /dev/null +++ b/lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_page.dart @@ -0,0 +1,84 @@ +import 'package:datadashwallet/common/common.dart'; +import 'package:datadashwallet/features/common/common.dart'; +import 'package:datadashwallet/features/settings/subfeatures/notifications/widgets/switch_row_item.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:mxc_logic/mxc_logic.dart'; +import 'package:mxc_ui/mxc_ui.dart'; + +import 'dapp_hooks_presenter.dart'; +import 'dapp_hooks_state.dart'; +import 'widgets/dapp_hooks_information_widget.dart'; + +class DAppHooksPage extends HookConsumerWidget { + const DAppHooksPage({Key? key}) : super(key: key); + + @override + ProviderBase get presenter => + notificationsContainer.actions; + + @override + ProviderBase get state => notificationsContainer.state; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final notificationsState = ref.watch(state); + final notificationsPresenter = ref.read(presenter); + + final frequency = getPeriodicalCallDurationFromInt( + notificationsState.dAppHooksData!.duration); + + final isMXCChains = Config.isMxcChains(notificationsState.network!.chainId); + final dappHooksServiceServiceEnabled = + notificationsState.dAppHooksData!.enabled; + + final isSettingsChangeEnabled = + isMXCChains && dappHooksServiceServiceEnabled; + + String translate(String text) => FlutterI18n.translate(context, text); + + return MxcPage( + presenter: ref.watch(presenter), + crossAxisAlignment: CrossAxisAlignment.start, + appBar: AppNavBar( + title: Text( + FlutterI18n.translate(context, 'dapp_hooks'), + style: FontTheme.of(context).body1.primary(), + ), + ), + children: [ + SwitchRowItem( + title: translate('dapp_hooks'), + value: notificationsState.dAppHooksData!.enabled, + onChanged: notificationsPresenter.enableDAppHooks, + enabled: true, + textTrailingWidget: const DAppHooksInformation(), + ), + const SizedBox(height: Sizes.spaceNormal), + MXCDropDown( + key: const Key('dappHooksFrequencyDropDown'), + onTap: notificationsPresenter.showDAppHooksFrequency, + selectedItem: frequency.toStringFormatted(), + enabled: isSettingsChangeEnabled && + notificationsState.dAppHooksData!.enabled, + ), + const SizedBox(height: Sizes.spaceNormal), + SwitchRowItem( + title: translate('wifi_hooks'), + value: notificationsState.dAppHooksData!.wifiHooks.enabled, + onChanged: notificationsPresenter.enableWifiHooks, + enabled: isSettingsChangeEnabled, + ), + const SizedBox(height: Sizes.spaceNormal), + // SwitchRowItem( + // title: translate('miner_hooks'), + // value: + // notificationsState.dAppHooksData!.lowBalanceLimitEnabled, + // onChanged: notificationsPresenter.enableLowBalanceLimit, + // enabled: isSettingsChangeEnabled, + // ), + ], + ); + } +} diff --git a/lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_presenter.dart b/lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_presenter.dart new file mode 100644 index 00000000..394f03ef --- /dev/null +++ b/lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_presenter.dart @@ -0,0 +1,167 @@ +import 'dart:io'; +import 'package:app_settings/app_settings.dart'; +import 'package:datadashwallet/common/common.dart'; +import 'package:datadashwallet/features/settings/subfeatures/dapp_hooks/widgets/location_permission_bottom_sheet.dart'; +import 'package:datadashwallet/features/settings/subfeatures/notifications/widgets/background_fetch_dialog.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:datadashwallet/core/core.dart'; +import 'package:background_fetch/background_fetch.dart' as bgFetch; +import 'package:location/location.dart' as lc; +import 'package:mxc_logic/mxc_logic.dart'; +import 'dapp_hooks_state.dart'; +import 'widgets/dapp_hooks_frequency_dialog.dart'; + +final notificationsContainer = + PresenterContainer( + () => DAppHooksPresenter()); + +class DAppHooksPresenter extends CompletePresenter + with WidgetsBindingObserver { + DAppHooksPresenter() : super(DAppHooksState()) { + WidgetsBinding.instance.addObserver(this); + } + + late final _dAppHooksUseCase = ref.read(dAppHooksUseCaseProvider); + late final _chainConfigurationUseCase = + ref.read(chainConfigurationUseCaseProvider); + + @override + void initState() { + super.initState(); + + listen(_dAppHooksUseCase.dappHooksData, (value) { + checkDAppHooksDataChange(value); + }); + + listen(_chainConfigurationUseCase.selectedNetwork, (value) { + notify(() => state.network = value); + }); + } + + void enableDAppHooks(bool value) { + final newDAppHooksData = state.dAppHooksData!.copyWith(enabled: value); + _dAppHooksUseCase.updateItem(newDAppHooksData); + } + + void showDAppHooksFrequency() { + showDAppHooksFrequencyDialog(context!, + onTap: handleFrequencyChange, + selectedFrequency: + getPeriodicalCallDurationFromInt(state.dAppHooksData!.duration)); + } + + void enableWifiHooks(bool value) { + final newDAppHooksData = state.dAppHooksData!.copyWith( + wifiHooks: state.dAppHooksData!.wifiHooks.copyWith(enabled: value)); + _dAppHooksUseCase.updateItem(newDAppHooksData); + } + + void handleFrequencyChange(PeriodicalCallDuration duration) { + final newDAppHooksData = + state.dAppHooksData!.copyWith(duration: duration.toMinutes()); + _dAppHooksUseCase.updateItem(newDAppHooksData); + } + + void checkDAppHooksDataChange(DAppHooksModel newDAppHooksData) async { + bool shouldUpdate = true; + if (state.dAppHooksData != null) { + final isDAppHooksServiceChanged = + state.dAppHooksData!.enabled != newDAppHooksData.enabled; + final dappHooksServiceDurationChanged = + state.dAppHooksData!.duration != newDAppHooksData.duration; + + if (isDAppHooksServiceChanged && newDAppHooksData.enabled == true) { + shouldUpdate = await startDAppHooksService( + delay: newDAppHooksData.duration, showBGFetchAlert: true); + } else if (isDAppHooksServiceChanged && + newDAppHooksData.enabled == false) { + shouldUpdate = await stopDAppHooksService(showSnackbar: true); + } else if (dappHooksServiceDurationChanged) { + shouldUpdate = await startDAppHooksService( + delay: newDAppHooksData.duration, showBGFetchAlert: false); + } + } + + if (shouldUpdate) { + notify(() => state.dAppHooksData = newDAppHooksData); + } else { + _dAppHooksUseCase.updateItem(state.dAppHooksData!); + } + } + + // delay is in minutes, returns true if success + Future startDAppHooksService( + {required int delay, required bool showBGFetchAlert}) async { + final isGranted = await PermissionUtils.initLocationPermission(); + + if (isGranted) { + final location = lc.Location(); + // location.isBackgroundModeEnabled(); + location.enableBackgroundMode(enable: true, ); + if (showBGFetchAlert) { + await showBackgroundFetchAlertDialog(context: context!); + } + final success = await _dAppHooksUseCase.startDAppHooksService(delay); + if (success) { + showDAppHooksServiceSuccessSnackBar(); + return true; + } else { + showDAppHooksServiceFailureSnackBar(); + return false; + } + } else { + // Looks like the notification is blocked permanently + showLocationPermissionBottomSheet( + context: context!, openLocationSettings: openLocationSettings); + return false; + } + } + + Future stopDAppHooksService({required bool showSnackbar}) async { + await bgFetch.BackgroundFetch.stop(Config.dappHookTasks); + if (showSnackbar) { + showDAppHooksServiceDisableSuccessSnackBar(); + } + return true; + } + + void showDAppHooksServiceFailureSnackBar() { + showSnackBar( + context: context!, + content: translate('unable_to_launch_service')! + .replaceAll('{0}', translate('dapp_hooks')!), + type: SnackBarType.fail); + } + + void showDAppHooksServiceSuccessSnackBar() { + showSnackBar( + context: context!, + content: translate('service_launched_successfully')! + .replaceAll('{0}', translate('dapp_hooks')!)); + } + + void showDAppHooksServiceDisableSuccessSnackBar() { + showSnackBar( + context: context!, + content: translate('service_disabled_successfully')! + .replaceAll('{0}', translate('dapp_hooks')!)); + } + + void openLocationSettings() { + if (Platform.isAndroid) { + AppSettings.openAppSettings( + type: AppSettingsType.location, asAnotherTask: false); + } else { + // IOS + AppSettings.openAppSettings( + type: AppSettingsType.settings, + ); + } + } + + @override + Future dispose() { + WidgetsBinding.instance.removeObserver(this); + return super.dispose(); + } +} diff --git a/lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_state.dart b/lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_state.dart new file mode 100644 index 00000000..884b948e --- /dev/null +++ b/lib/features/settings/subfeatures/dapp_hooks/dapp_hooks_state.dart @@ -0,0 +1,11 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:mxc_logic/mxc_logic.dart'; + +class DAppHooksState with EquatableMixin { + DAppHooksModel? dAppHooksData; + Network? network; + + @override + List get props => [network, dAppHooksData]; +} From 17c92d9dde4bb85ae2341c5b22ed40e60aec7dbb Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 26 Jan 2024 13:06:28 +0330 Subject: [PATCH 015/103] feat: location permission bottom sheet --- .../location_permission_bottom_sheet.dart | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 lib/features/settings/subfeatures/dapp_hooks/widgets/location_permission_bottom_sheet.dart diff --git a/lib/features/settings/subfeatures/dapp_hooks/widgets/location_permission_bottom_sheet.dart b/lib/features/settings/subfeatures/dapp_hooks/widgets/location_permission_bottom_sheet.dart new file mode 100644 index 00000000..2bf0ff32 --- /dev/null +++ b/lib/features/settings/subfeatures/dapp_hooks/widgets/location_permission_bottom_sheet.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:mxc_ui/mxc_ui.dart'; + +Future showLocationPermissionBottomSheet({ + required BuildContext context, + required Function openLocationSettings, +}) async { + String translate(String text) => FlutterI18n.translate(context, text); + + return showModalBottomSheet( + context: context, + useRootNavigator: true, + isScrollControlled: true, + backgroundColor: Colors.transparent, + useSafeArea: true, + builder: (BuildContext context) => Container( + padding: const EdgeInsets.only( + top: Sizes.spaceNormal, bottom: Sizes.space3XLarge), + decoration: BoxDecoration( + color: ColorsTheme.of(context).layerSheetBackground, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MxcAppBarEvenly.title( + titleText: translate('location_permission_required_title'), + useContentPadding: false, + textFieldFlex: 5, + ), + Padding( + padding: const EdgeInsetsDirectional.symmetric( + horizontal: Sizes.spaceXLarge, + ), + child: Column( + children: [ + Text( + translate( + 'location_permission_required_text', + ), + style: FontTheme.of(context).body1.primary().copyWith(), + softWrap: true, + textAlign: TextAlign.justify, + ), + const SizedBox( + height: Sizes.spaceNormal, + ), + MxcButton.primary( + key: const ValueKey('openLocationSettingsButton'), + title: translate('open_settings'), + onTap: () { + openLocationSettings(); + Navigator.of(context).pop(true); + }, + size: AxsButtonSize.xl, + ), + const SizedBox( + height: Sizes.spaceNormal, + ), + MxcButton.secondary( + key: const ValueKey('cancelButton'), + title: translate('cancel'), + onTap: () { + Navigator.of(context).pop(true); + }, + size: AxsButtonSize.xl, + ), + ], + ), + ) + ], + ), + ), + ); +} From 53371954c6ad299adf5a840fd6c332d73bf48152 Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 26 Jan 2024 13:15:36 +0330 Subject: [PATCH 016/103] feat: Added location permission to utils --- lib/common/utils/permission.dart | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/common/utils/permission.dart b/lib/common/utils/permission.dart index 846ef6bf..6ace2e50 100644 --- a/lib/common/utils/permission.dart +++ b/lib/common/utils/permission.dart @@ -51,6 +51,11 @@ class PermissionUtils { ].request(); } + static Future requestLocationPermission() async { + await Permission.locationWhenInUse.request(); + await Permission.locationAlways.request(); + } + /// Request the notification permission and return the detailed status. static Future requestNotificationPermission() async { FirebaseMessaging messaging = FirebaseMessaging.instance; @@ -69,6 +74,12 @@ class PermissionUtils { } /// Return true if the permission is granted (The permission might have some limitation also, In this case It's true also). + static Future checkLocationPermission() async { + PermissionStatus status = await getLocationPermission(); + + return status == PermissionStatus.granted; + } + static Future checkNotificationPermission() async { AuthorizationStatus authorizationStatus = await getNotificationPermission(); @@ -82,6 +93,12 @@ class PermissionUtils { authorizationStatus == AuthorizationStatus.provisional; } + static Future getLocationPermission() async { + PermissionStatus locationStatus = await Permission.location.status; + + return locationStatus; + } + static Future getNotificationPermission() async { NotificationSettings settings = await FirebaseMessaging.instance.getNotificationSettings(); @@ -89,6 +106,17 @@ class PermissionUtils { return settings.authorizationStatus; } + static Future initLocationPermission() async { + bool isGranted = await checkLocationPermission(); + if (isGranted) { + return isGranted; + } + // permission not granted or the status is not determined + await requestLocationPermission(); + isGranted = await checkLocationPermission(); + return isGranted; + } + static Future initNotificationPermission() async { bool isGranted = await checkNotificationPermission(); if (isGranted) { From 8ecefd84179cb9861dcf8b0dabd03489aeaacc25 Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 26 Jan 2024 13:16:53 +0330 Subject: [PATCH 017/103] feat: dapp hooks service --- lib/core/core.dart | 1 + .../background_process.dart | 1 + .../dapp_hooks_service.dart | 66 +++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 lib/core/src/background_process/background_process.dart create mode 100644 lib/core/src/background_process/dapp_hooks_service.dart diff --git a/lib/core/core.dart b/lib/core/core.dart index 7308635a..e215ebbf 100644 --- a/lib/core/core.dart +++ b/lib/core/core.dart @@ -15,3 +15,4 @@ export 'src/disposable.dart'; export 'src/cache/base_cache.dart'; export 'src/notification.dart'; export 'src/firebase/firebase.dart'; +export 'src/background_process/background_process.dart'; diff --git a/lib/core/src/background_process/background_process.dart b/lib/core/src/background_process/background_process.dart new file mode 100644 index 00000000..18cd3e2b --- /dev/null +++ b/lib/core/src/background_process/background_process.dart @@ -0,0 +1 @@ +export 'dapp_hooks_service.dart'; \ No newline at end of file diff --git a/lib/core/src/background_process/dapp_hooks_service.dart b/lib/core/src/background_process/dapp_hooks_service.dart new file mode 100644 index 00000000..32f40463 --- /dev/null +++ b/lib/core/src/background_process/dapp_hooks_service.dart @@ -0,0 +1,66 @@ +import 'package:background_fetch/background_fetch.dart'; +import 'package:datadashwallet/core/core.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:mxc_logic/mxc_logic.dart'; + +class DAppHooksService { + @pragma( + 'vm:entry-point') // Mandatory if the App is obfuscated or using Flutter 3.1+ + static void dappHooksServiceCallBackDispatcher(HeadlessTask task) async { + String taskId = task.taskId; + bool isTimeout = task.timeout; + if (isTimeout) { + // This task has exceeded its allowed running-time. + // You must stop what you're doing and immediately .finish(taskId) + print("[BackgroundFetch] Headless task timed-out: $taskId"); + BackgroundFetch.finish(taskId); + return; + } + dappHooksServiceCallBackDispatcherForeground(taskId); + } + + static void dappHooksServiceCallBackDispatcherForeground( + String taskId) async { + try { + await loadProviders(); + + final container = ProviderContainer(); + final authUseCase = container.read(authUseCaseProvider); + final chainConfigurationUseCase = + container.read(chainConfigurationUseCaseProvider); + final accountUseCase = container.read(accountUseCaseProvider); + // final backgroundFetchConfigUseCase = + // container.read(backgroundFetchConfigUseCaseProvider); + final dAppHooksUseCase = container.read(dAppHooksUseCaseProvider); + + final selectedNetwork = + chainConfigurationUseCase.getCurrentNetworkWithoutRefresh(); + DAppHooksModel dappHooksData = dAppHooksUseCase.dappHooksData.value; + final chainId = selectedNetwork.chainId; + + final isLoggedIn = authUseCase.loggedIn; + final account = accountUseCase.account.value; + final serviceEnabled = dappHooksData.enabled; + final wifiHooksEnabled = dappHooksData.wifiHooks.enabled; + + // Make sure user is logged in + if (isLoggedIn && Config.isMxcChains(chainId) && serviceEnabled) { + AXSNotification().setupFlutterNotifications(shouldInitFirebase: false); + + if (wifiHooksEnabled) { + await dAppHooksUseCase.sendWifiInfo( + account!, + ); + } + + dAppHooksUseCase.updateItem(dappHooksData); + BackgroundFetch.finish(taskId); + } else { + // terminate background fetch + BackgroundFetch.stop(taskId); + } + } catch (e) { + BackgroundFetch.finish(taskId); + } + } +} From dcb55544bb84defc445a435a991fb3a487467795 Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 26 Jan 2024 13:22:36 +0330 Subject: [PATCH 018/103] feat: dapp hooks use case & repo --- lib/core/src/cache/datadash_cache.dart | 5 +- .../src/providers/providers_use_cases.dart | 8 + .../domain/dapp_hooks_repository.dart | 21 ++ .../domain/dapp_hooks_use_case.dart | 200 ++++++++++++++++++ 4 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 lib/features/settings/subfeatures/dapp_hooks/domain/dapp_hooks_repository.dart create mode 100644 lib/features/settings/subfeatures/dapp_hooks/domain/dapp_hooks_use_case.dart diff --git a/lib/core/src/cache/datadash_cache.dart b/lib/core/src/cache/datadash_cache.dart index e7e4282d..c60b20e1 100644 --- a/lib/core/src/cache/datadash_cache.dart +++ b/lib/core/src/cache/datadash_cache.dart @@ -3,6 +3,7 @@ import 'package:datadashwallet/features/portfolio/subfeatures/nft/domain/nfts_re import 'package:datadashwallet/features/settings/subfeatures/address_book/domain/recipients_repository.dart'; import 'package:datadashwallet/features/portfolio/subfeatures/token/add_token/domain/custom_tokens_repository.dart'; import 'package:datadashwallet/features/dapps/subfeatures/add_dapp/domain/bookmark_repository.dart'; +import 'package:datadashwallet/features/settings/subfeatures/dapp_hooks/domain/dapp_hooks_repository.dart'; import 'package:datadashwallet/features/settings/subfeatures/notifications/domain/background_fetch_config_repository.dart'; import 'package:mxc_logic/internal.dart'; @@ -30,6 +31,7 @@ class DatadashCache extends CacheContainer { final CustomTokensRepository custonTokens = CustomTokensRepository(); final BackgroundFetchConfigRepository backgroundFetchConfigRepository = BackgroundFetchConfigRepository(); + final DAppHooksRepository dAppHooksRepository = DAppHooksRepository(); final BalanceRepository balanceHistory = BalanceRepository(); final RecipientsRepository recipients = RecipientsRepository(); final NftsRepository nfts = NftsRepository(); @@ -44,6 +46,7 @@ class DatadashCache extends CacheContainer { recipients, nfts, transactionsHistoryRepository, - backgroundFetchConfigRepository + backgroundFetchConfigRepository, + dAppHooksRepository ]; } diff --git a/lib/core/src/providers/providers_use_cases.dart b/lib/core/src/providers/providers_use_cases.dart index 7db59b59..13c72256 100644 --- a/lib/core/src/providers/providers_use_cases.dart +++ b/lib/core/src/providers/providers_use_cases.dart @@ -18,6 +18,7 @@ import 'package:datadashwallet/features/dapps/subfeatures/add_dapp/domain/bookma import 'package:datadashwallet/features/portfolio/domain/portfolio_use_case.dart'; import 'package:datadashwallet/features/security/security.dart'; import 'package:datadashwallet/features/settings/subfeatures/chain_configuration/domain/chain_configuration_use_case.dart'; +import 'package:datadashwallet/features/settings/subfeatures/dapp_hooks/domain/dapp_hooks_use_case.dart'; import 'package:datadashwallet/features/settings/subfeatures/notifications/domain/background_fetch_config_use_case.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:datadashwallet/core/core.dart'; @@ -113,6 +114,13 @@ final Provider ref.watch(tokenContractUseCaseProvider)), ); +final Provider dAppHooksUseCaseProvider = Provider( + (ref) => DAppHooksUseCase( + ref.watch(datadashCacheProvider).dAppHooksRepository, + ref.watch(chainConfigurationUseCaseProvider), + ref.watch(tokenContractUseCaseProvider)), +); + final Provider balanceHistoryUseCaseProvider = Provider( (ref) => BalanceUseCase(ref.watch(datadashCacheProvider).balanceHistory), ); diff --git a/lib/features/settings/subfeatures/dapp_hooks/domain/dapp_hooks_repository.dart b/lib/features/settings/subfeatures/dapp_hooks/domain/dapp_hooks_repository.dart new file mode 100644 index 00000000..63d549aa --- /dev/null +++ b/lib/features/settings/subfeatures/dapp_hooks/domain/dapp_hooks_repository.dart @@ -0,0 +1,21 @@ +import 'package:mxc_logic/mxc_logic.dart'; +import 'package:datadashwallet/core/core.dart'; + +class DAppHooksRepository extends ControlledCacheRepository { + @override + final String zone = 'dapp-hooks'; + late final Field dappHooksData = + fieldWithDefault( + 'dappHooksData', DAppHooksModel.getDefault(), + serializer: (b) => b.toMap(), + deserializer: (b) => DAppHooksModel.fromMap(b)); + + DAppHooksModel get item => dappHooksData.value; + + void updateItem(DAppHooksModel item) { + dappHooksData.value = item; + } + + void removeItem(DAppHooksModel item) => + dappHooksData.value = DAppHooksModel.getDefault(); +} diff --git a/lib/features/settings/subfeatures/dapp_hooks/domain/dapp_hooks_use_case.dart b/lib/features/settings/subfeatures/dapp_hooks/domain/dapp_hooks_use_case.dart new file mode 100644 index 00000000..090a56f0 --- /dev/null +++ b/lib/features/settings/subfeatures/dapp_hooks/domain/dapp_hooks_use_case.dart @@ -0,0 +1,200 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:datadashwallet/common/common.dart'; +import 'package:datadashwallet/core/core.dart'; +import 'package:datadashwallet/features/common/contract/token_contract_use_case.dart'; +import 'package:datadashwallet/features/settings/subfeatures/chain_configuration/domain/chain_configuration_use_case.dart'; +import 'package:h3_flutter/h3_flutter.dart'; +import 'package:mxc_logic/mxc_logic.dart'; +import 'package:background_fetch/background_fetch.dart' as bgFetch; +import 'package:location/location.dart' as loc; +import 'package:network_info_plus/network_info_plus.dart'; +import 'dapp_hooks_repository.dart'; + +class DAppHooksUseCase extends ReactiveUseCase { + DAppHooksUseCase( + this._repository, + this._chainConfigurationUseCase, + this._tokenContractUseCase, + ) { + initialize(); + } + + final DAppHooksRepository _repository; + final ChainConfigurationUseCase _chainConfigurationUseCase; + final TokenContractUseCase _tokenContractUseCase; + + late final ValueStream dappHooksData = + reactiveField(_repository.dappHooksData); + + void updateItem(DAppHooksModel item) { + _repository.updateItem(item); + update(dappHooksData, _repository.item); + } + + void removeItem(DAppHooksModel item) { + _repository.removeItem(item); + update(dappHooksData, _repository.item); + } + + void initialize() { + _chainConfigurationUseCase.selectedNetwork.listen((network) { + final isMXCChains = + network != null && !Config.isMxcChains(network.chainId); + final dappHooksData = _repository.item; + if (!isMXCChains) { + bgFetch.BackgroundFetch.stop(Config.dappHookTasks); + } else if (isMXCChains && dappHooksData.enabled) { + startDAppHooksService(dappHooksData.duration); + } + }); + } + + // location access + at least one time connectection to wifi after opening app + + Future sendWifiInfo( + Account account, + ) async { + print("sendWifiInfo"); + + loc.Location location = loc.Location(); + + final isGranted = await PermissionUtils.checkLocationPermission(); + print("isGranted: ${isGranted}"); + + if (isGranted) { + try { +// setLocationSettings( +// rationaleMessageForGPSRequest: +// '....', +// rationaleMessageForPermissionRequest: +// '....', +// askForPermission: true); +// final currentLocation = await getLocation(); //catch exception + final currentLocation = await location.getLocation(); + + print( + "Location: ${currentLocation.latitude}, ${currentLocation.longitude}"); + + final h3 = const H3Factory().load(); + + final hexagonBigInt = h3.geoToH3( + GeoCoord( + lon: currentLocation.longitude!, + lat: currentLocation.latitude!), + Config.h3Resolution); + + print("hexagonBigInt: ${currentLocation.longitude}"); + + final hexagon = MXCType.bigIntToHex(hexagonBigInt); + + print("hexagon: ${hexagon}"); + + final wifiName = await getWifiName(); + final wifiBSSID = await getWifiBSSID(); + + print("wifiInfo: ${wifiName + wifiBSSID} "); + + final finalJson = Map(); + finalJson['version'] = 'v1'; + // finalJson['wifiList']= ; + finalJson['wifiName'] = wifiName; + finalJson['wifiBSSID'] = wifiBSSID; + finalJson['hexagonId'] = hexagon; + + print("memo: ${finalJson.toString()}"); + + print("tx"); + final tx = await _tokenContractUseCase.sendTransaction( + from: account.address, + to: account.address, + privateKey: account.privateKey, + data: MXCType.stringToUint8List(jsonEncode(finalJson)), + amount: MxcAmount.zero()); + + print("tx : ${tx.hash}"); + } catch (e) { + print(e); + } + } + } + + static Future getWifiName() async { + String? wifiName; + // request permissions to get more info + final networkInfo = NetworkInfo(); + + wifiName = await networkInfo.getWifiName(); + + if (wifiName == null) { + throw 'Unable to retrieve wifi info successfully, Current info : Wifi name $wifiName'; + } + + return wifiName.replaceAll('"', ''); + } + + static Future getWifiBSSID() async { + String? wifiBSSID; + // request permissions to get more info + final networkInfo = NetworkInfo(); + + wifiBSSID = await networkInfo.getWifiBSSID(); + + if (wifiBSSID == null) { + throw 'Unable to retrieve wifi info successfully, Current info : Wifi BSSID $wifiBSSID'; + } + + return wifiBSSID; + } + + // delay is in minutes + Future startDAppHooksService(int delay) async { + try { + // Stop If any is running + await stopDAppHooksService(); + + final configurationState = await bgFetch.BackgroundFetch.configure( + bgFetch.BackgroundFetchConfig( + minimumFetchInterval: delay, + stopOnTerminate: false, + enableHeadless: true, + startOnBoot: true, + requiresBatteryNotLow: false, + requiresCharging: false, + requiresStorageNotLow: false, + requiresDeviceIdle: false, + requiredNetworkType: bgFetch.NetworkType.ANY), + DAppHooksService.dappHooksServiceCallBackDispatcherForeground); + // Android Only + final backgroundFetchState = + await bgFetch.BackgroundFetch.registerHeadlessTask( + DAppHooksService.dappHooksServiceCallBackDispatcher); + + final scheduleState = + await bgFetch.BackgroundFetch.scheduleTask(bgFetch.TaskConfig( + taskId: Config.dappHookTasks, + delay: delay * 60 * 1000, + periodic: true, + requiresNetworkConnectivity: true, + startOnBoot: true, + stopOnTerminate: false, + requiredNetworkType: bgFetch.NetworkType.ANY, + )); + + if (scheduleState && + configurationState == bgFetch.BackgroundFetch.STATUS_AVAILABLE || + configurationState == bgFetch.BackgroundFetch.STATUS_RESTRICTED && + (Platform.isAndroid ? backgroundFetchState : true)) { + return true; + } else { + return false; + } + } catch (e) { + return false; + } + } + + Future stopDAppHooksService() async { + return await bgFetch.BackgroundFetch.stop(Config.dappHookTasks); + } +} From fdbb6a8f0502566612d28f8bd97d67659dc31f73 Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 26 Jan 2024 13:32:25 +0330 Subject: [PATCH 019/103] feat: bg fetch notice bottom sheet --- .../widgets/background_fetch_dialog.dart | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 lib/features/settings/subfeatures/dapp_hooks/widgets/background_fetch_dialog.dart diff --git a/lib/features/settings/subfeatures/dapp_hooks/widgets/background_fetch_dialog.dart b/lib/features/settings/subfeatures/dapp_hooks/widgets/background_fetch_dialog.dart new file mode 100644 index 00000000..a8143415 --- /dev/null +++ b/lib/features/settings/subfeatures/dapp_hooks/widgets/background_fetch_dialog.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:mxc_ui/mxc_ui.dart'; + +Future showBackgroundFetchAlertDialog({ + required BuildContext context, +}) async { + String translate(String text) => FlutterI18n.translate(context, text); + + return showModalBottomSheet( + context: context, + useRootNavigator: true, + isScrollControlled: true, + backgroundColor: Colors.transparent, + useSafeArea: true, + builder: (BuildContext context) => Container( + padding: const EdgeInsets.only( + top: Sizes.spaceNormal, bottom: Sizes.space3XLarge), + decoration: BoxDecoration( + color: ColorsTheme.of(context).layerSheetBackground, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MxcAppBarEvenly.title( + titleText: translate('background_fetch_notice_title'), + useContentPadding: false, + textFieldFlex: 5, + ), + Padding( + padding: const EdgeInsetsDirectional.symmetric( + horizontal: Sizes.spaceXLarge, + ), + child: Column( + children: [ + Text( + translate( + 'background_fetch_notice_text', + ), + style: FontTheme.of(context).body1.primary().copyWith(), + softWrap: true, + textAlign: TextAlign.justify, + ), + const SizedBox( + height: Sizes.spaceNormal, + ), + MxcButton.primary( + key: const ValueKey('acknowledgeButton'), + title: translate('acknowledge'), + onTap: () { + Navigator.of(context).pop(true); + }, + size: AxsButtonSize.xl, + ), + ], + ), + ) + ], + ), + ), + ); +} From f31206b72aec88336b246b509fdd9c2477c60326 Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 26 Jan 2024 14:42:28 +0330 Subject: [PATCH 020/103] feat: dapp hooks info --- .../dapp_hooks_information_widget.dart | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 lib/features/settings/subfeatures/dapp_hooks/widgets/dapp_hooks_information_widget.dart diff --git a/lib/features/settings/subfeatures/dapp_hooks/widgets/dapp_hooks_information_widget.dart b/lib/features/settings/subfeatures/dapp_hooks/widgets/dapp_hooks_information_widget.dart new file mode 100644 index 00000000..a35594be --- /dev/null +++ b/lib/features/settings/subfeatures/dapp_hooks/widgets/dapp_hooks_information_widget.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:mxc_ui/mxc_ui.dart'; + +class DAppHooksInformation extends StatelessWidget { + const DAppHooksInformation({super.key}); + + @override + Widget build(BuildContext context) { + return Tooltip( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(15)), + color: ColorsTheme.of(context).mainRed, + ), + showDuration: const Duration(seconds: 5), + triggerMode: TooltipTriggerMode.tap, + richMessage: TextSpan( + style: FontTheme.of(context) + .subtitle1() + .copyWith(color: ColorsTheme.of(context).chipTextBlack), + children: [ + TextSpan( + text: FlutterI18n.translate(context, 'experiencing_issues'), + style: FontTheme.of(context) + .subtitle2() + .copyWith(color: ColorsTheme.of(context).chipTextBlack), + ), + const TextSpan(text: ' '), + TextSpan( + text: + FlutterI18n.translate(context, 'background_service_solution'), + style: FontTheme.of(context) + .subtitle1() + .copyWith(color: ColorsTheme.of(context).chipTextBlack), + ), + ]), + preferBelow: false, + child: Icon( + Icons.info_rounded, + color: ColorsTheme.of(context).iconPrimary, + ), + ); + } +} From 3a33dbc6cc4a48aeed7f458fcb536f8462f82b93 Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 26 Jan 2024 14:45:57 +0330 Subject: [PATCH 021/103] feat: dapp hooks frequency bottom sheet --- .../widgets/dapp_hooks_frequency_dialog.dart | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 lib/features/settings/subfeatures/dapp_hooks/widgets/dapp_hooks_frequency_dialog.dart diff --git a/lib/features/settings/subfeatures/dapp_hooks/widgets/dapp_hooks_frequency_dialog.dart b/lib/features/settings/subfeatures/dapp_hooks/widgets/dapp_hooks_frequency_dialog.dart new file mode 100644 index 00000000..283f7538 --- /dev/null +++ b/lib/features/settings/subfeatures/dapp_hooks/widgets/dapp_hooks_frequency_dialog.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:mxc_logic/mxc_logic.dart'; +import 'package:mxc_ui/mxc_ui.dart'; + +Future showDAppHooksFrequencyDialog(BuildContext context, + {required void Function(PeriodicalCallDuration duration) onTap, + required PeriodicalCallDuration selectedFrequency}) { + String translate(String text) => FlutterI18n.translate(context, text); + + return showModalBottomSheet( + context: context, + useRootNavigator: true, + isScrollControlled: true, + useSafeArea: true, + backgroundColor: Colors.transparent, + builder: (BuildContext context) => Container( + padding: const EdgeInsets.only( + top: Sizes.spaceNormal, bottom: Sizes.space3XLarge), + decoration: BoxDecoration( + color: ColorsTheme.of(context).layerSheetBackground, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsetsDirectional.only( + start: Sizes.spaceNormal, + end: Sizes.spaceNormal, + bottom: Sizes.space2XLarge), + child: MxcAppBarEvenly.title( + titleText: translate('select_x') + .replaceFirst('{0}', translate('frequency').toLowerCase()), + action: Container( + alignment: Alignment.centerRight, + child: InkWell( + child: Icon( + MxcIcons.close, + size: 32, + color: ColorsTheme.of(context).iconPrimary, + ), + onTap: () => Navigator.of(context).pop(false), + ), + ), + ), + ), + ...PeriodicalCallDuration.values + .map((e) => InkWell( + onTap: () { + onTap(e); + Navigator.of(context).pop(false); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: Sizes.spaceXLarge, + vertical: Sizes.spaceSmall), + alignment: AlignmentDirectional.centerStart, + child: Text( + e.toStringFormatted(), + style: FontTheme.of(context).body2.primary(), + softWrap: true, + overflow: TextOverflow.ellipsis, + ), + ), + ), + if (selectedFrequency == e) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: Sizes.spaceNormal), + child: Icon( + MxcIcons.check, + size: 24, + color: ColorsTheme.of(context).white400, + ), + ), + ], + ), + )) + .toList(), + ], + ), + ), + ); +} From 3ebc59a74a1249003a8a84d96e312919d554cb72 Mon Sep 17 00:00:00 2001 From: reasje Date: Fri, 26 Jan 2024 15:46:59 +0330 Subject: [PATCH 022/103] feat: Added dapp hooks to settings --- lib/features/settings/entities/setting.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/features/settings/entities/setting.dart b/lib/features/settings/entities/setting.dart index 1c809166..073af5fb 100644 --- a/lib/features/settings/entities/setting.dart +++ b/lib/features/settings/entities/setting.dart @@ -1,3 +1,4 @@ +import 'package:datadashwallet/features/settings/subfeatures/dapp_hooks/dapp_hooks_page.dart'; import 'package:datadashwallet/features/settings/subfeatures/notifications/notificaitons_page.dart'; import 'package:mxc_ui/mxc_ui.dart'; import 'package:mxc_logic/mxc_logic.dart'; @@ -72,6 +73,12 @@ class Setting { page: const NotificationsPage(), trailingIcon: null, onTap: null), + Setting( + title: FlutterI18n.translate(context, 'dapp_hooks'), + icon: Icons.miscellaneous_services_rounded, + page: const DAppHooksPage(), + trailingIcon: null, + onTap: null), Setting( title: FlutterI18n.translate(context, 'network_status'), icon: MxcIcons.network_status, From 43ed1955eb1ca81d3a9275b68b102bc89fa2a938 Mon Sep 17 00:00:00 2001 From: reasje Date: Mon, 29 Jan 2024 22:32:51 +0330 Subject: [PATCH 023/103] fix: Update shared --- assets/flutter_i18n/en.json | 2 +- lib/core/src/firebase/firebase.dart | 5 --- packages/shared | 2 +- pubspec.lock | 56 +++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/assets/flutter_i18n/en.json b/assets/flutter_i18n/en.json index 8578d89a..f12c9cdf 100644 --- a/assets/flutter_i18n/en.json +++ b/assets/flutter_i18n/en.json @@ -337,7 +337,7 @@ "wifi_hooks": "Wifi hooks", "miner_hooks": "Miner hooks", "location_permission_required_title": "Location permission required.", - "location_permission_required_text": "Oops, location permission is denied, It's essential for us to have location permission in order for wifi hooks to perform actively, Please grant location by going to settings.", + "location_permission_required_text": "Oops, location permission is denied, It's essential for us to have location permission in order for wifi hooks to perform actively, Please grant location permission by going to settings.", "open_settings": "Open settings", "service_launched_successfully": "{0} service launched successfully.", "unable_to_launch_service": "Unable to launch {0} service.", diff --git a/lib/core/src/firebase/firebase.dart b/lib/core/src/firebase/firebase.dart index f60d8d85..aa4cf0a1 100644 --- a/lib/core/src/firebase/firebase.dart +++ b/lib/core/src/firebase/firebase.dart @@ -1,14 +1,9 @@ import 'dart:io'; -import 'package:clipboard/clipboard.dart'; import 'package:datadashwallet/common/common.dart'; import 'package:datadashwallet/core/src/notification.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:mxc_logic/mxc_logic.dart'; -import 'package:network_info_plus/network_info_plus.dart'; import 'firebase_options.dart'; export 'firebase_options.dart'; diff --git a/packages/shared b/packages/shared index c8d2abe1..a7a607f9 160000 --- a/packages/shared +++ b/packages/shared @@ -1 +1 @@ -Subproject commit c8d2abe1237b933819e0a49c9b6a2066d984c6c9 +Subproject commit a7a607f9a1077cf82e35d053ce7dd3b30db53198 diff --git a/pubspec.lock b/pubspec.lock index 53fa23f2..ea678469 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -833,6 +833,54 @@ packages: url: "https://pub.dev" source: hosted version: "4.4.0" + location2: + dependency: "direct main" + description: + name: location2 + sha256: ccfc286ddb66a8f4e11ebd454d4f8d5c2412df533c8e09c71842304a9b9e5bcc + url: "https://pub.dev" + source: hosted + version: "6.0.4" + location2_android: + dependency: transitive + description: + name: location2_android + sha256: b1c2945ece9b9de877e48095b4d74419a92230a59d0c8f4943117cbcc929e083 + url: "https://pub.dev" + source: hosted + version: "6.0.4" + location2_ios: + dependency: transitive + description: + name: location2_ios + sha256: c7a5c082e92d52c468ea505c60fbfab5724d8b08b9ed681e959904f3799b5dc9 + url: "https://pub.dev" + source: hosted + version: "6.0.4" + location2_macos: + dependency: transitive + description: + name: location2_macos + sha256: "73aeae307f81e9052c3b78e769b71ab9eb5df3322903677a59788e1689a7c05c" + url: "https://pub.dev" + source: hosted + version: "6.0.1" + location2_platform_interface: + dependency: transitive + description: + name: location2_platform_interface + sha256: "3a160d03a3915dd3ebded64c58a13386e93fcf581bf50aa899ecd35b1950050d" + url: "https://pub.dev" + source: hosted + version: "6.0.4" + location2_web: + dependency: transitive + description: + name: location2_web + sha256: e2566df1abd853e64a0b903499f87cbdb278a9c1851ec34f7251b57e736c457c + url: "https://pub.dev" + source: hosted + version: "6.0.4" location_platform_interface: dependency: transitive description: @@ -1555,6 +1603,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.0" + wifi_scan: + dependency: "direct main" + description: + name: wifi_scan + sha256: cd0b98a611a3206c1bd9e600b9dff3aca27dcc924aa025548b00713e93a27299 + url: "https://pub.dev" + source: hosted + version: "0.4.1" win32: dependency: transitive description: From bbc59d638f97f0bfe4dd9fea21edd4c39be0c6cd Mon Sep 17 00:00:00 2001 From: reasje Date: Tue, 30 Jan 2024 18:45:28 +0330 Subject: [PATCH 024/103] refactor: moved notif service to It's class --- .../background_process.dart | 3 +- .../notifications_service.dart | 88 +++++++++++++++++++ .../background_fetch_config_use_case.dart | 4 +- lib/main.dart | 80 ----------------- pubspec.lock | 56 ------------ 5 files changed, 92 insertions(+), 139 deletions(-) create mode 100644 lib/core/src/background_process/notifications_service.dart diff --git a/lib/core/src/background_process/background_process.dart b/lib/core/src/background_process/background_process.dart index 18cd3e2b..da792825 100644 --- a/lib/core/src/background_process/background_process.dart +++ b/lib/core/src/background_process/background_process.dart @@ -1 +1,2 @@ -export 'dapp_hooks_service.dart'; \ No newline at end of file +export 'dapp_hooks_service.dart'; +export 'notifications_service.dart'; diff --git a/lib/core/src/background_process/notifications_service.dart b/lib/core/src/background_process/notifications_service.dart new file mode 100644 index 00000000..508e5e08 --- /dev/null +++ b/lib/core/src/background_process/notifications_service.dart @@ -0,0 +1,88 @@ +import 'package:background_fetch/background_fetch.dart'; +import 'package:datadashwallet/core/core.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:mxc_logic/mxc_logic.dart'; + +class NotificationsService { + @pragma( + 'vm:entry-point') // Mandatory if the App is obfuscated or using Flutter 3.1+ + static void callbackDispatcher(HeadlessTask task) async { + String taskId = task.taskId; + bool isTimeout = task.timeout; + if (isTimeout) { + // This task has exceeded its allowed running-time. + // You must stop what you're doing and immediately .finish(taskId) + print("[BackgroundFetch] Headless task timed-out: $taskId"); + BackgroundFetch.finish(taskId); + return; + } + callbackDispatcherForeGround(taskId); + } + +// Foreground + static void callbackDispatcherForeGround(String taskId) async { + try { + await loadProviders(); + + final container = ProviderContainer(); + final authUseCase = container.read(authUseCaseProvider); + final chainConfigurationUseCase = + container.read(chainConfigurationUseCaseProvider); + final accountUseCase = container.read(accountUseCaseProvider); + final backgroundFetchConfigUseCase = + container.read(backgroundFetchConfigUseCaseProvider); + + final selectedNetwork = + chainConfigurationUseCase.getCurrentNetworkWithoutRefresh(); + PeriodicalCallData periodicalCallData = + backgroundFetchConfigUseCase.periodicalCallData.value; + final chainId = selectedNetwork.chainId; + + final isLoggedIn = authUseCase.loggedIn; + final account = accountUseCase.account.value; + final lowBalanceLimit = periodicalCallData.lowBalanceLimit; + final expectedTransactionFee = periodicalCallData.expectedTransactionFee; + final lowBalanceLimitEnabled = periodicalCallData.lowBalanceLimitEnabled; + final expectedTransactionFeeEnabled = + periodicalCallData.expectedTransactionFeeEnabled; + final lastEpoch = periodicalCallData.lasEpoch; + final expectedEpochOccurrence = + periodicalCallData.expectedEpochOccurrence; + final expectedEpochOccurrenceEnabled = + periodicalCallData.expectedEpochOccurrenceEnabled; + final serviceEnabled = periodicalCallData.serviceEnabled; + + // Make sure user is logged in + if (isLoggedIn && Config.isMxcChains(chainId) && serviceEnabled) { + AXSNotification().setupFlutterNotifications(shouldInitFirebase: false); + + if (lowBalanceLimitEnabled) { + await backgroundFetchConfigUseCase.checkLowBalance( + account!, lowBalanceLimit); + } + + if (expectedTransactionFeeEnabled) { + await backgroundFetchConfigUseCase + .checkTransactionFee(expectedTransactionFee); + } + + if (expectedEpochOccurrenceEnabled) { + periodicalCallData = + await backgroundFetchConfigUseCase.checkEpochOccur( + periodicalCallData, + lastEpoch, + expectedEpochOccurrence, + chainId); + } + + backgroundFetchConfigUseCase.updateItem(periodicalCallData); + BackgroundFetch.finish(taskId); + } else { + // terminate background fetch + BackgroundFetch.stop(taskId); + } + } catch (e) { + BackgroundFetch.finish(taskId); + } + } +} diff --git a/lib/features/settings/subfeatures/notifications/domain/background_fetch_config_use_case.dart b/lib/features/settings/subfeatures/notifications/domain/background_fetch_config_use_case.dart index efbaf243..38dc270b 100644 --- a/lib/features/settings/subfeatures/notifications/domain/background_fetch_config_use_case.dart +++ b/lib/features/settings/subfeatures/notifications/domain/background_fetch_config_use_case.dart @@ -161,11 +161,11 @@ class BackgroundFetchConfigUseCase extends ReactiveUseCase { requiresStorageNotLow: false, requiresDeviceIdle: false, requiredNetworkType: bgFetch.NetworkType.ANY), - callbackDispatcherForeGround); + NotificationsService.callbackDispatcherForeGround); // Android Only final backgroundFetchState = await bgFetch.BackgroundFetch.registerHeadlessTask( - callbackDispatcher); + NotificationsService.callbackDispatcher); final scheduleState = await bgFetch.BackgroundFetch.scheduleTask(bgFetch.TaskConfig( diff --git a/lib/main.dart b/lib/main.dart index c34ce3a8..c6646b5a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:convert'; import 'package:datadashwallet/app/logger.dart'; import 'package:datadashwallet/common/common.dart'; import 'package:datadashwallet/core/core.dart'; @@ -8,8 +7,6 @@ import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:background_fetch/background_fetch.dart'; -import 'package:mxc_logic/mxc_logic.dart'; import 'app/app.dart'; @@ -25,83 +22,6 @@ Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { print('Handling a background message ${message.messageId}'); } -@pragma( - 'vm:entry-point') // Mandatory if the App is obfuscated or using Flutter 3.1+ -void callbackDispatcher(HeadlessTask task) async { - String taskId = task.taskId; - bool isTimeout = task.timeout; - if (isTimeout) { - // This task has exceeded its allowed running-time. - // You must stop what you're doing and immediately .finish(taskId) - print("[BackgroundFetch] Headless task timed-out: $taskId"); - BackgroundFetch.finish(taskId); - return; - } - callbackDispatcherForeGround(taskId); -} - -// Foreground -void callbackDispatcherForeGround(String taskId) async { - try { - await loadProviders(); - - final container = ProviderContainer(); - final authUseCase = container.read(authUseCaseProvider); - final chainConfigurationUseCase = - container.read(chainConfigurationUseCaseProvider); - final accountUseCase = container.read(accountUseCaseProvider); - final backgroundFetchConfigUseCase = - container.read(backgroundFetchConfigUseCaseProvider); - - final selectedNetwork = - chainConfigurationUseCase.getCurrentNetworkWithoutRefresh(); - PeriodicalCallData periodicalCallData = - backgroundFetchConfigUseCase.periodicalCallData.value; - final chainId = selectedNetwork.chainId; - - final isLoggedIn = authUseCase.loggedIn; - final account = accountUseCase.account.value; - final lowBalanceLimit = periodicalCallData.lowBalanceLimit; - final expectedTransactionFee = periodicalCallData.expectedTransactionFee; - final lowBalanceLimitEnabled = periodicalCallData.lowBalanceLimitEnabled; - final expectedTransactionFeeEnabled = - periodicalCallData.expectedTransactionFeeEnabled; - final lastEpoch = periodicalCallData.lasEpoch; - final expectedEpochOccurrence = periodicalCallData.expectedEpochOccurrence; - final expectedEpochOccurrenceEnabled = - periodicalCallData.expectedEpochOccurrenceEnabled; - final serviceEnabled = periodicalCallData.serviceEnabled; - - // Make sure user is logged in - if (isLoggedIn && Config.isMxcChains(chainId) && serviceEnabled) { - AXSNotification().setupFlutterNotifications(shouldInitFirebase: false); - - if (lowBalanceLimitEnabled) { - await backgroundFetchConfigUseCase.checkLowBalance( - account!, lowBalanceLimit); - } - - if (expectedTransactionFeeEnabled) { - await backgroundFetchConfigUseCase - .checkTransactionFee(expectedTransactionFee); - } - - if (expectedEpochOccurrenceEnabled) { - periodicalCallData = await backgroundFetchConfigUseCase.checkEpochOccur( - periodicalCallData, lastEpoch, expectedEpochOccurrence, chainId); - } - - backgroundFetchConfigUseCase.updateItem(periodicalCallData); - BackgroundFetch.finish(taskId); - } else { - // terminate background fetch - BackgroundFetch.stop(taskId); - } - } catch (e) { - BackgroundFetch.finish(taskId); - } -} - void main() { var onError = FlutterError.onError; FlutterError.onError = (FlutterErrorDetails details) { diff --git a/pubspec.lock b/pubspec.lock index ea678469..53fa23f2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -833,54 +833,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.4.0" - location2: - dependency: "direct main" - description: - name: location2 - sha256: ccfc286ddb66a8f4e11ebd454d4f8d5c2412df533c8e09c71842304a9b9e5bcc - url: "https://pub.dev" - source: hosted - version: "6.0.4" - location2_android: - dependency: transitive - description: - name: location2_android - sha256: b1c2945ece9b9de877e48095b4d74419a92230a59d0c8f4943117cbcc929e083 - url: "https://pub.dev" - source: hosted - version: "6.0.4" - location2_ios: - dependency: transitive - description: - name: location2_ios - sha256: c7a5c082e92d52c468ea505c60fbfab5724d8b08b9ed681e959904f3799b5dc9 - url: "https://pub.dev" - source: hosted - version: "6.0.4" - location2_macos: - dependency: transitive - description: - name: location2_macos - sha256: "73aeae307f81e9052c3b78e769b71ab9eb5df3322903677a59788e1689a7c05c" - url: "https://pub.dev" - source: hosted - version: "6.0.1" - location2_platform_interface: - dependency: transitive - description: - name: location2_platform_interface - sha256: "3a160d03a3915dd3ebded64c58a13386e93fcf581bf50aa899ecd35b1950050d" - url: "https://pub.dev" - source: hosted - version: "6.0.4" - location2_web: - dependency: transitive - description: - name: location2_web - sha256: e2566df1abd853e64a0b903499f87cbdb278a9c1851ec34f7251b57e736c457c - url: "https://pub.dev" - source: hosted - version: "6.0.4" location_platform_interface: dependency: transitive description: @@ -1603,14 +1555,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.0" - wifi_scan: - dependency: "direct main" - description: - name: wifi_scan - sha256: cd0b98a611a3206c1bd9e600b9dff3aca27dcc924aa025548b00713e93a27299 - url: "https://pub.dev" - source: hosted - version: "0.4.1" win32: dependency: transitive description: From b5cf394a20cf90e0b32d3754f365feb2e06777be Mon Sep 17 00:00:00 2001 From: reasje Date: Wed, 31 Jan 2024 23:11:12 +0330 Subject: [PATCH 025/103] feat: Added geolocator --- pubspec.lock | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++ pubspec.yaml | 1 + 2 files changed, 97 insertions(+) diff --git a/pubspec.lock b/pubspec.lock index 53fa23f2..3c870042 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -610,6 +610,54 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.1" + geolocator: + dependency: "direct main" + description: + name: geolocator + sha256: e946395fc608842bb2f6c914807e9183f86f3cb787f6b8f832753e5251036f02 + url: "https://pub.dev" + source: hosted + version: "10.1.0" + geolocator_android: + dependency: transitive + description: + name: geolocator_android + sha256: "93906636752ea4d4e778afa981fdfe7409f545b3147046300df194330044d349" + url: "https://pub.dev" + source: hosted + version: "4.3.1" + geolocator_apple: + dependency: transitive + description: + name: geolocator_apple + sha256: "79babf44b692ec5e789d322dc736ef71586056e8e6828f747c9e005456b248bf" + url: "https://pub.dev" + source: hosted + version: "2.3.5" + geolocator_platform_interface: + dependency: transitive + description: + name: geolocator_platform_interface + sha256: b8cc1d3be0ca039a3f2174b0b026feab8af3610e220b8532e42cff8ec6658535 + url: "https://pub.dev" + source: hosted + version: "4.1.0" + geolocator_web: + dependency: transitive + description: + name: geolocator_web + sha256: "102e7da05b48ca6bf0a5bda0010f886b171d1a08059f01bfe02addd0175ebece" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + geolocator_windows: + dependency: transitive + description: + name: geolocator_windows + sha256: a92fae29779d5c6dc60e8411302f5221ade464968fe80a36d330e80a71f087af + url: "https://pub.dev" + source: hosted + version: "0.2.2" gql: dependency: transitive description: @@ -833,6 +881,54 @@ packages: url: "https://pub.dev" source: hosted version: "4.4.0" + location2: + dependency: "direct main" + description: + name: location2 + sha256: ccfc286ddb66a8f4e11ebd454d4f8d5c2412df533c8e09c71842304a9b9e5bcc + url: "https://pub.dev" + source: hosted + version: "6.0.4" + location2_android: + dependency: transitive + description: + name: location2_android + sha256: b1c2945ece9b9de877e48095b4d74419a92230a59d0c8f4943117cbcc929e083 + url: "https://pub.dev" + source: hosted + version: "6.0.4" + location2_ios: + dependency: transitive + description: + name: location2_ios + sha256: c7a5c082e92d52c468ea505c60fbfab5724d8b08b9ed681e959904f3799b5dc9 + url: "https://pub.dev" + source: hosted + version: "6.0.4" + location2_macos: + dependency: transitive + description: + name: location2_macos + sha256: "73aeae307f81e9052c3b78e769b71ab9eb5df3322903677a59788e1689a7c05c" + url: "https://pub.dev" + source: hosted + version: "6.0.1" + location2_platform_interface: + dependency: transitive + description: + name: location2_platform_interface + sha256: "3a160d03a3915dd3ebded64c58a13386e93fcf581bf50aa899ecd35b1950050d" + url: "https://pub.dev" + source: hosted + version: "6.0.4" + location2_web: + dependency: transitive + description: + name: location2_web + sha256: e2566df1abd853e64a0b903499f87cbdb278a9c1851ec34f7251b57e736c457c + url: "https://pub.dev" + source: hosted + version: "6.0.4" location_platform_interface: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 5ef77ae0..218dfc32 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,6 +61,7 @@ dependencies: flutter_mailer: ^2.0.2 flutter_staggered_grid_view: ^0.7.0 flutter_svg: ^2.0.1 + geolocator: ^10.1.0 h3_flutter: ^0.6.6 hooks_riverpod: ^1.0.3 jdenticon_dart: ^2.0.0 From 9e22b61a0c5eb15639e268fec93209a93dabe77a Mon Sep 17 00:00:00 2001 From: reasje Date: Thu, 1 Feb 2024 10:36:57 +0330 Subject: [PATCH 026/103] feat: Added wifi scan --- pubspec.lock | 56 ++++++++-------------------------------------------- pubspec.yaml | 1 + 2 files changed, 9 insertions(+), 48 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 3c870042..fc983948 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -881,54 +881,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.4.0" - location2: - dependency: "direct main" - description: - name: location2 - sha256: ccfc286ddb66a8f4e11ebd454d4f8d5c2412df533c8e09c71842304a9b9e5bcc - url: "https://pub.dev" - source: hosted - version: "6.0.4" - location2_android: - dependency: transitive - description: - name: location2_android - sha256: b1c2945ece9b9de877e48095b4d74419a92230a59d0c8f4943117cbcc929e083 - url: "https://pub.dev" - source: hosted - version: "6.0.4" - location2_ios: - dependency: transitive - description: - name: location2_ios - sha256: c7a5c082e92d52c468ea505c60fbfab5724d8b08b9ed681e959904f3799b5dc9 - url: "https://pub.dev" - source: hosted - version: "6.0.4" - location2_macos: - dependency: transitive - description: - name: location2_macos - sha256: "73aeae307f81e9052c3b78e769b71ab9eb5df3322903677a59788e1689a7c05c" - url: "https://pub.dev" - source: hosted - version: "6.0.1" - location2_platform_interface: - dependency: transitive - description: - name: location2_platform_interface - sha256: "3a160d03a3915dd3ebded64c58a13386e93fcf581bf50aa899ecd35b1950050d" - url: "https://pub.dev" - source: hosted - version: "6.0.4" - location2_web: - dependency: transitive - description: - name: location2_web - sha256: e2566df1abd853e64a0b903499f87cbdb278a9c1851ec34f7251b57e736c457c - url: "https://pub.dev" - source: hosted - version: "6.0.4" location_platform_interface: dependency: transitive description: @@ -1651,6 +1603,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.0" + wifi_scan: + dependency: "direct main" + description: + name: wifi_scan + sha256: cd0b98a611a3206c1bd9e600b9dff3aca27dcc924aa025548b00713e93a27299 + url: "https://pub.dev" + source: hosted + version: "0.4.1" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 218dfc32..faffea85 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -92,6 +92,7 @@ dependencies: wallet_connect: ^1.0.4 web3_provider: path: packages/web3_provider + wifi_scan: ^0.4.1 dev_dependencies: flutter_launcher_icons: ^0.9.0 From d7b0e19023a78bb266505b5cf736c246ecbdd6ed Mon Sep 17 00:00:00 2001 From: reasje Date: Thu, 1 Feb 2024 10:37:37 +0330 Subject: [PATCH 027/103] fix: Android location dialog app crash fix --- android/app/src/main/AndroidManifest.xml | 2 +- android/app/src/main/res/values/styles.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 39ad8c5c..0795324a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -30,7 +30,7 @@ - + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index f8101f16..aae8457d 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -16,7 +16,7 @@ running. This Theme is only used starting with V2 of Flutter's Android embedding. --> -