|
...
|
...
|
@@ -14,6 +14,8 @@ import '../../pigeon/health_kit_api.g.dart'; |
|
|
|
import '../../pigeon/health_kit_raw_data_api.g.dart';
|
|
|
|
import '../config/app_environment_config.dart';
|
|
|
|
import '../logging/app_logger.dart';
|
|
|
|
import '../network/api/health_api.dart';
|
|
|
|
import '../result/app_result.dart';
|
|
|
|
import 'health_raw_local_notification.dart';
|
|
|
|
import 'health_raw_stress_calculator.dart';
|
|
|
|
import 'health_sleep_calculator.dart';
|
|
...
|
...
|
@@ -30,6 +32,7 @@ class HealthRawDataCoreService { |
|
|
|
int Function()? userIdProvider,
|
|
|
|
bool uploadResultsAfterCalculation = true,
|
|
|
|
HealthRawLocalNotificationDispatcher? localNotificationDispatcher,
|
|
|
|
HealthApi? serverHealthApi,
|
|
|
|
}) : _healthApi = healthApi ?? HealthKitHostApi(),
|
|
|
|
_rawDataApi = rawDataApi ?? HealthKitRawDataHostApi(),
|
|
|
|
_localStore = localStore ?? HealthRawStressLocalStore(),
|
|
...
|
...
|
@@ -37,7 +40,8 @@ class HealthRawDataCoreService { |
|
|
|
_userIdProvider = userIdProvider,
|
|
|
|
_uploadResultsAfterCalculation = uploadResultsAfterCalculation,
|
|
|
|
_localNotificationDispatcher = localNotificationDispatcher ??
|
|
|
|
HealthRawLocalNotificationDispatcher();
|
|
|
|
HealthRawLocalNotificationDispatcher(),
|
|
|
|
_serverHealthApi = serverHealthApi;
|
|
|
|
|
|
|
|
final HealthKitHostApi _healthApi;
|
|
|
|
final HealthKitRawDataHostApi _rawDataApi;
|
|
...
|
...
|
@@ -46,6 +50,7 @@ class HealthRawDataCoreService { |
|
|
|
final int Function()? _userIdProvider;
|
|
|
|
final bool _uploadResultsAfterCalculation;
|
|
|
|
final HealthRawLocalNotificationDispatcher _localNotificationDispatcher;
|
|
|
|
final HealthApi? _serverHealthApi;
|
|
|
|
final StreamController<HealthRawDataUpdatedEvent>
|
|
|
|
_healthDataUpdatedController =
|
|
|
|
StreamController<HealthRawDataUpdatedEvent>.broadcast();
|
|
...
|
...
|
@@ -424,15 +429,60 @@ class HealthRawDataCoreService { |
|
|
|
record: record,
|
|
|
|
);
|
|
|
|
if (notifications.isEmpty) return;
|
|
|
|
await _localNotificationDispatcher.sendAll(
|
|
|
|
final sentNotifications = await _localNotificationDispatcher.sendAll(
|
|
|
|
userId: result.userId,
|
|
|
|
notifications: notifications,
|
|
|
|
);
|
|
|
|
_scheduleRealtimeStressServerPush(sentNotifications);
|
|
|
|
} catch (error, stackTrace) {
|
|
|
|
_logError('send local health notifications failed', error, stackTrace);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void _scheduleRealtimeStressServerPush(
|
|
|
|
Iterable<HealthRawLocalNotification> sentNotifications,
|
|
|
|
) {
|
|
|
|
final realtimeNotifications = sentNotifications.where(
|
|
|
|
(notification) =>
|
|
|
|
notification.recordType ==
|
|
|
|
HealthRawLocalNotificationRecordType.realtimeStress &&
|
|
|
|
notification.currentState != null,
|
|
|
|
);
|
|
|
|
for (final notification in realtimeNotifications) {
|
|
|
|
unawaited(
|
|
|
|
_pushRealtimeStressServerNotification(notification),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> _pushRealtimeStressServerNotification(
|
|
|
|
HealthRawLocalNotification notification,
|
|
|
|
) async {
|
|
|
|
final serverHealthApi = _serverHealthApi;
|
|
|
|
if (serverHealthApi == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
final result = await serverHealthApi.pushRealtimeStressNotification(
|
|
|
|
latestDataTime: notification.recordTime,
|
|
|
|
currentState: notification.currentState!,
|
|
|
|
);
|
|
|
|
if (result is AppFailure) {
|
|
|
|
_logError(
|
|
|
|
'push realtime stress server notification failed',
|
|
|
|
result.error,
|
|
|
|
StackTrace.current,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} catch (error, stackTrace) {
|
|
|
|
_logError(
|
|
|
|
'push realtime stress server notification failed',
|
|
|
|
error,
|
|
|
|
stackTrace,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<bool> _hasHealthReadAuthorization() async {
|
|
|
|
final authorization = await _healthApi.checkHealthAppAuthorization();
|
|
|
|
return authorization.status == 1;
|
...
|
...
|
|