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

Commit

Permalink
feat: blueberry ring auto sync
Browse files Browse the repository at this point in the history
  • Loading branch information
reasje committed Jul 26, 2024
1 parent 5e66996 commit 2515098
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 38 deletions.
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

0 comments on commit 2515098

Please sign in to comment.