Geofence
This commit is contained in:
@@ -19,10 +19,15 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
|
||||
final _keyCtrl = TextEditingController();
|
||||
final _latCtrl = TextEditingController();
|
||||
final _lonCtrl = TextEditingController();
|
||||
bool _geofenceEnabled = false;
|
||||
bool _saving = false;
|
||||
|
||||
bool get _isEdit => widget.home != null;
|
||||
|
||||
/// Координаты заполнены (оба поля непустые)
|
||||
bool get _hasCoordinates =>
|
||||
_latCtrl.text.trim().isNotEmpty && _lonCtrl.text.trim().isNotEmpty;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -36,11 +41,27 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
|
||||
if (widget.home!.longitude != null) {
|
||||
_lonCtrl.text = widget.home!.longitude.toString();
|
||||
}
|
||||
_geofenceEnabled = widget.home!.geofenceEnabled;
|
||||
}
|
||||
|
||||
// Следим за полями координат чтобы обновлять доступность Switch
|
||||
_latCtrl.addListener(_onCoordsChanged);
|
||||
_lonCtrl.addListener(_onCoordsChanged);
|
||||
}
|
||||
|
||||
void _onCoordsChanged() {
|
||||
// Если координаты очистили -- выключаем геофенс
|
||||
if (!_hasCoordinates && _geofenceEnabled) {
|
||||
setState(() => _geofenceEnabled = false);
|
||||
} else {
|
||||
setState(() {}); // перерисовать Switch enabled/disabled
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_latCtrl.removeListener(_onCoordsChanged);
|
||||
_lonCtrl.removeListener(_onCoordsChanged);
|
||||
_nameCtrl.dispose();
|
||||
_urlCtrl.dispose();
|
||||
_keyCtrl.dispose();
|
||||
@@ -134,6 +155,43 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// ─── Геофенс ───
|
||||
SwitchListTile(
|
||||
title: const Text('Выключать свет при уходе'),
|
||||
subtitle: Text(
|
||||
_hasCoordinates
|
||||
? 'Автовыключение при удалении на 500 м'
|
||||
: 'Задайте координаты для активации',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: _hasCoordinates ? Colors.white38 : Colors.white24,
|
||||
),
|
||||
),
|
||||
value: _geofenceEnabled,
|
||||
activeColor: Colors.deepOrange,
|
||||
onChanged: _hasCoordinates
|
||||
? (v) => setState(() => _geofenceEnabled = v)
|
||||
: null,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
secondary: Icon(
|
||||
Icons.directions_walk,
|
||||
color: _geofenceEnabled && _hasCoordinates
|
||||
? Colors.deepOrange
|
||||
: Colors.white24,
|
||||
),
|
||||
),
|
||||
if (_geofenceEnabled && _hasCoordinates)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(left: 40, bottom: 4),
|
||||
child: Text(
|
||||
'Проверка раз в ~15 мин (ограничение Android).\n'
|
||||
'Работает в фоне, без постоянной нотификации.',
|
||||
style: TextStyle(fontSize: 11, color: Colors.white24),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
@@ -193,6 +251,8 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
|
||||
|
||||
setState(() => _saving = true);
|
||||
|
||||
final clearCoords = latText.isEmpty && lonText.isEmpty;
|
||||
|
||||
final home = _isEdit
|
||||
? widget.home!.copyWith(
|
||||
name: name,
|
||||
@@ -200,7 +260,8 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
|
||||
apiKey: key,
|
||||
latitude: lat,
|
||||
longitude: lon,
|
||||
clearCoordinates: latText.isEmpty && lonText.isEmpty,
|
||||
geofenceEnabled: clearCoords ? false : _geofenceEnabled,
|
||||
clearCoordinates: clearCoords,
|
||||
)
|
||||
: HomeConfig(
|
||||
id: DateTime.now().millisecondsSinceEpoch.toString(),
|
||||
@@ -209,6 +270,7 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
|
||||
apiKey: key,
|
||||
latitude: lat,
|
||||
longitude: lon,
|
||||
geofenceEnabled: _geofenceEnabled,
|
||||
);
|
||||
|
||||
if (_isEdit) {
|
||||
@@ -217,6 +279,10 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
|
||||
await ref.read(homesProvider.notifier).add(home);
|
||||
}
|
||||
|
||||
// Синхронизировать фоновый таск с новыми настройками
|
||||
final allHomes = ref.read(homesProvider);
|
||||
await syncGeofenceTask(allHomes);
|
||||
|
||||
if (mounted) Navigator.of(context).pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user