124 lines
5.4 KiB
Dart
124 lines
5.4 KiB
Dart
import 'package:geolocator/geolocator.dart';
|
||
|
||
import '../../../models/home_config.dart';
|
||
import '../geofence_logic.dart';
|
||
import 'geofence_runtime_state.dart';
|
||
|
||
enum GeofenceStatusKind {
|
||
noActiveHome,
|
||
disabled,
|
||
missingCoordinates,
|
||
locationServicesDisabled,
|
||
locationPermissionDenied,
|
||
backgroundPermissionDenied,
|
||
notificationsPermissionDenied,
|
||
cooldown,
|
||
triggered,
|
||
ready,
|
||
}
|
||
|
||
class GeofenceDiagnostics {
|
||
final HomeConfig? activeHome;
|
||
final GeofenceStatusKind status;
|
||
final GeofenceRuntimeState runtime;
|
||
final bool locationServicesEnabled;
|
||
final LocationPermission locationPermission;
|
||
final bool notificationsEnabled;
|
||
final Duration? retryRemaining;
|
||
final String? detail;
|
||
|
||
const GeofenceDiagnostics({
|
||
required this.activeHome,
|
||
required this.status,
|
||
required this.runtime,
|
||
required this.locationServicesEnabled,
|
||
required this.locationPermission,
|
||
required this.notificationsEnabled,
|
||
this.retryRemaining,
|
||
this.detail,
|
||
});
|
||
|
||
const GeofenceDiagnostics.initial()
|
||
: activeHome = null,
|
||
status = GeofenceStatusKind.noActiveHome,
|
||
runtime = const GeofenceRuntimeState(),
|
||
locationServicesEnabled = true,
|
||
locationPermission = LocationPermission.denied,
|
||
notificationsEnabled = true,
|
||
retryRemaining = null,
|
||
detail = null;
|
||
|
||
String get title {
|
||
return switch (status) {
|
||
GeofenceStatusKind.noActiveHome => 'Геофенс не активен',
|
||
GeofenceStatusKind.disabled => 'Автовыключение выключено',
|
||
GeofenceStatusKind.missingCoordinates => 'Нет координат дома',
|
||
GeofenceStatusKind.locationServicesDisabled => 'Геолокация выключена',
|
||
GeofenceStatusKind.locationPermissionDenied => 'Нет доступа к геолокации',
|
||
GeofenceStatusKind.backgroundPermissionDenied =>
|
||
'Нет фонового доступа к геолокации',
|
||
GeofenceStatusKind.notificationsPermissionDenied =>
|
||
'Нет доступа к уведомлениям',
|
||
GeofenceStatusKind.cooldown => 'Повтор отложен',
|
||
GeofenceStatusKind.triggered => 'Геофенс уже сработал',
|
||
GeofenceStatusKind.ready => 'Геофенс активен',
|
||
};
|
||
}
|
||
|
||
String get message {
|
||
final homeName = activeHome?.name ?? 'активного дома';
|
||
return switch (status) {
|
||
GeofenceStatusKind.noActiveHome =>
|
||
'Сначала выберите активный дом. Без этого фоновой автоматике нечего отслеживать.',
|
||
GeofenceStatusKind.disabled =>
|
||
'Для дома "$homeName" автовыключение пока отключено.',
|
||
GeofenceStatusKind.missingCoordinates =>
|
||
'У дома "$homeName" не заданы координаты. Без них расстояние считать не из чего.',
|
||
GeofenceStatusKind.locationServicesDisabled =>
|
||
'На устройстве выключена геолокация. И карта расстояний, и фоновый geofence сейчас слепые как кроты.',
|
||
GeofenceStatusKind.locationPermissionDenied =>
|
||
'Приложению не дали доступ к геолокации. Разрешите доступ хотя бы во время использования.',
|
||
GeofenceStatusKind.backgroundPermissionDenied =>
|
||
'Для фонового geofence нужен доступ к локации "Всегда". Иначе в фоне Android эту магию задушит.',
|
||
GeofenceStatusKind.notificationsPermissionDenied =>
|
||
'Свет выключить мы ещё попробуем, но честно отчитаться пользователю не сможем, пока уведомления запрещены.',
|
||
GeofenceStatusKind.cooldown =>
|
||
'Последняя попытка выключить свет сорвалась. Повторим позже, чтобы не долбить backend без остановки.',
|
||
GeofenceStatusKind.triggered =>
|
||
'Свет уже был автоматически выключен. Повторно бахать не будем, пока вы не вернётесь в домашний радиус.',
|
||
GeofenceStatusKind.ready =>
|
||
'Фоновая автоматика готова следить за домом "$homeName" и выключить свет после ухода.',
|
||
};
|
||
}
|
||
|
||
String? get secondaryMessage {
|
||
if (status == GeofenceStatusKind.cooldown && retryRemaining != null) {
|
||
return 'Повтор через ${formatGeofenceRetry(retryRemaining!)}.';
|
||
}
|
||
|
||
if (status == GeofenceStatusKind.triggered &&
|
||
runtime.lastSuccessAt != null &&
|
||
runtime.lastSuccessHomeId == activeHome?.id) {
|
||
return 'Последнее успешное срабатывание уже зафиксировано.';
|
||
}
|
||
|
||
if (detail != null && detail!.trim().isNotEmpty) {
|
||
return detail;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
bool get canRequestLocation =>
|
||
status == GeofenceStatusKind.locationPermissionDenied;
|
||
|
||
bool get canRequestBackgroundLocation =>
|
||
status == GeofenceStatusKind.backgroundPermissionDenied;
|
||
|
||
bool get canOpenLocationSettings =>
|
||
status == GeofenceStatusKind.locationServicesDisabled;
|
||
|
||
bool get canRequestNotifications =>
|
||
status == GeofenceStatusKind.notificationsPermissionDenied;
|
||
}
|