Skip to content
This repository has been archived by the owner on Sep 17, 2024. It is now read-only.

feat: blueberry ring auto sync #262

Merged
merged 1 commit into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions assets/flutter_i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,19 @@
"low_battery": "Low battery",
"blueberry_background_notifications_requirements_title": "This service requires: ",
"blueberry_background_notifications_requirements_text_1": "1. Bluetooth to be ON",
"blueberry_background_notifications_requirements_text_2": "2. Blueberry to be reachable"

"blueberry_background_notifications_requirements_text_2": "2. Blueberry to be reachable",
"auto_sync_started": "Blueberry Ring auto sync started 🏁",
"no_rings_selected_notification_title": "Looks like you haven't selected any Blueberry Rings. ℹ️",
"no_rings_selected_notification_text": "Please head over to Blueberry Ring DApp for selecting rings.",
"auto_sync_successful_notification_title": "Blueberry Ring aut-claim successful ✅",
"auto_sync_successful_notification_text": "AXS wallet has been successfully synced your ring data",
"already_synced_notification_title": "Oops, Already synced ℹ️",
"already_synced_notification_text": "AXS wallet tried to sync your ring data, But looks like you have synced the ring data today.",
"auto_sync_failed": "Blueberry Ring aut-sync failed ❌",
"no_rings_owned_notification": "Looks like this wallet doesn't own any Blueberry Rings. ℹ️",
"syncing_data_from_ring": "Syncing data from Blueberry Ring #{0}. ⛏️",
"already_synced_ring": "Blueberry Ring #{0}: Already synced. ℹ️",
"data_synced_successfully_ring": "Blueberry Ring #{0}: Data synced successfully. ✅",
"data_syncing_failed": "Blueberry Ring #{0}: Data syncing process failed. ❌",
"blueberry_hooks": "Blueberry hooks"
}
4 changes: 3 additions & 1 deletion lib/core/src/background_process/axs_background_fetch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class AXSBackgroundFetch {
DAppHooksService.dappHooksServiceCallBackDispatcherForeground(taskId);
} else if (taskId == BackgroundExecutionConfig.minerAutoClaimTask) {
DAppHooksService.autoClaimServiceCallBackDispatcherForeground(taskId);
} else if (taskId == BackgroundExecutionConfig.blueberryAutoSyncTask) {
DAppHooksService.blueberryAutoSyncServiceCallBackDispatcherForeground(taskId);
} else {
bgFetch.BackgroundFetch.finish(taskId);
}
Expand Down Expand Up @@ -77,7 +79,7 @@ class AXSBackgroundFetch {
requiresCharging: false,
requiresStorageNotLow: false,
requiresDeviceIdle: false,
requiredNetworkType: bgFetch.NetworkType.ANY),
requiredNetworkType: bgFetch.NetworkType.ANY,),
handleCallBackDispatcher);
// Android Only
final backgroundFetchState =
Expand Down
44 changes: 44 additions & 0 deletions lib/core/src/background_process/dapp_hooks_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,50 @@ class DAppHooksService {
DAppHooksModel dappHooksData = dAppHooksUseCase.dappHooksData.value;
final chainId = selectedNetwork.chainId;

final isLoggedIn = authUseCase.loggedIn;
final account = accountUseCase.account.value;
// final serviceEnabled = dappHooksData.enabled;
final minerHooksEnabled = dappHooksData.minerHooks.enabled;
final minerHooksTime = dappHooksData.minerHooks.time;
final selectedMiners = dappHooksData.minerHooks.selectedMiners;
// Make sure user is logged in
if (isLoggedIn && MXCChains.isMXCChains(chainId) && minerHooksEnabled) {
await AXSNotification()
.setupFlutterNotifications(shouldInitFirebase: false);

await dAppHooksUseCase.executeMinerAutoClaim(
account: account!,
selectedMinerListId: selectedMiners,
minerAutoClaimTime: minerHooksTime);
BackgroundFetch.finish(taskId);
} else {
// terminate background fetch
BackgroundFetch.stop(taskId);
}
} catch (e) {
BackgroundFetch.finish(taskId);
}
}

static void blueberryAutoSyncServiceCallBackDispatcherForeground(
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 dAppHooksUseCase = container.read(dAppHooksUseCaseProvider);
final contextLessTranslationUseCase =
container.read(contextLessTranslationUseCaseProvider);

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;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import 'dart:async';
import 'dart:convert';
import 'package:datadashwallet/features/common/common.dart';
import 'package:mxc_logic/mxc_logic.dart';

import 'package:datadashwallet/core/core.dart';
import 'package:datadashwallet/features/settings/subfeatures/chain_configuration/domain/chain_configuration_use_case.dart';

import '../../../../../../app/logger.dart';

class BlueberryRingBackgroundNotificationsUseCase extends ReactiveUseCase {
BlueberryRingBackgroundNotificationsUseCase(
this._repository,
this._chainConfigurationUseCase,
this._bluetoothUseCase,
this._blueberryRingUseCase,
this._accountUserCase,
this._contextLessTranslationUseCase);

final Web3Repository _repository;
final ChainConfigurationUseCase _chainConfigurationUseCase;
final BluetoothUseCase _bluetoothUseCase;
final BlueberryRingUseCase _blueberryRingUseCase;
final AccountUseCase _accountUserCase;
final ContextLessTranslationUseCase _contextLessTranslationUseCase;


// Context less translation, This should be only used for BG functions
String cTranslate(String key) =>
_contextLessTranslationUseCase.translate(key);


Future<void> sendSyncTransaction({
required BlueberryRingMiner ring,
required Account account,
required void Function(String title, String? text) showNotification,
required String Function(
String key,
)
translate,
}) async {
// Get rings list

// showNotification(
// translate('no_token_to_claim_miner')
// .replaceFirst('{0}', miner.mep1004TokenId!),
// null,
// );
// no_rings_owned_notification
// syncing_data_from_ring
// already_synced_ring
// data_synced_successfully_ring
// data_syncing_failed
final memo = await fetchRingData();

final postClaimRequest = PostClaimRequestModel(
sncode: ring.sncode,
sender: account.address,
);
final postClaimResponse = await _repository.blueberryRingRepository.postClaim(
postClaimRequest,
);

final txSig = await _repository.blueberryRingRepository.sendSyncTransaction(account.privateKey, ring, postClaimResponse, memo);

// showNotification(
// translate('no_token_to_claim_miner')
// .replaceFirst('{0}', miner.mep1004TokenId!),
// null,
// );


}


Future<String> fetchRingData() async {
collectLog('fetchRingData');

final sleep = await _blueberryRingUseCase.readSleep();
final bloodOxygens = await _blueberryRingUseCase.readBloodOxygens();
final steps = await _blueberryRingUseCase.readSteps();
final heartRate = await _blueberryRingUseCase.readHeartRate();

final data = {
'sleep': sleep.map((e) => e.toJson()).toList(),
'steps': steps.map((e) => e.toJson()).toList(),
'heartRate': heartRate.map((e) => e.toJson()).toList(),
'bloodOxygens': bloodOxygens.map((e) => e.toJson()).toList(),
};


final content = json.encode(data);

collectLog('fetchRingData:content : $content');

final mep3355 = {
'format': 'MEP-3355',
'version': '1.0.0',
'metadata': {
'data_source': 'BlueberryRingV1',
'data_collection_method': 'bluetooth',
'preprocessing': 'weighted average of data',
},
'data': [
{
'type': 'sensor',
// 'content': await compress(content),
'compression': 'brotli',
},
],
};

collectLog('fetchRingData:content : $mep3355');

final returndataMap = {
'json': mep3355,
'data': data,
};
final returnDataJson = json.encode(returndataMap);
return returnDataJson;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,28 @@ class DAppHooksPage extends HookConsumerWidget {
const SizedBox(height: Sizes.spaceNormal),
MXCDropDown(
key: const Key('minerHooksTimingDropDown'),
onTap: dappHooksPresenter.showTimePickerDialog,
onTap: dappHooksPresenter.showTimePickerMinerDialog,
selectedItem: autoClaimTime,
enabled:
isMXCChains && dappHooksState.dAppHooksData!.minerHooks.enabled,
),
// const SizedBox(height: Sizes.spaceLarge),
// MXCSwitchRowItem(
// key: const Key('blueberryRingHookSwitch'),
// title: translate('blueberry_hooks'),
// value: dappHooksState.dAppHooksData!.blueberryRingHooks.enabled,
// onChanged: dappHooksPresenter.changeBlueberryHooksEnabled,
// enabled: isMXCChains,
// titleStyle: FontTheme.of(context).h6(),
// ),
// const SizedBox(height: Sizes.spaceNormal),
// MXCDropDown(
// key: const Key('BlueberryHooksTimingDropDown'),
// onTap: dappHooksPresenter.showTimePickerBlueberryRingDialog,
// selectedItem: autoClaimTime,
// enabled:
// isMXCChains && dappHooksState.dAppHooksData!.blueberryRingHooks.enabled,
// ),
],
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ class DAppHooksPresenter extends CompletePresenter<DAppHooksState>
accountUseCase: _accountUseCase,
backgroundFetchConfigUseCase: _backgroundFetchConfigUseCase);

BlueberryHooksHelper get blueberryRingHooksHelper => BlueberryHooksHelper(
translate: translate,
context: context,
dAppHooksUseCase: _dAppHooksUseCase,
accountUseCase: _accountUseCase,
backgroundFetchConfigUseCase: _backgroundFetchConfigUseCase);

WiFiHooksHelper get wifiHooksHelper => WiFiHooksHelper(
translate: translate,
context: context,
Expand Down Expand Up @@ -82,15 +89,30 @@ class DAppHooksPresenter extends CompletePresenter<DAppHooksState>
void changeMinerHooksEnabled(bool value) =>
minerHooksHelper.changeMinerHooksEnabled(value);

void changeBlueberryHooksEnabled(bool value) =>
blueberryRingHooksHelper.changeBLueberryRingHooksEnabled(value);

void showWiFiHooksFrequency() {
showWiFiHooksFrequencyBottomSheet(context!,
onTap: wifiHooksHelper.handleFrequencyChange,
selectedFrequency: getPeriodicalCallDurationFromInt(
state.dAppHooksData!.wifiHooks.duration));
}

void showTimePickerDialog() async {
void showTimePickerMinerDialog() async {
final currentTimeOfDay = state.dAppHooksData!.minerHooks.time;
showTimePickerDialog(
currentTimeOfDay, minerHooksHelper.changeMinerHookTiming);
}

void showTimePickerBlueberryRingDialog() async {
final currentTimeOfDay = state.dAppHooksData!.blueberryRingHooks.time;
showTimePickerDialog(currentTimeOfDay,
blueberryRingHooksHelper.changeBlueberryRingHookTiming);
}

void showTimePickerDialog(DateTime currentTimeOfDay,
Future<void> Function(TimeOfDay value) changeTimeFunction) async {
final initialTime = TimeOfDay.fromDateTime(currentTimeOfDay);
final newTimeOfDay = await showTimePicker(
context: context!,
Expand All @@ -99,7 +121,7 @@ class DAppHooksPresenter extends CompletePresenter<DAppHooksState>
);

if (newTimeOfDay != null) {
minerHooksHelper.changeMinerHookTiming(newTimeOfDay);
changeTimeFunction(newTimeOfDay);
}
}

Expand Down
Loading
Loading